Browse Source

Merge pull request #5604 from Ultimaker/CURA-6447_fix_start_onboarding

CURA-6447 Fix start onboarding
Jaime van Kessel 5 years ago
parent
commit
f2044998ae

+ 29 - 1
cura/CuraApplication.py

@@ -112,7 +112,9 @@ from cura.UI import CuraSplashScreen, MachineActionManager, PrintInformation
 from cura.UI.MachineSettingsManager import MachineSettingsManager
 from cura.UI.ObjectsModel import ObjectsModel
 from cura.UI.TextManager import TextManager
+from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel
 from cura.UI.WelcomePagesModel import WelcomePagesModel
+from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel
 
 from .SingleInstance import SingleInstance
 from .AutoSave import AutoSave
@@ -217,6 +219,8 @@ class CuraApplication(QtApplication):
         self._discovered_printer_model = DiscoveredPrintersModel(self)
         self._first_start_machine_actions_model = FirstStartMachineActionsModel(self)
         self._welcome_pages_model = WelcomePagesModel(self)
+        self._add_printer_pages_model = AddPrinterPagesModel(self)
+        self._whats_new_pages_model = WhatsNewPagesModel(self)
         self._text_manager = TextManager(self)
 
         self._quality_profile_drop_down_menu_model = None
@@ -762,6 +766,8 @@ class CuraApplication(QtApplication):
 
         self._output_device_manager.start()
         self._welcome_pages_model.initialize()
+        self._add_printer_pages_model.initialize()
+        self._whats_new_pages_model.initialize()
 
         # Detect in which mode to run and execute that mode
         if self._is_headless:
@@ -873,6 +879,14 @@ class CuraApplication(QtApplication):
     def getWelcomePagesModel(self, *args) -> "WelcomePagesModel":
         return self._welcome_pages_model
 
+    @pyqtSlot(result = QObject)
+    def getAddPrinterPagesModel(self, *args) -> "AddPrinterPagesModel":
+        return self._add_printer_pages_model
+
+    @pyqtSlot(result = QObject)
+    def getWhatsNewPagesModel(self, *args) -> "WhatsNewPagesModel":
+        return self._whats_new_pages_model
+
     @pyqtSlot(result = QObject)
     def getMachineSettingsManager(self, *args) -> "MachineSettingsManager":
         return self._machine_settings_manager
@@ -1014,6 +1028,8 @@ class CuraApplication(QtApplication):
         qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
 
         qmlRegisterType(WelcomePagesModel, "Cura", 1, 0, "WelcomePagesModel")
+        qmlRegisterType(WhatsNewPagesModel, "Cura", 1, 0, "WhatsNewPagesModel")
+        qmlRegisterType(AddPrinterPagesModel, "Cura", 1, 0, "AddPrinterPagesModel")
         qmlRegisterType(TextManager, "Cura", 1, 0, "TextManager")
 
         qmlRegisterType(NetworkMJPGImage, "Cura", 1, 0, "NetworkMJPGImage")
@@ -1098,7 +1114,6 @@ class CuraApplication(QtApplication):
             self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition())
             self._camera_animation.start()
 
-    requestAddPrinter = pyqtSignal()
     activityChanged = pyqtSignal()
     sceneBoundingBoxChanged = pyqtSignal()
 
@@ -1758,3 +1773,16 @@ class CuraApplication(QtApplication):
     def getSidebarCustomMenuItems(self) -> list:
         return self._sidebar_custom_menu_items
 
+    @pyqtSlot(result = bool)
+    def shouldShowWelcomeDialog(self) -> bool:
+        # Only show the complete flow if there is no printer yet.
+        return self._machine_manager.activeMachine is None
+
+    @pyqtSlot(result = bool)
+    def shouldShowWhatsNewDialog(self) -> bool:
+        has_active_machine = self._machine_manager.activeMachine is not None
+        has_app_just_upgraded = self.hasJustUpdatedFromOldVersion()
+
+        # Only show the what's new dialog if there's no machine and we have just upgraded
+        show_whatsnew_only = has_active_machine and has_app_just_upgraded
+        return show_whatsnew_only

+ 30 - 0
cura/UI/AddPrinterPagesModel.py

@@ -0,0 +1,30 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from .WelcomePagesModel import WelcomePagesModel
+
+
+#
+# This Qt ListModel is more or less the same the WelcomePagesModel, except that this model is only for adding a printer,
+# so only the steps for adding a printer is included.
+#
+class AddPrinterPagesModel(WelcomePagesModel):
+
+    def initialize(self) -> None:
+        self._pages.append({"id": "add_network_or_local_printer",
+                            "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
+                            "next_page_id": "machine_actions",
+                            "next_page_button_text": self._catalog.i18nc("@action:button", "Add"),
+                            })
+        self._pages.append({"id": "add_printer_by_ip",
+                            "page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
+                            "next_page_id": "machine_actions",
+                            })
+        self._pages.append({"id": "machine_actions",
+                            "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
+                            "should_show_function": self.shouldShowMachineActions,
+                            })
+        self.setItems(self._pages)
+
+
+__all__ = ["AddPrinterPagesModel"]

+ 51 - 31
cura/UI/WelcomePagesModel.py

@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Optional, List, Dict, Any
 
 from PyQt5.QtCore import QUrl, Qt, pyqtSlot, pyqtProperty, pyqtSignal
 
+from UM.i18n import i18nCatalog
 from UM.Logger import Logger
 from UM.Qt.ListModel import ListModel
 from UM.Resources import Resources
@@ -23,6 +24,9 @@ if TYPE_CHECKING:
 #  - page_url     : The QUrl to the QML file that contains the content of this page
 #  - next_page_id : (OPTIONAL) The next page ID to go to when this page finished. This is optional. If this is not
 #                   provided, it will go to the page with the current index + 1
+#  - next_page_button_text: (OPTIONAL) The text to show for the "next" button, by default it's the translated text of
+#                           "Next". Note that each step QML can decide whether to use this text or not, so it's not
+#                           mandatory.
 #  - should_show_function : (OPTIONAL) An optional function that returns True/False indicating if this page should be
 #                           shown. By default all pages should be shown. If a function returns False, that page will
 #                           be skipped and its next page will be shown.
@@ -34,6 +38,7 @@ class WelcomePagesModel(ListModel):
     IdRole = Qt.UserRole + 1  # Page ID
     PageUrlRole = Qt.UserRole + 2  # URL to the page's QML file
     NextPageIdRole = Qt.UserRole + 3  # The next page ID it should go to
+    NextPageButtonTextRole = Qt.UserRole + 4  # The text for the next page button
 
     def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
         super().__init__(parent)
@@ -41,8 +46,12 @@ class WelcomePagesModel(ListModel):
         self.addRoleName(self.IdRole, "id")
         self.addRoleName(self.PageUrlRole, "page_url")
         self.addRoleName(self.NextPageIdRole, "next_page_id")
+        self.addRoleName(self.NextPageButtonTextRole, "next_page_button_text")
 
         self._application = application
+        self._catalog = i18nCatalog("cura")
+
+        self._default_next_button_text = self._catalog.i18nc("@action:button", "Next")
 
         self._pages = []  # type: List[Dict[str, Any]]
 
@@ -137,7 +146,8 @@ class WelcomePagesModel(ListModel):
         page_index = self.getPageIndexById(page_id)
         if page_index is None:
             # FIXME: If we cannot find the next page, we cannot do anything here.
-            Logger.log("e", "Cannot find page with ID [%s]", page_index)
+            Logger.log("e", "Cannot find page with ID [%s], go to the next page by default", page_index)
+            self.goToNextPage()
             return
 
         if self._shouldPageBeShown(page_index):
@@ -180,38 +190,48 @@ class WelcomePagesModel(ListModel):
                                                     os.path.join("WelcomePages", page_filename)))
 
     def initialize(self) -> None:
-        # Add default welcome pages
-        self._pages.append({"id": "welcome",
-                            "page_url": self._getBuiltinWelcomePagePath("WelcomeContent.qml"),
-                            })
-        self._pages.append({"id": "user_agreement",
-                            "page_url": self._getBuiltinWelcomePagePath("UserAgreementContent.qml"),
-                            })
-        self._pages.append({"id": "whats_new",
-                            "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"),
-                            })
-        self._pages.append({"id": "data_collections",
-                            "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"),
-                            })
-        self._pages.append({"id": "add_network_or_local_printer",
-                            "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
-                            "next_page_id": "machine_actions",
-                            })
-        self._pages.append({"id": "add_printer_by_ip",
-                            "page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
-                            "next_page_id": "machine_actions",
-                            })
-        self._pages.append({"id": "machine_actions",
-                            "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
-                            "next_page_id": "cloud",
-                            "should_show_function": self.shouldShowMachineActions,
-                            })
-        self._pages.append({"id": "cloud",
-                            "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
-                            })
-
+        # All pages
+        all_pages_list = [{"id": "welcome",
+                           "page_url": self._getBuiltinWelcomePagePath("WelcomeContent.qml"),
+                           },
+                          {"id": "user_agreement",
+                           "page_url": self._getBuiltinWelcomePagePath("UserAgreementContent.qml"),
+                           },
+                          {"id": "whats_new",
+                           "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"),
+                           },
+                          {"id": "data_collections",
+                           "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"),
+                           },
+                          {"id": "add_network_or_local_printer",
+                           "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
+                           "next_page_id": "machine_actions",
+                           },
+                          {"id": "add_printer_by_ip",
+                           "page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
+                           "next_page_id": "machine_actions",
+                           },
+                          {"id": "machine_actions",
+                           "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
+                           "next_page_id": "cloud",
+                           "should_show_function": self.shouldShowMachineActions,
+                           },
+                          {"id": "cloud",
+                           "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
+                           },
+                          ]
+
+        self._pages = all_pages_list
         self.setItems(self._pages)
 
+    # For convenience, inject the default "next" button text to each item if it's not present.
+    def setItems(self, items: List[Dict[str, Any]]) -> None:
+        for item in items:
+            if "next_page_button_text" not in item:
+                item["next_page_button_text"] = self._default_next_button_text
+
+        super().setItems(items)
+
     # Indicates if the machine action panel should be shown by checking if there's any first start machine actions
     # available.
     def shouldShowMachineActions(self) -> bool:

+ 22 - 0
cura/UI/WhatsNewPagesModel.py

@@ -0,0 +1,22 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from .WelcomePagesModel import WelcomePagesModel
+
+
+#
+# This Qt ListModel is more or less the same the WelcomePagesModel, except that this model is only for showing the
+# "what's new" page. This is also used in the "Help" menu to show the changes log.
+#
+class WhatsNewPagesModel(WelcomePagesModel):
+
+    def initialize(self) -> None:
+        self._pages = []
+        self._pages.append({"id": "whats_new",
+                            "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"),
+                            "next_page_button_text": self._catalog.i18nc("@action:button", "Close"),
+                            })
+        self.setItems(self._pages)
+
+
+__all__ = ["WhatsNewPagesModel"]

+ 0 - 65
plugins/ChangeLogPlugin/ChangeLog.py

@@ -1,65 +0,0 @@
-# Copyright (c) 2019 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-import os.path
-
-from PyQt5.QtCore import QObject
-
-from UM.i18n import i18nCatalog
-from UM.Extension import Extension
-from UM.Application import Application
-from UM.PluginRegistry import PluginRegistry
-from UM.Version import Version
-
-catalog = i18nCatalog("cura")
-
-
-class ChangeLog(Extension, QObject):
-    def __init__(self, parent = None):
-        QObject.__init__(self, parent)
-        Extension.__init__(self)
-        self._changelog_window = None
-        self._changelog_context = None
-        version_string = Application.getInstance().getVersion()
-        if version_string is not "master":
-            self._current_app_version = Version(version_string)
-        else:
-            self._current_app_version = None
-
-        Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
-        Application.getInstance().getPreferences().addPreference("general/latest_version_changelog_shown", "2.0.0") #First version of CURA with uranium
-        self.setMenuName(catalog.i18nc("@item:inmenu", "Changelog"))
-        self.addMenuItem(catalog.i18nc("@item:inmenu", "Show Changelog"), self.showChangelog)
-
-    def _onEngineCreated(self):
-        if not self._current_app_version:
-            return #We're on dev branch.
-
-        if Application.getInstance().getPreferences().getValue("general/latest_version_changelog_shown") == "master":
-            latest_version_shown = Version("0.0.0")
-        else:
-            latest_version_shown = Version(Application.getInstance().getPreferences().getValue("general/latest_version_changelog_shown"))
-
-        Application.getInstance().getPreferences().setValue("general/latest_version_changelog_shown", Application.getInstance().getVersion())
-
-        # Do not show the changelog when there is no global container stack
-        # This implies we are running Cura for the first time.
-        if not Application.getInstance().getGlobalContainerStack():
-            return
-
-        if self._current_app_version > latest_version_shown:
-            self.showChangelog()
-
-    def showChangelog(self):
-        if not self._changelog_window:
-            self.createChangelogWindow()
-
-        self._changelog_window.show()
-
-    def hideChangelog(self):
-        if self._changelog_window:
-            self._changelog_window.hide()
-
-    def createChangelogWindow(self):
-        path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml")
-        self._changelog_window = Application.getInstance().createQmlComponent(path, {"manager": self})

+ 0 - 43
plugins/ChangeLogPlugin/ChangeLog.qml

@@ -1,43 +0,0 @@
-// Copyright (c) 2015 Ultimaker B.V.
-// Cura is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.1
-import QtQuick.Controls 1.3
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
-
-import UM 1.3 as UM
-import Cura 1.0 as Cura
-
-
-UM.Dialog
-{
-    id: base
-    minimumWidth: (UM.Theme.getSize("modal_window_minimum").width * 0.75) | 0
-    minimumHeight: (UM.Theme.getSize("modal_window_minimum").height * 0.75) | 0
-    width: minimumWidth
-    height: minimumHeight
-    title: catalog.i18nc("@label", "Changelog")
-
-    TextArea
-    {
-        anchors.fill: parent
-        text: CuraApplication.getTextManager().getChangeLogText()
-        readOnly: true;
-        textFormat: TextEdit.RichText
-    }
-
-    rightButtons: [
-        Button
-        {
-            UM.I18nCatalog
-            {
-                id: catalog
-                name: "cura"
-            }
-
-            text: catalog.i18nc("@action:button", "Close")
-            onClicked: base.hide()
-        }
-    ]
-}

+ 0 - 11
plugins/ChangeLogPlugin/__init__.py

@@ -1,11 +0,0 @@
-# Copyright (c) 2015 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from . import ChangeLog
-
-
-def getMetaData():
-    return {}
-
-def register(app):
-    return {"extension": ChangeLog.ChangeLog()}

+ 0 - 8
plugins/ChangeLogPlugin/plugin.json

@@ -1,8 +0,0 @@
-{
-    "name": "Changelog",
-    "author": "Ultimaker B.V.",
-    "version": "1.0.1",
-    "description": "Shows changes since latest checked version.",
-    "api": "6.0",
-    "i18n-catalog": "cura"
-}

+ 2 - 2
plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml

@@ -23,11 +23,11 @@ Cura.MachineAction
         Label
         {
             id: pageDescription
-            anchors.top: pageTitle.bottom
+            anchors.top: parent.top
             anchors.topMargin: UM.Theme.getSize("default_margin").height
             width: parent.width
             wrapMode: Text.WordWrap
-            text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker 2.")
+            text: catalog.i18nc("@label", "Please select any upgrades made to this Ultimaker 2.")
             font: UM.Theme.getFont("medium")
             renderType: Text.NativeRendering
         }

+ 5 - 0
plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py

@@ -71,6 +71,11 @@ class VersionUpgrade40to41(VersionUpgrade):
         parser["general"]["version"] = "6"
         if "metadata" not in parser:
             parser["metadata"] = {}
+
+        # Remove changelog plugin
+        if "latest_version_changelog_shown" in parser["general"]:
+            del parser["general"]["latest_version_changelog_shown"]
+
         parser["metadata"]["setting_version"] = "7"
 
         result = io.StringIO()

Some files were not shown because too many files changed in this diff