mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-29 17:45:45 +08:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
7a6330fd08
@ -1,6 +1,5 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from PyQt5.QtNetwork import QLocalServer
|
from PyQt5.QtNetwork import QLocalServer
|
||||||
from PyQt5.QtNetwork import QLocalSocket
|
from PyQt5.QtNetwork import QLocalSocket
|
||||||
|
|
||||||
@ -32,6 +31,7 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
|||||||
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
|
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
|
||||||
from UM.Operations.GroupedOperation import GroupedOperation
|
from UM.Operations.GroupedOperation import GroupedOperation
|
||||||
from UM.Operations.SetTransformOperation import SetTransformOperation
|
from UM.Operations.SetTransformOperation import SetTransformOperation
|
||||||
|
|
||||||
from cura.Arrange import Arrange
|
from cura.Arrange import Arrange
|
||||||
from cura.ShapeArray import ShapeArray
|
from cura.ShapeArray import ShapeArray
|
||||||
from cura.ConvexHullDecorator import ConvexHullDecorator
|
from cura.ConvexHullDecorator import ConvexHullDecorator
|
||||||
@ -128,6 +128,7 @@ class CuraApplication(QtApplication):
|
|||||||
stacksValidationFinished = pyqtSignal() # Emitted whenever a validation is finished
|
stacksValidationFinished = pyqtSignal() # Emitted whenever a validation is finished
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
# this list of dir names will be used by UM to detect an old cura directory
|
# this list of dir names will be used by UM to detect an old cura directory
|
||||||
for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "user", "variants"]:
|
for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "user", "variants"]:
|
||||||
Resources.addExpectedDirNameInData(dir_name)
|
Resources.addExpectedDirNameInData(dir_name)
|
||||||
@ -156,7 +157,6 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
SettingDefinition.addSettingType("extruder", None, str, Validator)
|
SettingDefinition.addSettingType("extruder", None, str, Validator)
|
||||||
SettingDefinition.addSettingType("optional_extruder", None, str, None)
|
SettingDefinition.addSettingType("optional_extruder", None, str, None)
|
||||||
|
|
||||||
SettingDefinition.addSettingType("[int]", None, str, None)
|
SettingDefinition.addSettingType("[int]", None, str, None)
|
||||||
|
|
||||||
SettingFunction.registerOperator("extruderValues", ExtruderManager.getExtruderValues)
|
SettingFunction.registerOperator("extruderValues", ExtruderManager.getExtruderValues)
|
||||||
@ -181,7 +181,8 @@ class CuraApplication(QtApplication):
|
|||||||
ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.DefinitionChangesContainer)
|
ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.DefinitionChangesContainer)
|
||||||
|
|
||||||
## Initialise the version upgrade manager with Cura's storage paths.
|
## Initialise the version upgrade manager with Cura's storage paths.
|
||||||
import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies.
|
# Needs to be here to prevent circular dependencies.
|
||||||
|
import UM.VersionUpgradeManager
|
||||||
|
|
||||||
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
|
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
|
||||||
{
|
{
|
||||||
@ -227,7 +228,9 @@ class CuraApplication(QtApplication):
|
|||||||
"TranslateTool",
|
"TranslateTool",
|
||||||
"FileLogger",
|
"FileLogger",
|
||||||
"XmlMaterialProfile",
|
"XmlMaterialProfile",
|
||||||
"PluginBrowser"
|
"PluginBrowser",
|
||||||
|
"PrepareStage",
|
||||||
|
"MonitorStage"
|
||||||
])
|
])
|
||||||
self._physics = None
|
self._physics = None
|
||||||
self._volume = None
|
self._volume = None
|
||||||
@ -388,7 +391,6 @@ class CuraApplication(QtApplication):
|
|||||||
def needToShowUserAgreement(self):
|
def needToShowUserAgreement(self):
|
||||||
return self._need_to_show_user_agreement
|
return self._need_to_show_user_agreement
|
||||||
|
|
||||||
|
|
||||||
def setNeedToShowUserAgreement(self, set_value = True):
|
def setNeedToShowUserAgreement(self, set_value = True):
|
||||||
self._need_to_show_user_agreement = set_value
|
self._need_to_show_user_agreement = set_value
|
||||||
|
|
||||||
@ -666,14 +668,14 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
controller = self.getController()
|
controller = self.getController()
|
||||||
|
|
||||||
|
controller.setActiveStage("PrepareStage")
|
||||||
controller.setActiveView("SolidView")
|
controller.setActiveView("SolidView")
|
||||||
|
|
||||||
controller.setCameraTool("CameraTool")
|
controller.setCameraTool("CameraTool")
|
||||||
controller.setSelectionTool("SelectionTool")
|
controller.setSelectionTool("SelectionTool")
|
||||||
|
|
||||||
t = controller.getTool("TranslateTool")
|
t = controller.getTool("TranslateTool")
|
||||||
if t:
|
if t:
|
||||||
t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis,ToolHandle.ZAxis])
|
t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis, ToolHandle.ZAxis])
|
||||||
|
|
||||||
Selection.selectionChanged.connect(self.onSelectionChanged)
|
Selection.selectionChanged.connect(self.onSelectionChanged)
|
||||||
|
|
||||||
@ -717,6 +719,7 @@ class CuraApplication(QtApplication):
|
|||||||
run_headless = self.getCommandLineOption("headless", False)
|
run_headless = self.getCommandLineOption("headless", False)
|
||||||
if not run_headless:
|
if not run_headless:
|
||||||
self.initializeEngine()
|
self.initializeEngine()
|
||||||
|
controller.setActiveStage("PrepareStage")
|
||||||
|
|
||||||
if run_headless or self._engine.rootObjects:
|
if run_headless or self._engine.rootObjects:
|
||||||
self.closeSplash()
|
self.closeSplash()
|
||||||
|
22
cura/Stages/CuraStage.py
Normal file
22
cura/Stages/CuraStage.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
from PyQt5.QtCore import pyqtProperty, QUrl, QObject
|
||||||
|
|
||||||
|
from UM.Stage import Stage
|
||||||
|
|
||||||
|
class CuraStage(Stage):
|
||||||
|
|
||||||
|
def __init__(self, parent = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
@pyqtProperty(str, constant = True)
|
||||||
|
def stageId(self):
|
||||||
|
return self.getPluginId()
|
||||||
|
|
||||||
|
@pyqtProperty(QUrl, constant = True)
|
||||||
|
def mainComponent(self):
|
||||||
|
return self.getDisplayComponent("main")
|
||||||
|
|
||||||
|
@pyqtProperty(QUrl, constant = True)
|
||||||
|
def sidebarComponent(self):
|
||||||
|
return self.getDisplayComponent("sidebar")
|
2
cura/Stages/__init__.py
Normal file
2
cura/Stages/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
@ -22,9 +22,10 @@ if Platform.isLinux(): # Needed for platform.linux_distribution, which is not av
|
|||||||
if Platform.isWindows() and hasattr(sys, "frozen"):
|
if Platform.isWindows() and hasattr(sys, "frozen"):
|
||||||
try:
|
try:
|
||||||
del os.environ["PYTHONPATH"]
|
del os.environ["PYTHONPATH"]
|
||||||
except KeyError: pass
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
#WORKAROUND: GITHUB-704 GITHUB-708
|
# WORKAROUND: GITHUB-704 GITHUB-708
|
||||||
# It looks like setuptools creates a .pth file in
|
# It looks like setuptools creates a .pth file in
|
||||||
# the default /usr/lib which causes the default site-packages
|
# the default /usr/lib which causes the default site-packages
|
||||||
# to be inserted into sys.path before PYTHONPATH.
|
# to be inserted into sys.path before PYTHONPATH.
|
||||||
@ -45,6 +46,7 @@ def exceptHook(hook_type, value, traceback):
|
|||||||
_crash_handler = CrashHandler(hook_type, value, traceback)
|
_crash_handler = CrashHandler(hook_type, value, traceback)
|
||||||
_crash_handler.show()
|
_crash_handler.show()
|
||||||
|
|
||||||
|
|
||||||
sys.excepthook = exceptHook
|
sys.excepthook = exceptHook
|
||||||
|
|
||||||
# Workaround for a race condition on certain systems where there
|
# Workaround for a race condition on certain systems where there
|
||||||
@ -75,7 +77,7 @@ faulthandler.enable()
|
|||||||
# Force an instance of CuraContainerRegistry to be created and reused later.
|
# Force an instance of CuraContainerRegistry to be created and reused later.
|
||||||
cura.Settings.CuraContainerRegistry.CuraContainerRegistry.getInstance()
|
cura.Settings.CuraContainerRegistry.CuraContainerRegistry.getInstance()
|
||||||
|
|
||||||
# This prestart up check is needed to determine if we should start the application at all.
|
# This pre-start up check is needed to determine if we should start the application at all.
|
||||||
if not cura.CuraApplication.CuraApplication.preStartUp():
|
if not cura.CuraApplication.CuraApplication.preStartUp():
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
39
plugins/MonitorStage/MonitorMainView.qml
Normal file
39
plugins/MonitorStage/MonitorMainView.qml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
|
||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
import UM 1.3 as UM
|
||||||
|
import Cura 1.0 as Cura
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
// We show a nice overlay on the 3D viewer when the current output device has no monitor view
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: viewportOverlay
|
||||||
|
|
||||||
|
color: UM.Theme.getColor("viewport_overlay")
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
visible: monitorViewComponent.sourceComponent == null ? 1 : 0
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.AllButtons
|
||||||
|
onWheel: wheel.accepted = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader
|
||||||
|
{
|
||||||
|
id: monitorViewComponent
|
||||||
|
|
||||||
|
property real maximumWidth: parent.width
|
||||||
|
property real maximumHeight: parent.height
|
||||||
|
|
||||||
|
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null
|
||||||
|
visible: sourceComponent != null
|
||||||
|
}
|
||||||
|
}
|
73
plugins/MonitorStage/MonitorStage.py
Normal file
73
plugins/MonitorStage/MonitorStage.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
import os.path
|
||||||
|
from UM.Application import Application
|
||||||
|
from UM.PluginRegistry import PluginRegistry
|
||||||
|
from UM.Resources import Resources
|
||||||
|
from cura.Stages.CuraStage import CuraStage
|
||||||
|
|
||||||
|
|
||||||
|
## Stage for monitoring a 3D printing while it's printing.
|
||||||
|
class MonitorStage(CuraStage):
|
||||||
|
|
||||||
|
def __init__(self, parent = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
# Wait until QML engine is created, otherwise creating the new QML components will fail
|
||||||
|
Application.getInstance().engineCreatedSignal.connect(self._setComponents)
|
||||||
|
|
||||||
|
# Update the status icon when the output device is changed
|
||||||
|
Application.getInstance().getOutputDeviceManager().activeDeviceChanged.connect(self._setIconSource)
|
||||||
|
|
||||||
|
def _setComponents(self):
|
||||||
|
self._setMainOverlay()
|
||||||
|
self._setSidebar()
|
||||||
|
self._setIconSource()
|
||||||
|
|
||||||
|
def _setMainOverlay(self):
|
||||||
|
main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("MonitorStage"), "MonitorMainView.qml")
|
||||||
|
self.addDisplayComponent("main", main_component_path)
|
||||||
|
|
||||||
|
def _setSidebar(self):
|
||||||
|
# TODO: currently the sidebar component for prepare and monitor stages is the same, this will change with the printer output device refactor!
|
||||||
|
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), "Sidebar.qml")
|
||||||
|
self.addDisplayComponent("sidebar", sidebar_component_path)
|
||||||
|
|
||||||
|
def _setIconSource(self):
|
||||||
|
if Application.getInstance().getTheme() is not None:
|
||||||
|
icon_name = self._getActiveOutputDeviceStatusIcon()
|
||||||
|
self.setIconSource(Application.getInstance().getTheme().getIcon(icon_name))
|
||||||
|
|
||||||
|
## Find the correct status icon depending on the active output device state
|
||||||
|
def _getActiveOutputDeviceStatusIcon(self):
|
||||||
|
output_device = Application.getInstance().getOutputDeviceManager().getActiveDevice()
|
||||||
|
|
||||||
|
if not output_device:
|
||||||
|
return "tab_status_unknown"
|
||||||
|
|
||||||
|
if hasattr(output_device, "acceptsCommands") and not output_device.acceptsCommands:
|
||||||
|
return "tab_status_unknown"
|
||||||
|
|
||||||
|
if not hasattr(output_device, "printerState") or not hasattr(output_device, "jobState"):
|
||||||
|
return "tab_status_unknown"
|
||||||
|
|
||||||
|
# TODO: refactor to use enum instead of hardcoded strings?
|
||||||
|
if output_device.printerState == "maintenance":
|
||||||
|
return "tab_status_busy"
|
||||||
|
|
||||||
|
if output_device.jobState in ["printing", "pre_print", "pausing", "resuming"]:
|
||||||
|
return "tab_status_busy"
|
||||||
|
|
||||||
|
if output_device.jobState == "wait_cleanup":
|
||||||
|
return "tab_status_finished"
|
||||||
|
|
||||||
|
if output_device.jobState in ["ready", ""]:
|
||||||
|
return "tab_status_connected"
|
||||||
|
|
||||||
|
if output_device.jobState == "paused":
|
||||||
|
return "tab_status_paused"
|
||||||
|
|
||||||
|
if output_device.jobState == "error":
|
||||||
|
return "tab_status_stopped"
|
||||||
|
|
||||||
|
return "tab_status_unknown"
|
20
plugins/MonitorStage/__init__.py
Normal file
20
plugins/MonitorStage/__init__.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from . import MonitorStage
|
||||||
|
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
def getMetaData():
|
||||||
|
return {
|
||||||
|
"stage": {
|
||||||
|
"name": i18n_catalog.i18nc("@item:inmenu", "Monitor"),
|
||||||
|
"weight": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def register(app):
|
||||||
|
return {
|
||||||
|
"stage": MonitorStage.MonitorStage()
|
||||||
|
}
|
8
plugins/MonitorStage/plugin.json
Normal file
8
plugins/MonitorStage/plugin.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "Monitor Stage",
|
||||||
|
"author": "Ultimaker B.V.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Provides a monitor stage in Cura.",
|
||||||
|
"api": 4,
|
||||||
|
"i18n-catalog": "cura"
|
||||||
|
}
|
18
plugins/PrepareStage/PrepareStage.py
Normal file
18
plugins/PrepareStage/PrepareStage.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
import os.path
|
||||||
|
from UM.Application import Application
|
||||||
|
from UM.Resources import Resources
|
||||||
|
from cura.Stages.CuraStage import CuraStage
|
||||||
|
|
||||||
|
|
||||||
|
## Stage for preparing model (slicing).
|
||||||
|
class PrepareStage(CuraStage):
|
||||||
|
|
||||||
|
def __init__(self, parent = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
Application.getInstance().engineCreatedSignal.connect(self._engineCreated)
|
||||||
|
|
||||||
|
def _engineCreated(self):
|
||||||
|
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), "Sidebar.qml")
|
||||||
|
self.addDisplayComponent("sidebar", sidebar_component_path)
|
20
plugins/PrepareStage/__init__.py
Normal file
20
plugins/PrepareStage/__init__.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from . import PrepareStage
|
||||||
|
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
def getMetaData():
|
||||||
|
return {
|
||||||
|
"stage": {
|
||||||
|
"name": i18n_catalog.i18nc("@item:inmenu", "Prepare"),
|
||||||
|
"weight": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def register(app):
|
||||||
|
return {
|
||||||
|
"stage": PrepareStage.PrepareStage()
|
||||||
|
}
|
8
plugins/PrepareStage/plugin.json
Normal file
8
plugins/PrepareStage/plugin.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "Prepare Stage",
|
||||||
|
"author": "Ultimaker B.V.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Provides a prepare stage in Cura.",
|
||||||
|
"api": 4,
|
||||||
|
"i18n-catalog": "cura"
|
||||||
|
}
|
@ -698,7 +698,7 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte
|
|||||||
if self._reply:
|
if self._reply:
|
||||||
self._reply.abort()
|
self._reply.abort()
|
||||||
self._stage = OutputStage.ready
|
self._stage = OutputStage.ready
|
||||||
Application.getInstance().showPrintMonitor.emit(False)
|
Application.getInstance().getController().setActiveStage("PrepareStage")
|
||||||
|
|
||||||
@pyqtSlot(int, result=str)
|
@pyqtSlot(int, result=str)
|
||||||
def formatDuration(self, seconds):
|
def formatDuration(self, seconds):
|
||||||
|
@ -672,7 +672,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
Logger.log("d", "Attempting to perform an action without authentication for printer %s. Auth state is %s", self._key, self._authentication_state)
|
Logger.log("d", "Attempting to perform an action without authentication for printer %s. Auth state is %s", self._key, self._authentication_state)
|
||||||
return
|
return
|
||||||
|
|
||||||
Application.getInstance().showPrintMonitor.emit(True)
|
Application.getInstance().getController().setActiveStage("MonitorStage")
|
||||||
self._print_finished = True
|
self._print_finished = True
|
||||||
self.writeStarted.emit(self)
|
self.writeStarted.emit(self)
|
||||||
self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list")
|
self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list")
|
||||||
@ -767,7 +767,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
if button == QMessageBox.Yes:
|
if button == QMessageBox.Yes:
|
||||||
self.startPrint()
|
self.startPrint()
|
||||||
else:
|
else:
|
||||||
Application.getInstance().showPrintMonitor.emit(False)
|
Application.getInstance().getController().setActiveStage("PrepareStage")
|
||||||
# For some unknown reason Cura on OSX will hang if we do the call back code
|
# For some unknown reason Cura on OSX will hang if we do the call back code
|
||||||
# immediately without first returning and leaving QML's event system.
|
# immediately without first returning and leaving QML's event system.
|
||||||
QTimer.singleShot(100, delayedCallback)
|
QTimer.singleShot(100, delayedCallback)
|
||||||
@ -850,7 +850,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
self._write_finished = True # post_reply does not always exist, so make sure we unblock writing
|
self._write_finished = True # post_reply does not always exist, so make sure we unblock writing
|
||||||
if self._post_reply:
|
if self._post_reply:
|
||||||
self._finalizePostReply()
|
self._finalizePostReply()
|
||||||
Application.getInstance().showPrintMonitor.emit(False)
|
Application.getInstance().getController().setActiveStage("PrepareStage")
|
||||||
|
|
||||||
## Attempt to start a new print.
|
## Attempt to start a new print.
|
||||||
# This function can fail to actually start a print due to not being authenticated or another print already
|
# This function can fail to actually start a print due to not being authenticated or another print already
|
||||||
|
@ -490,7 +490,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
self.setJobName(file_name)
|
self.setJobName(file_name)
|
||||||
self._print_estimated_time = int(Application.getInstance().getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.Seconds))
|
self._print_estimated_time = int(Application.getInstance().getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.Seconds))
|
||||||
|
|
||||||
Application.getInstance().showPrintMonitor.emit(True)
|
Application.getInstance().getController().setActiveStage("MonitorStage")
|
||||||
self.startPrint()
|
self.startPrint()
|
||||||
|
|
||||||
def _setEndstopState(self, endstop_key, value):
|
def _setEndstopState(self, endstop_key, value):
|
||||||
@ -698,7 +698,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
self._is_printing = False
|
self._is_printing = False
|
||||||
self._is_paused = False
|
self._is_paused = False
|
||||||
self._updateJobState("ready")
|
self._updateJobState("ready")
|
||||||
Application.getInstance().showPrintMonitor.emit(False)
|
Application.getInstance().getController().setActiveStage("PrepareStage")
|
||||||
|
|
||||||
## Check if the process did not encounter an error yet.
|
## Check if the process did not encounter an error yet.
|
||||||
def hasError(self):
|
def hasError(self):
|
||||||
|
@ -20,14 +20,16 @@ UM.MainWindow
|
|||||||
viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
|
viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
|
||||||
property bool showPrintMonitor: false
|
property bool showPrintMonitor: false
|
||||||
|
|
||||||
|
// This connection is here to support legacy printer output devices that use the showPrintMonitor signal on Application to switch to the monitor stage
|
||||||
|
// It should be phased out in newer plugin versions.
|
||||||
Connections
|
Connections
|
||||||
{
|
{
|
||||||
target: Printer
|
target: Printer
|
||||||
onShowPrintMonitor: {
|
onShowPrintMonitor: {
|
||||||
if (show) {
|
if (show) {
|
||||||
topbar.startMonitoringPrint()
|
UM.Controller.setActiveStage("MonitorStage")
|
||||||
} else {
|
} else {
|
||||||
topbar.stopMonitoringPrint()
|
UM.Controller.setActiveStage("PrepareStage")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,7 +333,7 @@ UM.MainWindow
|
|||||||
text: catalog.i18nc("@action:button","Open File");
|
text: catalog.i18nc("@action:button","Open File");
|
||||||
iconSource: UM.Theme.getIcon("load")
|
iconSource: UM.Theme.getIcon("load")
|
||||||
style: UM.Theme.styles.tool_button
|
style: UM.Theme.styles.tool_button
|
||||||
tooltip: '';
|
tooltip: ""
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: topbar.bottom;
|
top: topbar.bottom;
|
||||||
@ -358,62 +360,49 @@ UM.MainWindow
|
|||||||
Topbar
|
Topbar
|
||||||
{
|
{
|
||||||
id: topbar
|
id: topbar
|
||||||
anchors.left:parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
monitoringPrint: base.showPrintMonitor
|
|
||||||
onStartMonitoringPrint: base.showPrintMonitor = true
|
|
||||||
onStopMonitoringPrint: base.showPrintMonitor = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Sidebar
|
|
||||||
{
|
|
||||||
id: sidebar;
|
|
||||||
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
top: topbar.bottom;
|
|
||||||
bottom: parent.bottom;
|
|
||||||
right: parent.right;
|
|
||||||
}
|
|
||||||
z: 1
|
|
||||||
width: UM.Theme.getSize("sidebar").width;
|
|
||||||
monitoringPrint: base.showPrintMonitor
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: viewportOverlay
|
|
||||||
|
|
||||||
color: UM.Theme.getColor("viewport_overlay")
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
top: topbar.bottom
|
|
||||||
bottom: parent.bottom
|
|
||||||
left:parent.left
|
|
||||||
right: sidebar.left
|
|
||||||
}
|
|
||||||
visible: opacity > 0
|
|
||||||
opacity: base.showPrintMonitor ? 1 : 0
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.AllButtons
|
|
||||||
|
|
||||||
onWheel: wheel.accepted = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader
|
Loader
|
||||||
{
|
{
|
||||||
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null
|
id: sidebar
|
||||||
visible: base.showPrintMonitor
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
{
|
||||||
anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2
|
top: topbar.bottom
|
||||||
anchors.verticalCenterOffset: UM.Theme.getSize("sidebar_header").height / 2
|
bottom: parent.bottom
|
||||||
property real maximumWidth: viewportOverlay.width
|
right: parent.right
|
||||||
property real maximumHeight: viewportOverlay.height
|
}
|
||||||
|
|
||||||
|
width: UM.Theme.getSize("sidebar").width
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
source: UM.Controller.activeStage.sidebarComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader
|
||||||
|
{
|
||||||
|
id: main
|
||||||
|
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: topbar.bottom
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: sidebar.left
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
visible: UM.Controller.activeStage.mainComponent != ""
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.AllButtons
|
||||||
|
onWheel: wheel.accepted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
source: UM.Controller.activeStage.mainComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
UM.MessageStack
|
UM.MessageStack
|
||||||
|
@ -12,21 +12,23 @@ Menu
|
|||||||
title: catalog.i18nc("@title:menu menubar:toplevel", "&View");
|
title: catalog.i18nc("@title:menu menubar:toplevel", "&View");
|
||||||
id: menu
|
id: menu
|
||||||
enabled: !PrintInformation.preSliced
|
enabled: !PrintInformation.preSliced
|
||||||
|
|
||||||
|
// main views
|
||||||
Instantiator
|
Instantiator
|
||||||
{
|
{
|
||||||
model: UM.ViewModel { }
|
model: UM.ViewModel{}
|
||||||
MenuItem
|
MenuItem
|
||||||
{
|
{
|
||||||
text: model.name;
|
text: model.name
|
||||||
checkable: true;
|
checkable: true
|
||||||
checked: model.active;
|
checked: model.active
|
||||||
exclusiveGroup: group;
|
exclusiveGroup: group
|
||||||
onTriggered: UM.Controller.setActiveView(model.id);
|
onTriggered: UM.Controller.setActiveView(model.id)
|
||||||
}
|
}
|
||||||
onObjectAdded: menu.insertItem(index, object)
|
onObjectAdded: menu.insertItem(index, object)
|
||||||
onObjectRemoved: menu.removeItem(object)
|
onObjectRemoved: menu.removeItem(object)
|
||||||
}
|
}
|
||||||
ExclusiveGroup { id: group; }
|
ExclusiveGroup { id: group }
|
||||||
|
|
||||||
MenuSeparator {}
|
MenuSeparator {}
|
||||||
MenuItem { action: Cura.Actions.homeCamera; }
|
MenuItem { action: Cura.Actions.homeCamera; }
|
||||||
|
@ -46,7 +46,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sliceOrStopSlicing() {
|
function sliceOrStopSlicing() {
|
||||||
if ([1, 5].indexOf(UM.Backend.state) != -1) {
|
if (backend != "undefined" && [1, 5].indexOf(UM.Backend.state) != -1) {
|
||||||
backend.forceSlice();
|
backend.forceSlice();
|
||||||
} else {
|
} else {
|
||||||
backend.stopSlicing();
|
backend.stopSlicing();
|
||||||
|
@ -24,7 +24,7 @@ Rectangle
|
|||||||
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
|
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
|
||||||
property int backendState: UM.Backend.state
|
property int backendState: UM.Backend.state
|
||||||
|
|
||||||
property bool monitoringPrint: false
|
property bool monitoringPrint: UM.Controller.activeStage.stageId == "MonitorStage"
|
||||||
|
|
||||||
property variant printDuration: PrintInformation.currentPrintTime
|
property variant printDuration: PrintInformation.currentPrintTime
|
||||||
property variant printMaterialLengths: PrintInformation.materialLengths
|
property variant printMaterialLengths: PrintInformation.materialLengths
|
||||||
@ -263,7 +263,7 @@ Rectangle
|
|||||||
{
|
{
|
||||||
id: controlItem
|
id: controlItem
|
||||||
anchors.bottom: footerSeparator.top
|
anchors.bottom: footerSeparator.top
|
||||||
anchors.top: headerSeparator.bottom
|
anchors.top: monitoringPrint ? base.top : headerSeparator.bottom
|
||||||
anchors.left: base.left
|
anchors.left: base.left
|
||||||
anchors.right: base.right
|
anchors.right: base.right
|
||||||
sourceComponent:
|
sourceComponent:
|
||||||
@ -282,7 +282,7 @@ Rectangle
|
|||||||
Loader
|
Loader
|
||||||
{
|
{
|
||||||
anchors.bottom: footerSeparator.top
|
anchors.bottom: footerSeparator.top
|
||||||
anchors.top: headerSeparator.bottom
|
anchors.top: monitoringPrint ? base.top : headerSeparator.bottom
|
||||||
anchors.left: base.left
|
anchors.left: base.left
|
||||||
anchors.right: base.right
|
anchors.right: base.right
|
||||||
source:
|
source:
|
||||||
|
@ -403,8 +403,6 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Infill
|
// Infill
|
||||||
//
|
//
|
||||||
@ -568,18 +566,20 @@ Item
|
|||||||
model: infillModel
|
model: infillModel
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
property int activeIndex: {
|
function activeIndex () {
|
||||||
for (var i = 0; i < infillModel.count; i++) {
|
for (var i = 0; i < infillModel.count; i++) {
|
||||||
var density = parseInt(infillDensity.properties.value)
|
var density = parseInt(infillDensity.properties.value)
|
||||||
var steps = parseInt(infillSteps.properties.value)
|
var steps = parseInt(infillSteps.properties.value)
|
||||||
var infillModelItem = infillModel.get(i)
|
var infillModelItem = infillModel.get(i)
|
||||||
|
|
||||||
if (density >= infillModelItem.percentageMin
|
if (infillModelItem != "undefined"
|
||||||
|
&& density >= infillModelItem.percentageMin
|
||||||
&& density <= infillModelItem.percentageMax
|
&& density <= infillModelItem.percentageMax
|
||||||
&& steps >= infillModelItem.stepsMin
|
&& steps >= infillModelItem.stepsMin
|
||||||
&& steps <= infillModelItem.stepsMax){
|
&& steps <= infillModelItem.stepsMax
|
||||||
return i
|
){
|
||||||
}
|
return i
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
@ -587,7 +587,7 @@ Item
|
|||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: infillIconList.activeIndex == index
|
visible: infillIconList.activeIndex() == index
|
||||||
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
border.width: UM.Theme.getSize("default_lining").width
|
||||||
border.color: UM.Theme.getColor("quality_slider_unavailable")
|
border.color: UM.Theme.getColor("quality_slider_unavailable")
|
||||||
|
@ -6,7 +6,7 @@ import QtQuick.Controls 1.1
|
|||||||
import QtQuick.Controls.Styles 1.1
|
import QtQuick.Controls.Styles 1.1
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.4 as UM
|
||||||
import Cura 1.0 as Cura
|
import Cura 1.0 as Cura
|
||||||
import "Menus"
|
import "Menus"
|
||||||
|
|
||||||
@ -16,27 +16,10 @@ Rectangle
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
height: UM.Theme.getSize("sidebar_header").height
|
height: UM.Theme.getSize("sidebar_header").height
|
||||||
color: base.monitoringPrint ? UM.Theme.getColor("topbar_background_color_monitoring") : UM.Theme.getColor("topbar_background_color")
|
color: UM.Controller.activeStage.stageId == "MonitorStage" ? UM.Theme.getColor("topbar_background_color_monitoring") : UM.Theme.getColor("topbar_background_color")
|
||||||
|
|
||||||
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
|
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
|
||||||
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
|
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
|
||||||
property bool monitoringPrint: false
|
|
||||||
|
|
||||||
// outgoing signal
|
|
||||||
signal startMonitoringPrint()
|
|
||||||
signal stopMonitoringPrint()
|
|
||||||
|
|
||||||
// update monitoring status when event was triggered outside topbar
|
|
||||||
Component.onCompleted: {
|
|
||||||
startMonitoringPrint.connect(function () {
|
|
||||||
base.monitoringPrint = true
|
|
||||||
UM.Controller.disableModelRendering()
|
|
||||||
})
|
|
||||||
stopMonitoringPrint.connect(function () {
|
|
||||||
base.monitoringPrint = false
|
|
||||||
UM.Controller.enableModelRendering()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
UM.I18nCatalog
|
UM.I18nCatalog
|
||||||
{
|
{
|
||||||
@ -67,92 +50,30 @@ Rectangle
|
|||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
spacing: UM.Theme.getSize("default_margin").width
|
spacing: UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
Button
|
// The topbar is dynamically filled with all available stages
|
||||||
|
Repeater
|
||||||
{
|
{
|
||||||
id: showSettings
|
id: stagesMenu
|
||||||
height: UM.Theme.getSize("sidebar_header").height
|
|
||||||
text: catalog.i18nc("@title:tab", "Prepare")
|
|
||||||
checkable: true
|
|
||||||
checked: isChecked()
|
|
||||||
exclusiveGroup: sidebarHeaderBarGroup
|
|
||||||
style: UM.Theme.styles.topbar_header_tab
|
|
||||||
|
|
||||||
// We use a Qt.binding to re-bind the checkbox state after manually setting it
|
model: UM.StageModel{}
|
||||||
// https://stackoverflow.com/questions/38798450/qt-5-7-qml-why-are-my-checkbox-property-bindings-disappearing
|
|
||||||
onClicked: {
|
|
||||||
base.stopMonitoringPrint()
|
|
||||||
checked = Qt.binding(isChecked)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isChecked () {
|
delegate: Button
|
||||||
return !base.monitoringPrint
|
|
||||||
}
|
|
||||||
|
|
||||||
property color overlayColor: "transparent"
|
|
||||||
property string overlayIconSource: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
Button
|
|
||||||
{
|
|
||||||
id: showMonitor
|
|
||||||
width: UM.Theme.getSize("topbar_button").width
|
|
||||||
height: UM.Theme.getSize("sidebar_header").height
|
|
||||||
text: catalog.i18nc("@title:tab", "Monitor")
|
|
||||||
checkable: true
|
|
||||||
checked: isChecked()
|
|
||||||
exclusiveGroup: sidebarHeaderBarGroup
|
|
||||||
style: UM.Theme.styles.topbar_header_tab_no_overlay
|
|
||||||
|
|
||||||
// We use a Qt.binding to re-bind the checkbox state after manually setting it
|
|
||||||
// https://stackoverflow.com/questions/38798450/qt-5-7-qml-why-are-my-checkbox-property-bindings-disappearing
|
|
||||||
onClicked: {
|
|
||||||
base.startMonitoringPrint()
|
|
||||||
checked = Qt.binding(isChecked)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isChecked () {
|
|
||||||
return base.monitoringPrint
|
|
||||||
}
|
|
||||||
|
|
||||||
property string iconSource:
|
|
||||||
{
|
{
|
||||||
if (!printerConnected)
|
text: model.name
|
||||||
{
|
checkable: true
|
||||||
return UM.Theme.getIcon("tab_status_unknown");
|
checked: model.active
|
||||||
}
|
exclusiveGroup: topbarMenuGroup
|
||||||
else if (!printerAcceptsCommands)
|
style: (model.stage.iconSource != "") ? UM.Theme.styles.topbar_header_tab_no_overlay : UM.Theme.styles.topbar_header_tab
|
||||||
{
|
height: UM.Theme.getSize("sidebar_header").height
|
||||||
return UM.Theme.getIcon("tab_status_unknown");
|
onClicked: UM.Controller.setActiveStage(model.id)
|
||||||
}
|
iconSource: model.stage.iconSource
|
||||||
|
|
||||||
if (Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
|
property color overlayColor: "transparent"
|
||||||
{
|
property string overlayIconSource: ""
|
||||||
return UM.Theme.getIcon("tab_status_busy");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Cura.MachineManager.printerOutputDevices[0].jobState)
|
|
||||||
{
|
|
||||||
case "printing":
|
|
||||||
case "pre_print":
|
|
||||||
case "pausing":
|
|
||||||
case "resuming":
|
|
||||||
return UM.Theme.getIcon("tab_status_busy");
|
|
||||||
case "wait_cleanup":
|
|
||||||
return UM.Theme.getIcon("tab_status_finished");
|
|
||||||
case "ready":
|
|
||||||
case "":
|
|
||||||
return UM.Theme.getIcon("tab_status_connected")
|
|
||||||
case "paused":
|
|
||||||
return UM.Theme.getIcon("tab_status_paused")
|
|
||||||
case "error":
|
|
||||||
return UM.Theme.getIcon("tab_status_stopped")
|
|
||||||
default:
|
|
||||||
return UM.Theme.getIcon("tab_status_unknown")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExclusiveGroup { id: sidebarHeaderBarGroup }
|
ExclusiveGroup { id: topbarMenuGroup }
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolButton
|
ToolButton
|
||||||
@ -220,17 +141,16 @@ Rectangle
|
|||||||
menu: PrinterMenu { }
|
menu: PrinterMenu { }
|
||||||
}
|
}
|
||||||
|
|
||||||
//View orientation Item
|
// View orientation Item
|
||||||
Row
|
Row
|
||||||
{
|
{
|
||||||
id: viewOrientationControl
|
id: viewOrientationControl
|
||||||
height: 30
|
height: 30
|
||||||
|
|
||||||
spacing: 2
|
spacing: 2
|
||||||
|
visible: UM.Controller.activeStage.stageId != "MonitorStage"
|
||||||
|
|
||||||
visible: !base.monitoringPrint
|
anchors
|
||||||
|
{
|
||||||
anchors {
|
|
||||||
verticalCenter: base.verticalCenter
|
verticalCenter: base.verticalCenter
|
||||||
right: viewModeButton.right
|
right: viewModeButton.right
|
||||||
rightMargin: UM.Theme.getSize("default_margin").width + viewModeButton.width
|
rightMargin: UM.Theme.getSize("default_margin").width + viewModeButton.width
|
||||||
@ -308,7 +228,7 @@ Rectangle
|
|||||||
}
|
}
|
||||||
|
|
||||||
style: UM.Theme.styles.combobox
|
style: UM.Theme.styles.combobox
|
||||||
visible: !base.monitoringPrint
|
visible: UM.Controller.activeStage.stageId != "MonitorStage"
|
||||||
|
|
||||||
model: UM.ViewModel { }
|
model: UM.ViewModel { }
|
||||||
textRole: "name"
|
textRole: "name"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user