diff --git a/examples/mvvmquick/SampleQuick/SampleView.qml b/examples/mvvmquick/SampleQuick/SampleView.qml index 6da9f84..1808e26 100644 --- a/examples/mvvmquick/SampleQuick/SampleView.qml +++ b/examples/mvvmquick/SampleQuick/SampleView.qml @@ -39,6 +39,10 @@ Page { text: qsTr("Add Color") onTriggered: viewModel.getColor() } + MenuItem { + text: qsTr("Show Progress") + onTriggered: viewModel.showProgress() + } MenuSeparator {} diff --git a/src/imports/mvvmcore/plugins.qmltypes b/src/imports/mvvmcore/plugins.qmltypes index 9a85034..ad7b1eb 100644 --- a/src/imports/mvvmcore/plugins.qmltypes +++ b/src/imports/mvvmcore/plugins.qmltypes @@ -128,7 +128,7 @@ Module { Signal { name: "closeRequested" } Signal { name: "canceled" - Parameter { name: "btn"; type: "MessageConfig::StandardButton" } + Parameter { name: "btn"; type: "QtMvvm::MessageConfig::StandardButton" } } Signal { name: "closed" } Method { name: "close" } @@ -162,7 +162,7 @@ Module { } Method { name: "requestCancel" - Parameter { name: "btn"; type: "MessageConfig::StandardButton" } + Parameter { name: "btn"; type: "QtMvvm::MessageConfig::StandardButton" } } Method { name: "notifyClosed" } } diff --git a/src/imports/mvvmquick/DialogPresenter11.qml b/src/imports/mvvmquick/DialogPresenter11.qml index 8323556..05eca03 100644 --- a/src/imports/mvvmquick/DialogPresenter11.qml +++ b/src/imports/mvvmquick/DialogPresenter11.qml @@ -76,9 +76,11 @@ QtObject { return createInput(config, result) else if(config.type == "file") return createFile(config, result) - else if(config.type == "color") { + else if(config.type == "color") return createColor(config, result) - } else + else if(config.type == "progress") + return createProgress(config, result) + else return false; } @@ -93,6 +95,10 @@ QtObject { */ function closeAction() { if(_popups.length > 0) { + if(typeof _popups[_popups.length - 1].closeAction == "function") { + if(_popups[_popups.length - 1].closeAction()) + return true; + } _popups[_popups.length - 1].reject(); return true; } else @@ -173,6 +179,24 @@ QtObject { } } + //! Internal property + property Component _progressComponent: ProgressDialog { + id: __progress + + onClosed: { + var index = _popups.indexOf(__progress); + if(index > -1) { + __progress.destroy(); + _dialogPresenter._popups.splice(index, 1); + } + } + + Component.onCompleted: { + _popups.push(__progress) + __progress.open() + } + } + /*! @brief Method present a dialog of the QtMvvm::MessageConfig::TypeMessageBox * * @param type:MessageConfig config The message configuration to create a dialog of @@ -243,4 +267,12 @@ QtObject { config.subType = "QColor"; return createInput(config, result); } + + function createProgress(config, result) { + var props = config.viewProperties; + props["msgConfig"] = config; + props["msgResult"] = result; + var incubator = _progressComponent.incubateObject(rootItem, props, Qt.Synchronous); + return incubator.status !== Component.Error; + } } diff --git a/src/imports/mvvmquick/MsgBoxBase.qml b/src/imports/mvvmquick/MsgBoxBase.qml index cddf7de..0c62fd2 100644 --- a/src/imports/mvvmquick/MsgBoxBase.qml +++ b/src/imports/mvvmquick/MsgBoxBase.qml @@ -2,7 +2,7 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Window 2.2 import QtQuick.Layouts 1.3 -import de.skycoder42.QtMvvm.Core 1.0 +import de.skycoder42.QtMvvm.Core 1.1 import de.skycoder42.QtMvvm.Quick 1.1 AlertDialog { @@ -13,6 +13,9 @@ AlertDialog { property alias iconVisible: _icon.visible property alias iconSource: _icon.source + property bool autoHandleBtns: true + + signal buttonClicked(int button) header: Pane { id: _headerPane @@ -45,6 +48,7 @@ AlertDialog { footer: DialogButtonBox { id: _btnBox + visible: msgConfig.buttons !== MessageConfig.NoButton readonly property var _allBtns: [ DialogButtonBox.NoButton, @@ -76,26 +80,27 @@ AlertDialog { } onClicked: { - if(msgResult) { + _msgBoxBase.buttonClicked(button); + if(msgResult && autoHandleBtns) { _allBtns.forEach(function(sBtn) { if(button === standardButton(sBtn)) { msgResult.complete(sBtn); msgResult = null; } - }) + }); } } } onClosed: { - if(msgResult) { + if(msgResult && autoHandleBtns) { msgResult.complete(MessageConfig.NoButton); msgResult = null; } } Component.onCompleted: { - if(msgResult) + if(msgResult && autoHandleBtns) msgResult.setCloseTarget(_msgBoxBase, "reject()"); } } diff --git a/src/imports/mvvmquick/PopupPresenter11.qml b/src/imports/mvvmquick/PopupPresenter11.qml index f631f81..35392f5 100644 --- a/src/imports/mvvmquick/PopupPresenter11.qml +++ b/src/imports/mvvmquick/PopupPresenter11.qml @@ -95,6 +95,10 @@ QtObject { */ function closeAction() { if(_popups.length > 0) { + if(typeof _popups[_popups.length - 1].closeAction == "function") { + if(_popups[_popups.length - 1].closeAction()) + return true; + } _popups[_popups.length - 1].close(); return true; } else diff --git a/src/imports/mvvmquick/ProgressDialog.qml b/src/imports/mvvmquick/ProgressDialog.qml new file mode 100644 index 0000000..dd0aa64 --- /dev/null +++ b/src/imports/mvvmquick/ProgressDialog.qml @@ -0,0 +1,97 @@ +import QtQuick 2.10 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import de.skycoder42.QtMvvm.Core 1.1 +import de.skycoder42.QtMvvm.Quick 1.1 + +MsgBoxBase { + id: _progressDialog + + closePolicy: Popup.NoAutoClose + autoHandleBtns: false + + readonly property ProgressControl progressControl: msgConfig.defaultValue + property string format: "%p%" + + property int _cancelAction: MessageConfig.NoButton + readonly property bool _allowClose: !progressControl || !msgResult + + onButtonClicked: tryCancel(button) + onAboutToHide: { //TODO find a way to NOT auto react on button presses... better that this solution + var closeFn = function(){ + if(!_allowClose) + _progressDialog.visible = true; + }; + if(QuickPresenter.currentStyle == "Material") + Qt.callLater(closeFn); + else + closeFn(); + } + + Component.onCompleted: { + if(msgResult) + msgResult.setCloseTarget(_progressDialog, "finish()"); + } + + function finish() { + msgResult.complete(_cancelAction); + msgResult = null; + close(); + } + + function tryCancel(button) { + if(_cancelAction == MessageConfig.NoButton) { + _cancelAction = button; + footer.enabled = false; + if(progressControl) + progressControl.requestCancel(button); + else + finish(); + } + } + + function closeAction() { + tryCancel(MessageConfig.Cancel); + return true; + } + + Connections { + target: progressControl + onChangeLabel: _contentLabel.text = text; + onCloseRequested: finish() + } + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + id: _contentLabel + text: msgConfig.text.replace(/<\/p>/g, "


") //needed because qml does not put space between paragraphs... + visible: text != "" + Layout.fillWidth: true + Layout.columnSpan: 2 + wrapMode: Text.Wrap + onLinkActivated: Qt.openUrlExternally(link) + } + + ProgressBar { + id: _loadProgress + Layout.fillWidth: true + Layout.columnSpan: progressControl.indeterminate ? 2 : 1 + indeterminate: progressControl.indeterminate + from: progressControl.minimum + to: progressControl.maximum + value: progressControl.progress + } + + Label { + id: _progressLabel + visible: !progressControl.indeterminate + text: format + .replace("%p", Math.round(((progressControl.progress - progressControl.minimum) / (progressControl.maximum - progressControl.minimum)) * 100.0)) + .replace("%v", progressControl.progress) + .replace("%m", progressControl.maximum - progressControl.minimum) + } + } +} diff --git a/src/imports/mvvmquick/mvvmquick.pro b/src/imports/mvvmquick/mvvmquick.pro index 029bc47..b92db8d 100644 --- a/src/imports/mvvmquick/mvvmquick.pro +++ b/src/imports/mvvmquick/mvvmquick.pro @@ -59,7 +59,8 @@ QML_FILES += \ TimeEdit.qml \ DateEdit.qml \ ColorHelper.qml \ - ColorEdit.qml + ColorEdit.qml \ + ProgressDialog.qml RESOURCES += \ qtmvvmquick_plugin.qrc diff --git a/src/imports/mvvmquick/qmldir b/src/imports/mvvmquick/qmldir index f9c27aa..f678df0 100644 --- a/src/imports/mvvmquick/qmldir +++ b/src/imports/mvvmquick/qmldir @@ -10,6 +10,7 @@ depends de.skycoder42.QtMvvm.Core 1.0 internal MsgBoxBase MsgBoxBase.qml internal MsgBox MsgBox.qml internal InputDialog InputDialog.qml +internal ProgressDialog ProgressDialog.qml internal ListSection ListSection.qml internal SectionListView SectionListView.qml diff --git a/src/mvvmcore/message.cpp b/src/mvvmcore/message.cpp index 84b1a3b..9cec27c 100644 --- a/src/mvvmcore/message.cpp +++ b/src/mvvmcore/message.cpp @@ -739,7 +739,7 @@ MessageResult *QtMvvm::showProgress(const QString &title, const QString &label, MessageConfig config(MessageConfig::TypeProgressDialog, isBusy ? MessageConfig::SubTypeBusy : MessageConfig::SubTypeProgress); config.setTitle(title); config.setText(label); - config.setDefaultValue(QVariant::fromValue>(control)); + config.setDefaultValue(QVariant::fromValue(control)); config.setButtons(allowCancel ? MessageConfig::Cancel : MessageConfig::NoButton); return CoreApp::showDialog(config); } diff --git a/src/mvvmcore/message.h b/src/mvvmcore/message.h index 9d8526a..f70e672 100644 --- a/src/mvvmcore/message.h +++ b/src/mvvmcore/message.h @@ -263,7 +263,7 @@ public: int maximum() const; int progress() const; - Q_INVOKABLE void requestCancel(MessageConfig::StandardButton btn); + Q_INVOKABLE void requestCancel(QtMvvm::MessageConfig::StandardButton btn); Q_INVOKABLE void notifyClosed(); public Q_SLOTS: @@ -287,7 +287,7 @@ Q_SIGNALS: void changeLabel(const QString &text, QPrivateSignal); void closeRequested(QPrivateSignal); - void canceled(MessageConfig::StandardButton btn, QPrivateSignal); + void canceled(QtMvvm::MessageConfig::StandardButton btn, QPrivateSignal); void closed(QPrivateSignal); private: diff --git a/src/mvvmwidgets/widgetspresenter.cpp b/src/mvvmwidgets/widgetspresenter.cpp index 5038e15..1c09655 100644 --- a/src/mvvmwidgets/widgetspresenter.cpp +++ b/src/mvvmwidgets/widgetspresenter.cpp @@ -482,7 +482,7 @@ void WidgetsPresenter::presentColorDialog(const MessageConfig &config, const QPo void WidgetsPresenter::presentProgressDialog(const MessageConfig &config, const QPointer &result) { - auto control = config.defaultValue().value>(); + auto control = config.defaultValue().value(); if(!control) { logWarning() << "ProgressControl was destroyed before a progress dialog could be shown"; return;