From dbd28419ade062b82e2b7184aff5ced0db4ebf10 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 14 May 2018 10:25:41 +0200 Subject: Deal with asynchronous component creation. On windows event local components are apparently instantiated asynchronously. --- components/kube/qml/Kube.qml | 5 ++- components/kube/qml/ViewManager.qml | 88 +++++++++++++++++++------------------ framework/qml/Messages.qml | 1 + views/log/qml/View.qml | 3 ++ 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/components/kube/qml/Kube.qml b/components/kube/qml/Kube.qml index 61933908..8d77ddb5 100644 --- a/components/kube/qml/Kube.qml +++ b/components/kube/qml/Kube.qml @@ -199,7 +199,10 @@ Controls2.ApplicationWindow { onClicked: kubeViews.showView("log") activeFocusOnTab: true checkable: true - alert: kubeViews.getView("log").pendingError + Kube.Listener { + filter: Kube.Messages.errorPending + onMessageReceived: logButton.alert = message.errorPending + } checked: kubeViews.currentViewName == "log" Controls2.ButtonGroup.group: viewButtonGroup tooltip: qsTr("logview") diff --git a/components/kube/qml/ViewManager.qml b/components/kube/qml/ViewManager.qml index 4c28403f..15ff2638 100644 --- a/components/kube/qml/ViewManager.qml +++ b/components/kube/qml/ViewManager.qml @@ -19,49 +19,17 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 -/* -* TODO -* * Only replace composer if necessary (on reply, edit draft, ...) -* * Shutdown procedure to save draft before destruction -* * Separate logging from view and and make accessible to log (initialize()) call? -*/ + StackView { id: root property string currentViewName: currentItem ? currentItem.objectName : "" property variant extensionModel: null property bool dontFocus: false + /* + * We maintain the view's lifetimes separately from the StackView in the viewDict. + */ property var viewDict: new Object - function getView(name, replaceView) { - if (name in viewDict) { - var item = viewDict[name] - if (item) { - if (replaceView) { - if (item && item.aborted) { - //Call the aborted hook on the view - item.aborted() - } - } else { - return item - } - } - } - - var source = extensionModel.findSource(name, "View.qml"); - var component = Qt.createComponent(source) - if (component.status == Component.Ready) { - var o = component.createObject(root) - viewDict[name] = o - return o - } else if (component.status == Component.Error) { - console.error("Error while loading the component: ", source, "\nError: ", component.errorString()) - } else if (component.status == Component.Loading) { - console.error("Error while loading the component: ", source, "\nThe component is loading.") - } else { - console.error("Unknown error while loading the component: ", source) - } - return null - } onCurrentItemChanged: { if (currentItem && !dontFocus) { @@ -69,6 +37,13 @@ StackView { } } + function pushView(view, properties, name) { + var item = push(view, properties, StackView.Immediate) + item.parent = root + item.anchors.fill = root + item.objectName = name + } + function showOrReplaceView(name, properties, replace) { if (currentItem && currentItem.objectName == name) { return @@ -80,14 +55,41 @@ StackView { if (currentItem && currentItem.objectName == name) { return } - var view = getView(name, replace) - if (!view) { - return + + var item = name in viewDict ? viewDict[name] : null + if (item) { + if (replace) { + if (item.aborted) { + //Call the aborted hook on the view + item.aborted() + } + //Fall through to create new component to replace this one + } else { + pushView(item, properties, name) + return + } + } + + //Creating a new view + var source = extensionModel.findSource(name, "View.qml"); + //On windows it will be async anyways, so just always create it async + var component = Qt.createComponent(source, Qt.Asynchronous) + + function finishCreation() { + if (component.status == Component.Ready) { + var view = component.createObject(root); + viewDict[name] = view + pushView(view, properties, name) + } else { + console.error("Error while loading the component: ", source, "\nError: ", component.errorString()) + } + } + + if (component.status == Component.Loading) { + component.statusChanged.connect(finishCreation); + } else { + finishCreation(); } - var item = push(view, properties, StackView.Immediate) - item.parent = root - item.anchors.fill = root - item.objectName = name } function showView(name, properties) { diff --git a/framework/qml/Messages.qml b/framework/qml/Messages.qml index 1483a71c..f357b78b 100644 --- a/framework/qml/Messages.qml +++ b/framework/qml/Messages.qml @@ -51,6 +51,7 @@ Item { property string sendOutbox: "sendOutbox" property string componentDone: "done" + property string errorPending: "errorPending" property string selectNextConversation: "selectNextConversation" property string selectPreviousConversation: "selectPreviousConversation" diff --git a/views/log/qml/View.qml b/views/log/qml/View.qml index bf06b76c..3aa76025 100644 --- a/views/log/qml/View.qml +++ b/views/log/qml/View.qml @@ -27,6 +27,9 @@ Controls1.SplitView { id: root property bool pendingError: false; + onPendingErrorChanged: { + Kube.Fabric.postMessage(Kube.Messages.errorPending, {errorPending: pendingError}) + } Controls2.StackView.onActivated: { root.pendingError = false; -- cgit v1.2.3