├── qmldir ├── README.md ├── icons ├── ic_close_white_24px.svg ├── ic_search_white_24px.svg ├── ic_settings_backup_restore_white_24px.svg └── ic_settings_white_24px.svg ├── settingsinputviewfactory.h ├── settingsinputviewfactory.cpp ├── .gitignore ├── SectionListView.qml ├── MsgDelegate.qml ├── ListSection.qml ├── de_skycoder42_qtmvvm_settings_quick.pri ├── multifilterproxymodel.h ├── qpm.json ├── settingsoverelement.cpp ├── de_skycoder42_qtmvvm_settings_quick.qrc ├── BoolDelegate.qml ├── settingsentryelement.cpp ├── qpmx.json ├── settingsoverelement.h ├── multifilterproxymodel.cpp ├── qtmvvm_settings_quick_de.ts ├── qtmvvm_settings_quick_template.ts ├── LICENSE ├── OverviewListView.qml ├── settingsentryelement.h ├── settingsuibuilder.h ├── SettingsView.qml └── settingsuibuilder.cpp /qmldir: -------------------------------------------------------------------------------- 1 | 2 | module de.skycoder42.qtmvvm.settings.quick 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QtMvvmSettingsQuick 2 | Has been replaced by https://github.com/Skycoder42/QtMvvm 3 | -------------------------------------------------------------------------------- /icons/ic_close_white_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /settingsinputviewfactory.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSINPUTVIEWFACTORY_H 2 | #define SETTINGSINPUTVIEWFACTORY_H 3 | 4 | #include 5 | 6 | class SettingsInputViewFactory : public InputViewFactory 7 | { 8 | public: 9 | virtual QUrl getDelegate(const QByteArray &type, const QVariantMap &properties); 10 | }; 11 | 12 | #endif // SETTINGSINPUTVIEWFACTORY_H 13 | -------------------------------------------------------------------------------- /settingsinputviewfactory.cpp: -------------------------------------------------------------------------------- 1 | #include "settingsinputviewfactory.h" 2 | 3 | QUrl SettingsInputViewFactory::getDelegate(const QByteArray &type, const QVariantMap &) 4 | { 5 | if(type == "bool") 6 | return QStringLiteral("qrc:/de/skycoder42/qtmvvm/settings/quick/BoolDelegate.qml"); 7 | else 8 | return QStringLiteral("qrc:/de/skycoder42/qtmvvm/settings/quick/MsgDelegate.qml"); 9 | } 10 | -------------------------------------------------------------------------------- /icons/ic_search_white_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /icons/ic_settings_backup_restore_white_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | # QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | 36 | # QtCtreator CMake 37 | CMakeLists.txt.user 38 | 39 | #qpm 40 | vendor -------------------------------------------------------------------------------- /SectionListView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.1 3 | import QtQuick.Layouts 1.3 4 | 5 | ListView { 6 | id: listView 7 | 8 | section.property: "group" 9 | section.labelPositioning: ViewSection.InlineLabels 10 | section.delegate: ListSection { 11 | title: section 12 | } 13 | 14 | delegate: Loader { 15 | id: loaderDelegate 16 | width: parent.width 17 | height: item ? item.implicitHeight : 0 18 | 19 | Component.onCompleted: loaderDelegate.setSource(delegateUrl, editProperties); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MsgDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.1 3 | import QtQuick.Layouts 1.3 4 | 5 | ItemDelegate { 6 | id: msgDelegate 7 | 8 | text: title 9 | 10 | contentItem: ColumnLayout { 11 | Label { 12 | id: titleLabel 13 | text: msgDelegate.text 14 | font.bold: true 15 | elide: Label.ElideRight 16 | Layout.fillWidth: true 17 | } 18 | 19 | Label { 20 | id: textLabel 21 | visible: tooltip 22 | text: tooltip 23 | wrapMode: Text.WordWrap 24 | Layout.fillWidth: true 25 | } 26 | } 27 | 28 | onClicked: showInputDialog = true 29 | } 30 | -------------------------------------------------------------------------------- /ListSection.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.1 3 | import de.skycoder42.quickextras 2.0 4 | 5 | Label { 6 | property string title 7 | 8 | CommonStyle { 9 | id: style 10 | } 11 | 12 | width: parent.width 13 | font.bold: true 14 | font.capitalization: Font.SmallCaps 15 | padding: 14 16 | bottomPadding: 4 17 | text: title + qsTr(":") 18 | 19 | background: Rectangle { 20 | anchors.fill: parent 21 | color: style.sBackground 22 | 23 | Rectangle { 24 | anchors.left: parent.left 25 | anchors.bottom: parent.bottom 26 | anchors.right: parent.right 27 | height: 2 28 | color: style.accent 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /de_skycoder42_qtmvvm_settings_quick.pri: -------------------------------------------------------------------------------- 1 | HEADERS += \ 2 | $$PWD/settingsuibuilder.h \ 3 | $$PWD/settingsoverelement.h \ 4 | $$PWD/settingsentryelement.h \ 5 | $$PWD/multifilterproxymodel.h \ 6 | $$PWD/settingsinputviewfactory.h 7 | 8 | SOURCES += \ 9 | $$PWD/settingsuibuilder.cpp \ 10 | $$PWD/settingsoverelement.cpp \ 11 | $$PWD/settingsentryelement.cpp \ 12 | $$PWD/multifilterproxymodel.cpp \ 13 | $$PWD/settingsinputviewfactory.cpp 14 | 15 | RESOURCES += \ 16 | $$PWD/de_skycoder42_qtmvvm_settings_quick.qrc 17 | 18 | TRANSLATIONS += $$PWD/qtmvvm_settings_quick_de.ts \ 19 | $$PWD/qtmvvm_settings_quick_template.ts 20 | 21 | INCLUDEPATH += $$PWD 22 | -------------------------------------------------------------------------------- /multifilterproxymodel.h: -------------------------------------------------------------------------------- 1 | #ifndef MULTIFILTERPROXYMODEL_H 2 | #define MULTIFILTERPROXYMODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class MultiFilterProxyModel : public QSortFilterProxyModel 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit MultiFilterProxyModel(QObject *parent = nullptr); 14 | 15 | void addFilterRole(QByteArray roleName); 16 | void addFilterRole(int role); 17 | void clearFilterRoles(); 18 | 19 | void setFilter(const QRegularExpression ®ex); 20 | 21 | protected: 22 | bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; 23 | 24 | private: 25 | QSet _filterRoles; 26 | QRegularExpression _filterRegex; 27 | }; 28 | 29 | #endif // MULTIFILTERPROXYMODEL_H 30 | -------------------------------------------------------------------------------- /qpm.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "email": "skycoder42.de@gmx.de", 4 | "name": "Skycoder" 5 | }, 6 | "dependencies": [ 7 | "de.skycoder42.qtmvvm.settings.core@1.1.2", 8 | "de.skycoder42.qtmvvm.quick@1.1.2" 9 | ], 10 | "description": "The quick controls 2 frontend of QtMvvm settings module", 11 | "license": "BSD_3_CLAUSE", 12 | "name": "de.skycoder42.qtmvvm.settings.quick", 13 | "pri_filename": "de_skycoder42_qtmvvm_settings_quick.pri", 14 | "repository": { 15 | "type": "GITHUB", 16 | "url": "https://github.com/Skycoder42/QtMvvmSettingsQuick.git" 17 | }, 18 | "version": { 19 | "fingerprint": "", 20 | "label": "1.1.2", 21 | "revision": "" 22 | }, 23 | "webpage": "https://github.com/Skycoder42/QtMvvm" 24 | } 25 | -------------------------------------------------------------------------------- /icons/ic_settings_white_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /settingsoverelement.cpp: -------------------------------------------------------------------------------- 1 | #include "settingsoverelement.h" 2 | 3 | SettingsOverElement::SettingsOverElement(QObject *parent) : 4 | QObject(parent) 5 | {} 6 | 7 | SettingsSection SettingsOverElement::settingsSection() const 8 | { 9 | return section; 10 | } 11 | 12 | void SettingsOverElement::setSettingsSection(const SettingsSection §ion) 13 | { 14 | this->section = section; 15 | 16 | searchKeys.clear(); 17 | searchKeys.append(section.title); 18 | searchKeys.append(section.tooltip); 19 | foreach(auto group, section.groups) { 20 | searchKeys.append(group.title); 21 | foreach(auto entry, group.entries) { 22 | searchKeys.append(entry.title); 23 | searchKeys.append(entry.tooltip); 24 | searchKeys.append(entry.searchKeys); 25 | } 26 | } 27 | 28 | emit settingsSectionChanged(); 29 | } 30 | 31 | QStringList SettingsOverElement::sectionSearchKeys() const 32 | { 33 | return searchKeys; 34 | } 35 | -------------------------------------------------------------------------------- /de_skycoder42_qtmvvm_settings_quick.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | icons/ic_search_white_24px.svg 4 | icons/ic_settings_backup_restore_white_24px.svg 5 | icons/ic_close_white_24px.svg 6 | 7 | 8 | SettingsView.qml 9 | 10 | 11 | icons/ic_settings_white_24px.svg 12 | 13 | 14 | OverviewListView.qml 15 | SectionListView.qml 16 | ListSection.qml 17 | BoolDelegate.qml 18 | MsgDelegate.qml 19 | 20 | 21 | -------------------------------------------------------------------------------- /BoolDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.1 3 | import QtQuick.Layouts 1.3 4 | 5 | SwitchDelegate { 6 | id: boolDelegate 7 | 8 | text: title 9 | 10 | Component.onCompleted: checked = settingsValue; 11 | onCheckedChanged: settingsValue = checked; 12 | 13 | contentItem: GridLayout { 14 | columns: 2 15 | rows: 2 16 | 17 | Label { 18 | id: titleLabel 19 | text: boolDelegate.text 20 | Layout.row: 0 21 | Layout.column: 0 22 | font.bold: true 23 | elide: Label.ElideRight 24 | Layout.fillWidth: true 25 | } 26 | 27 | Label { 28 | id: textLabel 29 | visible: tooltip 30 | Layout.row: 1 31 | Layout.column: 0 32 | text: tooltip 33 | wrapMode: Text.WordWrap 34 | Layout.fillWidth: true 35 | } 36 | 37 | Item { 38 | Layout.row: 0 39 | Layout.column: 1 40 | Layout.rowSpan: 2 41 | Layout.minimumWidth: implicitWidth 42 | Layout.maximumWidth: implicitWidth 43 | implicitWidth: boolDelegate.indicator.width + 14 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /settingsentryelement.cpp: -------------------------------------------------------------------------------- 1 | #include "settingsentryelement.h" 2 | #include 3 | #include 4 | 5 | SettingsEntryElement::SettingsEntryElement(SettingsControl *control, QObject *parent) : 6 | QObject(parent), 7 | control(control) 8 | {} 9 | 10 | QVariant SettingsEntryElement::settingsValue() const 11 | { 12 | auto res = control->loadValue(key, defaultValue); 13 | res.convert(conversionType); 14 | return res; 15 | } 16 | 17 | QVariantMap SettingsEntryElement::getEditProperties() const 18 | { 19 | return editProperties; 20 | } 21 | 22 | bool SettingsEntryElement::returnFalse() const 23 | { 24 | return false; 25 | } 26 | 27 | void SettingsEntryElement::showInputDialog(bool show) 28 | { 29 | if(show) { 30 | CoreMessage::getInput(title + tr(":"), QString(), inputType.constData(), [=](QVariant value) { 31 | if(value.isValid()) 32 | setSettingsValue(value); 33 | }, settingsValue(), editProperties); 34 | } 35 | } 36 | 37 | void SettingsEntryElement::setSettingsValue(QVariant settingsValue) 38 | { 39 | control->saveValue(key, settingsValue); 40 | } 41 | 42 | QUrl SettingsEntryElement::getDelegateUrl() const 43 | { 44 | return delegateUrl; 45 | } 46 | -------------------------------------------------------------------------------- /qpmx.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "package": "de.skycoder42.qtmvvm.settings.core", 5 | "provider": "qpm", 6 | "version": "1.1.2" 7 | }, 8 | { 9 | "package": "de.skycoder42.qtmvvm.quick", 10 | "provider": "qpm", 11 | "version": "1.1.2" 12 | } 13 | ], 14 | "license": { 15 | "file": "LICENSE", 16 | "name": "BSD_3_CLAUSE" 17 | }, 18 | "prcFile": "", 19 | "priFile": "de_skycoder42_qtmvvm_settings_quick.pri", 20 | "priIncludes": [ 21 | ], 22 | "publishers": { 23 | "qpm": { 24 | "author": { 25 | "email": "skycoder42.de@gmx.de", 26 | "name": "Skycoder" 27 | }, 28 | "description": "The quick controls 2 frontend of QtMvvm settings module", 29 | "name": "de.skycoder42.qtmvvm.settings.quick", 30 | "repository": { 31 | "type": "GITHUB", 32 | "url": "https://github.com/Skycoder42/QtMvvmSettingsQuick.git" 33 | }, 34 | "webpage": "https://github.com/Skycoder42/QtMvvm" 35 | } 36 | }, 37 | "source": false 38 | } 39 | -------------------------------------------------------------------------------- /settingsoverelement.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSOVERELEMENT_H 2 | #define SETTINGSOVERELEMENT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class SettingsOverElement : public QObject 9 | { 10 | Q_OBJECT 11 | 12 | Q_PROPERTY(QString category MEMBER category NOTIFY categoryChanged) 13 | 14 | Q_PROPERTY(QString title MEMBER title NOTIFY titleChanged) 15 | Q_PROPERTY(QUrl icon MEMBER icon NOTIFY iconChanged) 16 | Q_PROPERTY(QString tooltip MEMBER tooltip NOTIFY tooltipChanged) 17 | 18 | Q_PROPERTY(SettingsSection settingsSection READ settingsSection WRITE setSettingsSection NOTIFY settingsSectionChanged) 19 | Q_PROPERTY(QStringList sectionSearchKeys READ sectionSearchKeys NOTIFY settingsSectionChanged) 20 | 21 | public: 22 | explicit SettingsOverElement(QObject *parent = nullptr); 23 | 24 | QString category; 25 | QString title; 26 | QUrl icon; 27 | QString tooltip; 28 | 29 | SettingsSection settingsSection() const; 30 | void setSettingsSection(const SettingsSection §ion); 31 | 32 | QStringList sectionSearchKeys() const; 33 | 34 | signals: 35 | void categoryChanged(); 36 | void titleChanged(); 37 | void iconChanged(); 38 | void tooltipChanged(); 39 | void settingsSectionChanged(); 40 | 41 | private: 42 | SettingsSection section; 43 | QStringList searchKeys; 44 | }; 45 | 46 | Q_DECLARE_METATYPE(SettingsSection) 47 | 48 | #endif // SETTINGSOVERELEMENT_H 49 | -------------------------------------------------------------------------------- /multifilterproxymodel.cpp: -------------------------------------------------------------------------------- 1 | #include "multifilterproxymodel.h" 2 | 3 | MultiFilterProxyModel::MultiFilterProxyModel(QObject *parent) : 4 | QSortFilterProxyModel(parent), 5 | _filterRoles() 6 | {} 7 | 8 | void MultiFilterProxyModel::addFilterRole(QByteArray roleName) 9 | { 10 | auto role = roleNames().key(roleName, -1); 11 | if(role != -1) 12 | addFilterRole(role); 13 | } 14 | 15 | void MultiFilterProxyModel::addFilterRole(int role) 16 | { 17 | _filterRoles.insert(role); 18 | invalidateFilter(); 19 | } 20 | 21 | void MultiFilterProxyModel::clearFilterRoles() 22 | { 23 | _filterRoles.clear(); 24 | invalidateFilter(); 25 | } 26 | 27 | void MultiFilterProxyModel::setFilter(const QRegularExpression ®ex) 28 | { 29 | _filterRegex = regex; 30 | invalidateFilter(); 31 | } 32 | 33 | bool MultiFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const 34 | { 35 | if(!_filterRegex.isValid() || _filterRoles.isEmpty()) 36 | return true; 37 | 38 | foreach(auto role, _filterRoles) { 39 | auto rData = sourceModel()->data(sourceModel()->index(source_row, 0, source_parent), role); 40 | auto strList = rData.toStringList(); 41 | foreach(auto str, strList) { 42 | if(_filterRegex.match(str).hasMatch()) 43 | return true; 44 | } 45 | auto str = rData.toString(); 46 | if(!str.isNull() && _filterRegex.match(str).hasMatch()) 47 | return true; 48 | } 49 | 50 | return false; 51 | } 52 | -------------------------------------------------------------------------------- /qtmvvm_settings_quick_de.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ListSection 6 | 7 | 8 | : 9 | : 10 | 11 | 12 | 13 | SettingsEntryElement 14 | 15 | 16 | : 17 | : 18 | 19 | 20 | 21 | SettingsUiBuilder 22 | 23 | 24 | Others 25 | Andere 26 | 27 | 28 | 29 | SettingsView 30 | 31 | 32 | Settings 33 | Einstellungen 34 | 35 | 36 | 37 | Search in settings 38 | In Einstellungen suchen 39 | 40 | 41 | 42 | Restore settings 43 | Werkseinstellungen wiederherstellen 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /qtmvvm_settings_quick_template.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ListSection 6 | 7 | 8 | : 9 | 10 | 11 | 12 | 13 | SettingsEntryElement 14 | 15 | 16 | : 17 | 18 | 19 | 20 | 21 | SettingsUiBuilder 22 | 23 | 24 | Others 25 | 26 | 27 | 28 | 29 | SettingsView 30 | 31 | 32 | Settings 33 | 34 | 35 | 36 | 37 | Search in settings 38 | 39 | 40 | 41 | 42 | Restore settings 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Felix Barz 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /OverviewListView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.1 3 | import QtQuick.Layouts 1.3 4 | import de.skycoder42.quickextras 2.0 5 | 6 | ListView { 7 | id: listView 8 | 9 | property bool showSections: true 10 | 11 | section.property: showSections ? "category" : "" 12 | section.labelPositioning: ViewSection.InlineLabels 13 | section.delegate: ListSection { 14 | title: section 15 | } 16 | 17 | delegate: ItemDelegate { 18 | id: delegate 19 | width: parent.width 20 | 21 | onClicked: builder.loadSection(settingsSection) 22 | 23 | Timer { 24 | id: enforcer 25 | interval: 50 26 | repeat: false 27 | running: true 28 | 29 | onTriggered: { 30 | delegate.implicitHeight = Qt.binding(function(){return grid.implicitHeight + 32}); 31 | } 32 | } 33 | 34 | contentItem: GridLayout { 35 | id: grid 36 | rows: 2 37 | columns: 2 38 | columnSpacing: 14 39 | 40 | TintIcon { 41 | id: tintIcon 42 | source: icon 43 | visible: icon != "" 44 | Layout.row: 0 45 | Layout.column: 0 46 | Layout.rowSpan: 2 47 | Layout.fillHeight: true 48 | Layout.preferredWidth: iconSize.width 49 | Layout.preferredHeight: iconSize.height 50 | Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft 51 | } 52 | 53 | Label { 54 | id: titleLabel 55 | text: title 56 | Layout.row: 0 57 | Layout.column: 1 58 | font.bold: true 59 | elide: Label.ElideRight 60 | Layout.fillWidth: true 61 | } 62 | 63 | Label { 64 | id: textLabel 65 | visible: tooltip 66 | Layout.row: 1 67 | Layout.column: 1 68 | text: tooltip 69 | wrapMode: Text.WordWrap 70 | Layout.fillWidth: true 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /settingsentryelement.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSENTRYELEMENT_H 2 | #define SETTINGSENTRYELEMENT_H 3 | 4 | #include 5 | #include 6 | 7 | class SettingsEntryElement : public QObject 8 | { 9 | Q_OBJECT 10 | 11 | Q_PROPERTY(QString group MEMBER group NOTIFY groupChanged) 12 | 13 | Q_PROPERTY(QString title MEMBER title NOTIFY titleChanged) 14 | Q_PROPERTY(QString tooltip MEMBER tooltip NOTIFY tooltipChanged) 15 | Q_PROPERTY(QVariant settingsValue READ settingsValue WRITE setSettingsValue NOTIFY settingsValueChanged) 16 | 17 | Q_PROPERTY(QStringList searchKeys MEMBER searchKeys CONSTANT) 18 | Q_PROPERTY(QUrl delegateUrl READ getDelegateUrl CONSTANT) 19 | Q_PROPERTY(QVariantMap editProperties READ getEditProperties CONSTANT) 20 | 21 | Q_PROPERTY(bool showInputDialog READ returnFalse WRITE showInputDialog) 22 | 23 | public: 24 | explicit SettingsEntryElement(SettingsControl *control, QObject *parent = nullptr); 25 | 26 | QString group; 27 | QString title; 28 | QString tooltip; 29 | 30 | QStringList searchKeys; 31 | QUrl delegateUrl; 32 | QVariantMap editProperties; 33 | 34 | QString key; 35 | QByteArray inputType; 36 | int conversionType; 37 | QVariant defaultValue; 38 | 39 | QVariant settingsValue() const; 40 | 41 | QUrl getDelegateUrl() const; 42 | QVariantMap getEditProperties() const; 43 | 44 | bool returnFalse() const; 45 | 46 | public slots: 47 | void showInputDialog(bool show); 48 | 49 | void setSettingsValue(QVariant settingsValue); 50 | 51 | signals: 52 | void groupChanged(); 53 | void titleChanged(); 54 | void tooltipChanged(); 55 | void settingsValueChanged(QVariant settingsValue); 56 | 57 | private: 58 | SettingsControl *control; 59 | }; 60 | 61 | #endif // SETTINGSENTRYELEMENT_H 62 | -------------------------------------------------------------------------------- /settingsuibuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGSUIBUILDER_H 2 | #define SETTINGSUIBUILDER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "multifilterproxymodel.h" 11 | #include "settingsentryelement.h" 12 | #include "settingsoverelement.h" 13 | 14 | class SettingsUiBuilder : public QObject 15 | { 16 | Q_OBJECT 17 | 18 | Q_PROPERTY(QQuickItem* buildView MEMBER _buildView NOTIFY buildViewChanged) 19 | Q_PROPERTY(SettingsControl* control MEMBER _control NOTIFY controlChanged) 20 | Q_PROPERTY(QString filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged) 21 | 22 | public: 23 | explicit SettingsUiBuilder(QObject *parent = nullptr); 24 | 25 | QString filterText() const; 26 | 27 | public slots: 28 | void loadSection(const SettingsSection §ion); 29 | 30 | void restoreDefaults(); 31 | void setFilterText(QString filterText); 32 | 33 | signals: 34 | void initActions(bool allowSearch, bool allowRestore); 35 | void createView(bool isOverview, QAbstractItemModel *model, bool showSections); 36 | 37 | void buildViewChanged(QQuickItem* buildView); 38 | void controlChanged(SettingsControl* control); 39 | 40 | void filterTextChanged(QString filterText); 41 | 42 | private slots: 43 | void startBuildUi(); 44 | 45 | private: 46 | QQuickItem* _buildView; 47 | SettingsControl *_control; 48 | QString _filterText; 49 | 50 | QGenericListModel *_rootModel; 51 | MultiFilterProxyModel *_rootFilter; 52 | QGenericListModel *_currentEntryModel; 53 | MultiFilterProxyModel *_currentEntryFilter; 54 | 55 | static QUrl svgEscape(QUrl url); 56 | }; 57 | 58 | #endif // SETTINGSUIBUILDER_H 59 | -------------------------------------------------------------------------------- /SettingsView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.1 3 | import de.skycoder42.quickextras 2.0 4 | import de.skycoder42.qtmvvm.quick 1.0 5 | import de.skycoder42.qtmvvm.settings.quick 1.0 6 | 7 | Page { 8 | id: settingsView 9 | property SettingsControl control: null 10 | 11 | function closeAction() { 12 | return settingsStack.closeAction(); 13 | } 14 | 15 | header: ActionBar { 16 | title: qsTr("Settings") 17 | showMenuAsBack: true 18 | onMenuButtonClicked: control.close() 19 | 20 | TextField { 21 | id: searchField 22 | visible: false 23 | 24 | Component.onDestruction: visible = true 25 | } 26 | 27 | AppBarButton { 28 | id: searchButton 29 | visible: false 30 | imageSource: searchField.visible ? 31 | "image://svg/de/skycoder42/qtmvvm/settings/quick/icons/ic_close" : 32 | "image://svg/de/skycoder42/qtmvvm/settings/quick/icons/ic_search" 33 | text: qsTr("Search in settings") 34 | onClicked: { 35 | searchField.visible = !searchField.visible; 36 | if(searchField.visible) 37 | searchField.forceActiveFocus(); 38 | else 39 | searchField.text = ""; 40 | } 41 | 42 | Component.onDestruction: visible = true 43 | } 44 | 45 | AppBarButton { 46 | id: restoreButton 47 | visible: false 48 | imageSource: "image://svg/de/skycoder42/qtmvvm/settings/quick/icons/ic_settings_backup_restore" 49 | text: qsTr("Restore settings") 50 | onClicked: builder.restoreDefaults() 51 | 52 | Component.onDestruction: visible = true 53 | } 54 | } 55 | 56 | PresenterProgress { 57 | z: 10 58 | } 59 | 60 | StackView { 61 | id: settingsStack 62 | anchors.fill: parent 63 | 64 | function closeAction() { 65 | if(settingsStack.depth <= 1) 66 | return false; 67 | else { 68 | var item = settingsStack.pop(); 69 | return true; 70 | } 71 | } 72 | } 73 | 74 | SettingsUiBuilder { 75 | id: builder 76 | buildView: settingsView 77 | control: settingsView.control 78 | filterText: searchField.text 79 | 80 | onInitActions: { 81 | searchButton.visible = allowSearch; 82 | restoreButton.visible = allowSearch; 83 | } 84 | 85 | onCreateView: { 86 | if(isOverview) { 87 | settingsStack.push("qrc:/de/skycoder42/qtmvvm/settings/quick/OverviewListView.qml", { 88 | "model": model, 89 | "showSections": showSections 90 | }); 91 | } else { 92 | settingsStack.push("qrc:/de/skycoder42/qtmvvm/settings/quick/SectionListView.qml", { 93 | "model": model 94 | }); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /settingsuibuilder.cpp: -------------------------------------------------------------------------------- 1 | #include "settingsentryelement.h" 2 | #include "settingsoverelement.h" 3 | #include "settingsuibuilder.h" 4 | #include "settingsinputviewfactory.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | static void registerSettingsTypes(); 11 | Q_COREAPP_STARTUP_FUNCTION(registerSettingsTypes) 12 | 13 | SettingsUiBuilder::SettingsUiBuilder(QObject *parent) : 14 | QObject(parent), 15 | _buildView(nullptr), 16 | _control(nullptr), 17 | _filterText(), 18 | _rootModel(nullptr), 19 | _rootFilter(new MultiFilterProxyModel(this)), 20 | _currentEntryModel(nullptr), 21 | _currentEntryFilter(new MultiFilterProxyModel(this)) 22 | { 23 | connect(this, &SettingsUiBuilder::buildViewChanged, 24 | this, &SettingsUiBuilder::startBuildUi); 25 | connect(this, &SettingsUiBuilder::controlChanged, 26 | this, &SettingsUiBuilder::startBuildUi); 27 | } 28 | 29 | QString SettingsUiBuilder::filterText() const 30 | { 31 | return _filterText; 32 | } 33 | 34 | void SettingsUiBuilder::loadSection(const SettingsSection §ion) 35 | { 36 | if(_currentEntryModel) 37 | _currentEntryModel->deleteLater(); 38 | 39 | //get the input factory and generate a default settings one if not set 40 | auto inputFactory = QuickPresenter::inputViewFactory(); 41 | auto settingsFactory = dynamic_cast(inputFactory); 42 | QScopedPointer localFactoryPtr; 43 | if(!settingsFactory) { 44 | settingsFactory = new SettingsInputViewFactory(); 45 | localFactoryPtr.reset(settingsFactory); 46 | } 47 | 48 | _currentEntryModel = new QGenericListModel(true, this); 49 | _currentEntryModel->setEditable(true); 50 | auto rIndex = 0; 51 | foreach(auto group, section.groups) { 52 | foreach(auto entry, group.entries) { 53 | auto element = new SettingsEntryElement(_control); 54 | element->title = entry.title.remove(QRegularExpression(QStringLiteral("&(?!&)"))); 55 | element->tooltip = entry.tooltip; 56 | element->searchKeys = entry.searchKeys; 57 | element->delegateUrl = settingsFactory->getDelegate(entry.type, entry.properties); 58 | element->inputType = entry.type; 59 | element->conversionType = inputFactory->metaTypeId(entry.type, entry.properties); 60 | element->editProperties = entry.properties; 61 | element->key = entry.key; 62 | element->defaultValue = entry.defaultValue; 63 | if(group.title.isEmpty()) 64 | _currentEntryModel->insertObject(rIndex++, element); 65 | else { 66 | element->group = group.title; 67 | _currentEntryModel->addObject(element); 68 | } 69 | } 70 | } 71 | 72 | _currentEntryFilter->clearFilterRoles(); 73 | _currentEntryFilter->setSourceModel(_currentEntryModel); 74 | _currentEntryFilter->addFilterRole("group"); 75 | _currentEntryFilter->addFilterRole("title"); 76 | _currentEntryFilter->addFilterRole("tooltip"); 77 | _currentEntryFilter->addFilterRole("searchKeys"); 78 | emit createView(false, _currentEntryFilter, true); 79 | } 80 | 81 | void SettingsUiBuilder::restoreDefaults() 82 | { 83 | if(!_control->canRestoreDefaults()) 84 | return; 85 | 86 | auto result = CoreMessage::message(_control->restoreConfig()); 87 | connect(result, &MessageResult::positiveAction, this, [=](){ 88 | if(_rootModel) { 89 | foreach(auto overElement, _rootModel->objects()) { 90 | foreach(auto group, overElement->settingsSection().groups) { 91 | foreach(auto entry, group.entries) 92 | _control->resetValue(entry.key); 93 | } 94 | } 95 | } else if(_currentEntryModel) { 96 | foreach(auto entryElement, _currentEntryModel->objects()) 97 | _control->resetValue(entryElement->key); 98 | } 99 | _control->close(); 100 | }); 101 | } 102 | 103 | void SettingsUiBuilder::setFilterText(QString filterText) 104 | { 105 | if (_filterText == filterText) 106 | return; 107 | 108 | _filterText = filterText; 109 | emit filterTextChanged(filterText); 110 | 111 | auto regexString = QRegularExpression::escape(filterText); 112 | regexString.replace(QStringLiteral("\\*"), QStringLiteral(".*")); 113 | regexString.replace(QStringLiteral("\\?"), QStringLiteral(".")); 114 | QRegularExpression regex(regexString, QRegularExpression::CaseInsensitiveOption); 115 | _rootFilter->setFilter(regex); 116 | _currentEntryFilter->setFilter(regex); 117 | } 118 | 119 | void SettingsUiBuilder::startBuildUi() 120 | { 121 | if(!_buildView || !_control) 122 | return; 123 | 124 | auto setup = _control->loadSetup("quick"); 125 | emit initActions(setup.allowSearch, setup.allowRestore); 126 | 127 | _rootModel = new QGenericListModel(true, this); 128 | _rootModel->setEditable(true); 129 | auto rIndex = 0; 130 | auto hasMultiSections = false; 131 | foreach(auto cat, setup.categories) { 132 | if(cat.sections.size() == 1) { 133 | auto element = new SettingsOverElement(); 134 | element->category = tr("Others"); 135 | element->title = cat.title; 136 | element->icon = svgEscape(cat.icon); 137 | element->tooltip = cat.tooltip; 138 | element->setSettingsSection(cat.sections.first()); 139 | _rootModel->addObject(element); 140 | } else { 141 | hasMultiSections = true; 142 | foreach(auto section, cat.sections) { 143 | auto element = new SettingsOverElement(); 144 | element->category = cat.title; 145 | element->title = section.title; 146 | element->icon = svgEscape(section.icon); 147 | element->tooltip = section.tooltip; 148 | element->setSettingsSection(section); 149 | _rootModel->insertObject(rIndex++, element); 150 | } 151 | } 152 | } 153 | 154 | if(_rootModel->rowCount() == 1) { 155 | auto section = _rootModel->object(0)->settingsSection(); 156 | loadSection(section); 157 | _rootModel->deleteLater(); 158 | _rootModel = nullptr; 159 | } else { 160 | _rootFilter->clearFilterRoles(); 161 | _rootFilter->setSourceModel(_rootModel); 162 | _rootFilter->addFilterRole("category"); 163 | _rootFilter->addFilterRole("title"); 164 | _rootFilter->addFilterRole("tooltip"); 165 | _rootFilter->addFilterRole("sectionSearchKeys"); 166 | emit createView(true, _rootFilter, setup.categories.size() > 1 && hasMultiSections); 167 | } 168 | } 169 | 170 | QUrl SettingsUiBuilder::svgEscape(QUrl url) 171 | { 172 | if(url.scheme() == QStringLiteral("qrc")) { 173 | auto path = url.path(); 174 | if(path.endsWith(QStringLiteral(".svg"))) { 175 | path.chop(4); 176 | path.prepend(QStringLiteral("image://svg")); 177 | return path; 178 | } 179 | } 180 | 181 | return url; 182 | } 183 | 184 | static void registerSettingsTypes() 185 | { 186 | qmlRegisterUncreatableType("de.skycoder42.qtmvvm.settings.quick", 1, 0, "SettingsControl", QStringLiteral("Controls cannot be created!")); 187 | qmlRegisterType("de.skycoder42.qtmvvm.settings.quick", 1, 0, "SettingsUiBuilder"); 188 | } 189 | --------------------------------------------------------------------------------