From add9669a0f3dd0ce3137002f9678e0077f62a8d4 Mon Sep 17 00:00:00 2001
From: Skycoder42
Date: Thu, 28 Jun 2018 22:50:41 +0200
Subject: [PATCH] added qml progress dialog
---
examples/mvvmquick/SampleQuick/SampleView.qml | 4 +
src/imports/mvvmcore/plugins.qmltypes | 4 +-
src/imports/mvvmquick/DialogPresenter11.qml | 36 ++++++-
src/imports/mvvmquick/MsgBoxBase.qml | 15 ++-
src/imports/mvvmquick/PopupPresenter11.qml | 4 +
src/imports/mvvmquick/ProgressDialog.qml | 97 +++++++++++++++++++
src/imports/mvvmquick/mvvmquick.pro | 3 +-
src/imports/mvvmquick/qmldir | 1 +
src/mvvmcore/message.cpp | 2 +-
src/mvvmcore/message.h | 4 +-
src/mvvmwidgets/widgetspresenter.cpp | 2 +-
11 files changed, 158 insertions(+), 14 deletions(-)
create mode 100644 src/imports/mvvmquick/ProgressDialog.qml
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;