Merge branch '4.0' into unify_font_types

This commit is contained in:
Diego Prado Gesto 2018-12-19 11:56:22 +01:00
commit ef2fb53790
141 changed files with 1872 additions and 3377 deletions

View file

@ -44,7 +44,7 @@ class Account(QObject):
OAUTH_SERVER_URL= self._oauth_root, OAUTH_SERVER_URL= self._oauth_root,
CALLBACK_PORT=self._callback_port, CALLBACK_PORT=self._callback_port,
CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port),
CLIENT_ID="um---------------ultimaker_cura_drive_plugin", CLIENT_ID="um----------------------------ultimaker_cura",
CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write",
AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data",
AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root),

View file

@ -66,6 +66,11 @@ class Arrange:
continue continue
vertices = vertices.getMinkowskiHull(Polygon.approximatedCircle(min_offset)) vertices = vertices.getMinkowskiHull(Polygon.approximatedCircle(min_offset))
points = copy.deepcopy(vertices._points) points = copy.deepcopy(vertices._points)
# After scaling (like up to 0.1 mm) the node might not have points
if len(points) == 0:
continue
shape_arr = ShapeArray.fromPolygon(points, scale = scale) shape_arr = ShapeArray.fromPolygon(points, scale = scale)
arranger.place(0, 0, shape_arr) arranger.place(0, 0, shape_arr)

View file

@ -51,6 +51,7 @@ from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
from cura.Arranging.ShapeArray import ShapeArray from cura.Arranging.ShapeArray import ShapeArray
from cura.MultiplyObjectsJob import MultiplyObjectsJob from cura.MultiplyObjectsJob import MultiplyObjectsJob
from cura.PrintersModel import PrintersModel
from cura.Scene.ConvexHullDecorator import ConvexHullDecorator from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
from cura.Operations.SetParentOperation import SetParentOperation from cura.Operations.SetParentOperation import SetParentOperation
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
@ -113,6 +114,7 @@ from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
from cura.ObjectsModel import ObjectsModel from cura.ObjectsModel import ObjectsModel
from cura.PrinterOutputDevice import PrinterOutputDevice
from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
@ -134,7 +136,7 @@ except ImportError:
CuraVersion = "master" # [CodeStyle: Reflecting imported value] CuraVersion = "master" # [CodeStyle: Reflecting imported value]
CuraBuildType = "" CuraBuildType = ""
CuraDebugMode = False CuraDebugMode = False
CuraSDKVersion = "5.0.0" CuraSDKVersion = "6.0.0"
class CuraApplication(QtApplication): class CuraApplication(QtApplication):
@ -205,6 +207,8 @@ class CuraApplication(QtApplication):
self._container_manager = None self._container_manager = None
self._object_manager = None self._object_manager = None
self._extruders_model = None
self._extruders_model_with_optional = None
self._build_plate_model = None self._build_plate_model = None
self._multi_build_plate_model = None self._multi_build_plate_model = None
self._setting_visibility_presets_model = None self._setting_visibility_presets_model = None
@ -862,6 +866,19 @@ class CuraApplication(QtApplication):
self._object_manager = ObjectsModel.createObjectsModel() self._object_manager = ObjectsModel.createObjectsModel()
return self._object_manager return self._object_manager
@pyqtSlot(result = QObject)
def getExtrudersModel(self, *args) -> "ExtrudersModel":
if self._extruders_model is None:
self._extruders_model = ExtrudersModel(self)
return self._extruders_model
@pyqtSlot(result = QObject)
def getExtrudersModelWithOptional(self, *args) -> "ExtrudersModel":
if self._extruders_model_with_optional is None:
self._extruders_model_with_optional = ExtrudersModel(self)
self._extruders_model_with_optional.setAddOptionalExtruder(True)
return self._extruders_model_with_optional
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getMultiBuildPlateModel(self, *args) -> MultiBuildPlateModel: def getMultiBuildPlateModel(self, *args) -> MultiBuildPlateModel:
if self._multi_build_plate_model is None: if self._multi_build_plate_model is None:
@ -954,6 +971,7 @@ class CuraApplication(QtApplication):
qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel") qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel")
qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer") qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
qmlRegisterType(PrintersModel, "Cura", 1, 0, "PrintersModel")
qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel") qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel")
qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
@ -975,6 +993,8 @@ class CuraApplication(QtApplication):
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance) qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance)
qmlRegisterType(SidebarCustomMenuItemsModel, "Cura", 1, 0, "SidebarCustomMenuItemsModel") qmlRegisterType(SidebarCustomMenuItemsModel, "Cura", 1, 0, "SidebarCustomMenuItemsModel")
qmlRegisterType(PrinterOutputDevice, "Cura", 1, 0, "PrinterOutputDevice")
from cura.API import CuraAPI from cura.API import CuraAPI
qmlRegisterSingletonType(CuraAPI, "Cura", 1, 1, "API", self.getCuraAPI) qmlRegisterSingletonType(CuraAPI, "Cura", 1, 1, "API", self.getCuraAPI)

View file

@ -106,10 +106,7 @@ class BaseMaterialsModel(ListModel):
return False return False
extruder_stack = global_stack.extruders[extruder_position] extruder_stack = global_stack.extruders[extruder_position]
available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) self._available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack)
if available_materials == self._available_materials:
return False
self._available_materials = available_materials
if self._available_materials is None: if self._available_materials is None:
return False return False

View file

@ -1,10 +1,9 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 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 UM.Logger import Logger
from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
## Model that shows the list of favorite materials.
class FavoriteMaterialsModel(BaseMaterialsModel): class FavoriteMaterialsModel(BaseMaterialsModel):
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)

View file

@ -33,8 +33,6 @@ class NozzleModel(ListModel):
def _update(self): def _update(self):
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__)) Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
self.items.clear()
global_stack = self._machine_manager.activeMachine global_stack = self._machine_manager.activeMachine
if global_stack is None: if global_stack is None:
self.setItems([]) self.setItems([])

View file

@ -6,7 +6,7 @@ from UM.Logger import Logger
from UM.Scene.SceneNode import SceneNode #For typing. from UM.Scene.SceneNode import SceneNode #For typing.
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication
@ -28,8 +28,8 @@ class AuthState(IntEnum):
class NetworkedPrinterOutputDevice(PrinterOutputDevice): class NetworkedPrinterOutputDevice(PrinterOutputDevice):
authenticationStateChanged = pyqtSignal() authenticationStateChanged = pyqtSignal()
def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], parent: QObject = None) -> None: def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType = ConnectionType.NetworkConnection, parent: QObject = None) -> None:
super().__init__(device_id = device_id, parent = parent) super().__init__(device_id = device_id, connection_type = connection_type, parent = parent)
self._manager = None # type: Optional[QNetworkAccessManager] self._manager = None # type: Optional[QNetworkAccessManager]
self._last_manager_create_time = None # type: Optional[float] self._last_manager_create_time = None # type: Optional[float]
self._recreate_network_manager_time = 30 self._recreate_network_manager_time = 30
@ -125,7 +125,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if self._connection_state_before_timeout is None: if self._connection_state_before_timeout is None:
self._connection_state_before_timeout = self._connection_state self._connection_state_before_timeout = self._connection_state
self.setConnectionState(ConnectionState.closed) self.setConnectionState(ConnectionState.Closed)
# We need to check if the manager needs to be re-created. If we don't, we get some issues when OSX goes to # We need to check if the manager needs to be re-created. If we don't, we get some issues when OSX goes to
# sleep. # sleep.
@ -133,7 +133,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if self._last_manager_create_time is None or time() - self._last_manager_create_time > self._recreate_network_manager_time: if self._last_manager_create_time is None or time() - self._last_manager_create_time > self._recreate_network_manager_time:
self._createNetworkManager() self._createNetworkManager()
assert(self._manager is not None) assert(self._manager is not None)
elif self._connection_state == ConnectionState.closed: elif self._connection_state == ConnectionState.Closed:
# Go out of timeout. # Go out of timeout.
if self._connection_state_before_timeout is not None: # sanity check, but it should never be None here if self._connection_state_before_timeout is not None: # sanity check, but it should never be None here
self.setConnectionState(self._connection_state_before_timeout) self.setConnectionState(self._connection_state_before_timeout)
@ -285,8 +285,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
self._last_response_time = time() self._last_response_time = time()
if self._connection_state == ConnectionState.connecting: if self._connection_state == ConnectionState.Connecting:
self.setConnectionState(ConnectionState.connected) self.setConnectionState(ConnectionState.Connected)
callback_key = reply.url().toString() + str(reply.operation()) callback_key = reply.url().toString() + str(reply.operation())
try: try:

View file

@ -4,7 +4,7 @@
from UM.Decorators import deprecated from UM.Decorators import deprecated
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.OutputDevice.OutputDevice import OutputDevice from UM.OutputDevice.OutputDevice import OutputDevice
from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl, Q_ENUMS
from PyQt5.QtWidgets import QMessageBox from PyQt5.QtWidgets import QMessageBox
from UM.Logger import Logger from UM.Logger import Logger
@ -28,11 +28,18 @@ i18n_catalog = i18nCatalog("cura")
## The current processing state of the backend. ## The current processing state of the backend.
class ConnectionState(IntEnum): class ConnectionState(IntEnum):
closed = 0 Closed = 0
connecting = 1 Connecting = 1
connected = 2 Connected = 2
busy = 3 Busy = 3
error = 4 Error = 4
class ConnectionType(IntEnum):
Unknown = 0
UsbConnection = 1
NetworkConnection = 2
CloudConnection = 3
## Printer output device adds extra interface options on top of output device. ## Printer output device adds extra interface options on top of output device.
@ -46,6 +53,11 @@ class ConnectionState(IntEnum):
# For all other uses it should be used in the same way as a "regular" OutputDevice. # For all other uses it should be used in the same way as a "regular" OutputDevice.
@signalemitter @signalemitter
class PrinterOutputDevice(QObject, OutputDevice): class PrinterOutputDevice(QObject, OutputDevice):
# Put ConnectionType here with Q_ENUMS() so it can be registered as a QML type and accessible via QML, and there is
# no need to remember what those Enum integer values mean.
Q_ENUMS(ConnectionType)
printersChanged = pyqtSignal() printersChanged = pyqtSignal()
connectionStateChanged = pyqtSignal(str) connectionStateChanged = pyqtSignal(str)
acceptsCommandsChanged = pyqtSignal() acceptsCommandsChanged = pyqtSignal()
@ -62,7 +74,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
# Signal to indicate that the configuration of one of the printers has changed. # Signal to indicate that the configuration of one of the printers has changed.
uniqueConfigurationsChanged = pyqtSignal() uniqueConfigurationsChanged = pyqtSignal()
def __init__(self, device_id: str, parent: QObject = None) -> None: def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.Unknown, parent: QObject = None) -> None:
super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance
self._printers = [] # type: List[PrinterOutputModel] self._printers = [] # type: List[PrinterOutputModel]
@ -83,7 +95,8 @@ class PrinterOutputDevice(QObject, OutputDevice):
self._update_timer.setSingleShot(False) self._update_timer.setSingleShot(False)
self._update_timer.timeout.connect(self._update) self._update_timer.timeout.connect(self._update)
self._connection_state = ConnectionState.closed #type: ConnectionState self._connection_state = ConnectionState.Closed #type: ConnectionState
self._connection_type = connection_type
self._firmware_updater = None #type: Optional[FirmwareUpdater] self._firmware_updater = None #type: Optional[FirmwareUpdater]
self._firmware_name = None #type: Optional[str] self._firmware_name = None #type: Optional[str]
@ -110,15 +123,18 @@ class PrinterOutputDevice(QObject, OutputDevice):
callback(QMessageBox.Yes) callback(QMessageBox.Yes)
def isConnected(self) -> bool: def isConnected(self) -> bool:
return self._connection_state != ConnectionState.closed and self._connection_state != ConnectionState.error return self._connection_state != ConnectionState.Closed and self._connection_state != ConnectionState.Error
def setConnectionState(self, connection_state: ConnectionState) -> None: def setConnectionState(self, connection_state: "ConnectionState") -> None:
if self._connection_state != connection_state: if self._connection_state != connection_state:
self._connection_state = connection_state self._connection_state = connection_state
self.connectionStateChanged.emit(self._id) self.connectionStateChanged.emit(self._id)
def getConnectionType(self) -> "ConnectionType":
return self._connection_type
@pyqtProperty(str, notify = connectionStateChanged) @pyqtProperty(str, notify = connectionStateChanged)
def connectionState(self) -> ConnectionState: def connectionState(self) -> "ConnectionState":
return self._connection_state return self._connection_state
def _update(self) -> None: def _update(self) -> None:
@ -174,13 +190,13 @@ class PrinterOutputDevice(QObject, OutputDevice):
## Attempt to establish connection ## Attempt to establish connection
def connect(self) -> None: def connect(self) -> None:
self.setConnectionState(ConnectionState.connecting) self.setConnectionState(ConnectionState.Connecting)
self._update_timer.start() self._update_timer.start()
## Attempt to close the connection ## Attempt to close the connection
def close(self) -> None: def close(self) -> None:
self._update_timer.stop() self._update_timer.stop()
self.setConnectionState(ConnectionState.closed) self.setConnectionState(ConnectionState.Closed)
## Ensure that close gets called when object is destroyed ## Ensure that close gets called when object is destroyed
def __del__(self) -> None: def __del__(self) -> None:

69
cura/PrintersModel.py Normal file
View file

@ -0,0 +1,69 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM.Qt.ListModel import ListModel
from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.ContainerStack import ContainerStack
from cura.PrinterOutputDevice import ConnectionType
from cura.Settings.GlobalStack import GlobalStack
class PrintersModel(ListModel):
NameRole = Qt.UserRole + 1
IdRole = Qt.UserRole + 2
HasRemoteConnectionRole = Qt.UserRole + 3
ConnectionTypeRole = Qt.UserRole + 4
MetaDataRole = Qt.UserRole + 5
def __init__(self, parent = None):
super().__init__(parent)
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.IdRole, "id")
self.addRoleName(self.HasRemoteConnectionRole, "hasRemoteConnection")
self.addRoleName(self.ConnectionTypeRole, "connectionType")
self.addRoleName(self.MetaDataRole, "metadata")
self._container_stacks = []
# Listen to changes
ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged)
ContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerChanged)
ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged)
self._filter_dict = {}
self._update()
## Handler for container added/removed events from registry
def _onContainerChanged(self, container):
# We only need to update when the added / removed container GlobalStack
if isinstance(container, GlobalStack):
self._update()
## Handler for container name change events.
def _onContainerNameChanged(self):
self._update()
def _update(self) -> None:
items = []
for container in self._container_stacks:
container.nameChanged.disconnect(self._onContainerNameChanged)
container_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
for container_stack in container_stacks:
connection_type = container_stack.getMetaDataEntry("connection_type")
has_remote_connection = connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value]
if container_stack.getMetaDataEntry("hidden", False) in ["True", True]:
continue
# TODO: Remove reference to connect group name.
items.append({"name": container_stack.getMetaDataEntry("connect_group_name", container_stack.getName()),
"id": container_stack.getId(),
"hasRemoteConnection": has_remote_connection,
"connectionType": connection_type,
"metadata": container_stack.getMetaData().copy()})
items.sort(key=lambda i: not i["hasRemoteConnection"])
self.setItems(items)

View file

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 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.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty, QTimer from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
from typing import Iterable from typing import Iterable
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
@ -78,8 +78,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
self._update_extruder_timer.setSingleShot(True) self._update_extruder_timer.setSingleShot(True)
self._update_extruder_timer.timeout.connect(self.__updateExtruders) self._update_extruder_timer.timeout.connect(self.__updateExtruders)
self._simple_names = False
self._active_machine_extruders = [] # type: Iterable[ExtruderStack] self._active_machine_extruders = [] # type: Iterable[ExtruderStack]
self._add_optional_extruder = False self._add_optional_extruder = False
@ -101,21 +99,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
def addOptionalExtruder(self): def addOptionalExtruder(self):
return self._add_optional_extruder return self._add_optional_extruder
## Set the simpleNames property.
def setSimpleNames(self, simple_names):
if simple_names != self._simple_names:
self._simple_names = simple_names
self.simpleNamesChanged.emit()
self._updateExtruders()
## Emitted when the simpleNames property changes.
simpleNamesChanged = pyqtSignal()
## Whether or not the model should show all definitions regardless of visibility.
@pyqtProperty(bool, fset = setSimpleNames, notify = simpleNamesChanged)
def simpleNames(self):
return self._simple_names
## Links to the stack-changed signal of the new extruders when an extruder ## Links to the stack-changed signal of the new extruders when an extruder
# is swapped out or added in the current machine. # is swapped out or added in the current machine.
# #
@ -221,7 +204,12 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
"enabled": True, "enabled": True,
"color": "#ffffff", "color": "#ffffff",
"index": -1, "index": -1,
"definition": "" "definition": "",
"material": "",
"variant": "",
"stack": None,
"material_brand": "",
"color_name": "",
} }
items.append(item) items.append(item)
if self._items != items: if self._items != items:

View file

@ -23,7 +23,7 @@ from UM.Settings.SettingFunction import SettingFunction
from UM.Signal import postponeSignals, CompressTechnique from UM.Signal import postponeSignals, CompressTechnique
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionType
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
@ -88,12 +88,14 @@ class MachineManager(QObject):
self._onGlobalContainerChanged() self._onGlobalContainerChanged()
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) extruder_manager = self._application.getExtruderManager()
extruder_manager.activeExtruderChanged.connect(self._onActiveExtruderStackChanged)
self._onActiveExtruderStackChanged() self._onActiveExtruderStackChanged()
ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) extruder_manager.activeExtruderChanged.connect(self.activeMaterialChanged)
ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) extruder_manager.activeExtruderChanged.connect(self.activeVariantChanged)
ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) extruder_manager.activeExtruderChanged.connect(self.activeQualityChanged)
self.globalContainerChanged.connect(self.activeStackChanged) self.globalContainerChanged.connect(self.activeStackChanged)
self.globalValueChanged.connect(self.activeStackValueChanged) self.globalValueChanged.connect(self.activeStackValueChanged)
@ -521,7 +523,13 @@ class MachineManager(QObject):
def printerConnected(self): def printerConnected(self):
return bool(self._printer_output_devices) return bool(self._printer_output_devices)
@pyqtProperty(str, notify = printerConnectedStatusChanged) @pyqtProperty(bool, notify = printerConnectedStatusChanged)
def activeMachineHasRemoteConnection(self) -> bool:
if self._global_container_stack:
connection_type = self._global_container_stack.getMetaDataEntry("connection_type")
return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value]
return False
def activeMachineNetworkKey(self) -> str: def activeMachineNetworkKey(self) -> str:
if self._global_container_stack: if self._global_container_stack:
return self._global_container_stack.getMetaDataEntry("um_network_key", "") return self._global_container_stack.getMetaDataEntry("um_network_key", "")
@ -749,7 +757,7 @@ class MachineManager(QObject):
self.setActiveMachine(other_machine_stacks[0]["id"]) self.setActiveMachine(other_machine_stacks[0]["id"])
metadata = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)[0] metadata = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)[0]
network_key = metadata["um_network_key"] if "um_network_key" in metadata else None network_key = metadata.get("um_network_key", None)
ExtruderManager.getInstance().removeMachineExtruders(machine_id) ExtruderManager.getInstance().removeMachineExtruders(machine_id)
containers = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id) containers = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id)
for container in containers: for container in containers:
@ -1315,17 +1323,18 @@ class MachineManager(QObject):
# Get the definition id corresponding to this machine name # Get the definition id corresponding to this machine name
machine_definition_id = CuraContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId() machine_definition_id = CuraContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId()
# Try to find a machine with the same network key # Try to find a machine with the same network key
new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey}) new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey()})
# If there is no machine, then create a new one and set it to the non-hidden instance # If there is no machine, then create a new one and set it to the non-hidden instance
if not new_machine: if not new_machine:
new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id) new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id)
if not new_machine: if not new_machine:
return return
new_machine.setMetaDataEntry("um_network_key", self.activeMachineNetworkKey) new_machine.setMetaDataEntry("um_network_key", self.activeMachineNetworkKey())
new_machine.setMetaDataEntry("connect_group_name", self.activeMachineNetworkGroupName) new_machine.setMetaDataEntry("connect_group_name", self.activeMachineNetworkGroupName)
new_machine.setMetaDataEntry("hidden", False) new_machine.setMetaDataEntry("hidden", False)
new_machine.setMetaDataEntry("connection_type", self._global_container_stack.getMetaDataEntry("connection_type"))
else: else:
Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey) Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey())
new_machine.setMetaDataEntry("hidden", False) new_machine.setMetaDataEntry("hidden", False)
# Set the current printer instance to hidden (the metadata entry must exist) # Set the current printer instance to hidden (the metadata entry must exist)
@ -1385,10 +1394,10 @@ class MachineManager(QObject):
# After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group # After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group
# then all the container stacks are updated, both the current and the hidden ones. # then all the container stacks are updated, both the current and the hidden ones.
def checkCorrectGroupName(self, device_id: str, group_name: str) -> None: def checkCorrectGroupName(self, device_id: str, group_name: str) -> None:
if self._global_container_stack and device_id == self.activeMachineNetworkKey: if self._global_container_stack and device_id == self.activeMachineNetworkKey():
# Check if the connect_group_name is correct. If not, update all the containers connected to the same printer # Check if the connect_group_name is correct. If not, update all the containers connected to the same printer
if self.activeMachineNetworkGroupName != group_name: if self.activeMachineNetworkGroupName != group_name:
metadata_filter = {"um_network_key": self.activeMachineNetworkKey} metadata_filter = {"um_network_key": self.activeMachineNetworkKey()}
containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter) containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
for container in containers: for container in containers:
container.setMetaDataEntry("connect_group_name", group_name) container.setMetaDataEntry("connect_group_name", group_name)
@ -1527,6 +1536,10 @@ class MachineManager(QObject):
def activeQualityChangesGroup(self) -> Optional["QualityChangesGroup"]: def activeQualityChangesGroup(self) -> Optional["QualityChangesGroup"]:
return self._current_quality_changes_group return self._current_quality_changes_group
@pyqtProperty(bool, notify = activeQualityChangesGroupChanged)
def hasCustomQuality(self) -> bool:
return self._current_quality_changes_group is not None
@pyqtProperty(str, notify = activeQualityGroupChanged) @pyqtProperty(str, notify = activeQualityGroupChanged)
def activeQualityOrQualityChangesName(self) -> str: def activeQualityOrQualityChangesName(self) -> str:
name = empty_quality_container.getName() name = empty_quality_container.getName()

View file

@ -1,7 +1,8 @@
# 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 typing import Set
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot
from UM.Application import Application from UM.Application import Application
@ -16,15 +17,11 @@ class SimpleModeSettingsManager(QObject):
self._is_profile_user_created = False # True when profile was custom created by user self._is_profile_user_created = False # True when profile was custom created by user
self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized) self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized)
self._machine_manager.activeQualityGroupChanged.connect(self._updateIsProfileUserCreated)
self._machine_manager.activeQualityChangesGroupChanged.connect(self._updateIsProfileUserCreated)
# update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts # update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts
self._updateIsProfileCustomized() self._updateIsProfileCustomized()
self._updateIsProfileUserCreated()
isProfileCustomizedChanged = pyqtSignal() isProfileCustomizedChanged = pyqtSignal()
isProfileUserCreatedChanged = pyqtSignal()
@pyqtProperty(bool, notify = isProfileCustomizedChanged) @pyqtProperty(bool, notify = isProfileCustomizedChanged)
def isProfileCustomized(self): def isProfileCustomized(self):
@ -57,33 +54,6 @@ class SimpleModeSettingsManager(QObject):
self._is_profile_customized = has_customized_user_settings self._is_profile_customized = has_customized_user_settings
self.isProfileCustomizedChanged.emit() self.isProfileCustomizedChanged.emit()
@pyqtProperty(bool, notify = isProfileUserCreatedChanged)
def isProfileUserCreated(self):
return self._is_profile_user_created
def _updateIsProfileUserCreated(self):
quality_changes_keys = set()
if not self._machine_manager.activeMachine:
return False
global_stack = self._machine_manager.activeMachine
# check quality changes settings in the global stack
quality_changes_keys.update(global_stack.qualityChanges.getAllKeys())
# check quality changes settings in the extruder stacks
if global_stack.extruders:
for extruder_stack in global_stack.extruders.values():
quality_changes_keys.update(extruder_stack.qualityChanges.getAllKeys())
# check if the qualityChanges container is not empty (meaning it is a user created profile)
has_quality_changes = len(quality_changes_keys) > 0
if has_quality_changes != self._is_profile_user_created:
self._is_profile_user_created = has_quality_changes
self.isProfileUserCreatedChanged.emit()
# These are the settings included in the Simple ("Recommended") Mode, so only when the other settings have been # These are the settings included in the Simple ("Recommended") Mode, so only when the other settings have been
# changed, we consider it as a user customized profile in the Simple ("Recommended") Mode. # changed, we consider it as a user customized profile in the Simple ("Recommended") Mode.
__ignored_custom_setting_keys = ["support_enable", __ignored_custom_setting_keys = ["support_enable",

View file

@ -24,10 +24,6 @@ class CuraStage(Stage):
def mainComponent(self) -> QUrl: def mainComponent(self) -> QUrl:
return self.getDisplayComponent("main") return self.getDisplayComponent("main")
@pyqtProperty(QUrl, constant = True)
def sidebarComponent(self) -> QUrl:
return self.getDisplayComponent("sidebar")
@pyqtProperty(QUrl, constant = True) @pyqtProperty(QUrl, constant = True)
def stageMenuComponent(self) -> QUrl: def stageMenuComponent(self) -> QUrl:
return self.getDisplayComponent("menu") return self.getDisplayComponent("menu")

View file

@ -794,7 +794,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# Clear all existing containers # Clear all existing containers
quality_changes_info.global_info.container.clear() quality_changes_info.global_info.container.clear()
for container_info in quality_changes_info.extruder_info_dict.values(): for container_info in quality_changes_info.extruder_info_dict.values():
container_info.container.clear() if container_info.container:
container_info.container.clear()
# Loop over everything and override the existing containers # Loop over everything and override the existing containers
global_info = quality_changes_info.global_info global_info = quality_changes_info.global_info

View file

@ -1,8 +1,8 @@
{ {
"name": "3MF Reader", "name": "3MF Reader",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides support for reading 3MF files.", "description": "Provides support for reading 3MF files.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "3MF Writer", "name": "3MF Writer",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides support for writing 3MF files.", "description": "Provides support for writing 3MF files.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

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

View file

@ -2,7 +2,7 @@
"name": "CuraEngine Backend", "name": "CuraEngine Backend",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"description": "Provides the link to the CuraEngine slicing backend.", "description": "Provides the link to the CuraEngine slicing backend.",
"api": 5, "api": "6.0",
"version": "1.0.0", "version": "1.0.1",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Cura Profile Reader", "name": "Cura Profile Reader",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides support for importing Cura profiles.", "description": "Provides support for importing Cura profiles.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Cura Profile Writer", "name": "Cura Profile Writer",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides support for exporting Cura profiles.", "description": "Provides support for exporting Cura profiles.",
"api": 5, "api": "6.0",
"i18n-catalog":"cura" "i18n-catalog":"cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Firmware Update Checker", "name": "Firmware Update Checker",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Checks for firmware updates.", "description": "Checks for firmware updates.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Firmware Updater", "name": "Firmware Updater",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides a machine actions for updating firmware.", "description": "Provides a machine actions for updating firmware.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Compressed G-code Reader", "name": "Compressed G-code Reader",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Reads g-code from a compressed archive.", "description": "Reads g-code from a compressed archive.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Compressed G-code Writer", "name": "Compressed G-code Writer",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Writes g-code to a compressed archive.", "description": "Writes g-code to a compressed archive.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "G-code Profile Reader", "name": "G-code Profile Reader",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides support for importing profiles from g-code files.", "description": "Provides support for importing profiles from g-code files.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -364,6 +364,8 @@ class FlavorParser:
self._layer_type = LayerPolygon.SupportType self._layer_type = LayerPolygon.SupportType
elif type == "FILL": elif type == "FILL":
self._layer_type = LayerPolygon.InfillType self._layer_type = LayerPolygon.InfillType
elif type == "SUPPORT-INTERFACE":
self._layer_type = LayerPolygon.SupportInterfaceType
else: else:
Logger.log("w", "Encountered a unknown type (%s) while parsing g-code.", type) Logger.log("w", "Encountered a unknown type (%s) while parsing g-code.", type)

View file

@ -1,8 +1,8 @@
{ {
"name": "G-code Reader", "name": "G-code Reader",
"author": "Victor Larchenko", "author": "Victor Larchenko, Ultimaker",
"version": "1.0.0", "version": "1.0.1",
"description": "Allows loading and displaying G-code files.", "description": "Allows loading and displaying G-code files.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "G-code Writer", "name": "G-code Writer",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Writes g-code to a file.", "description": "Writes g-code to a file.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Image Reader", "name": "Image Reader",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Enables ability to generate printable geometry from 2D image files.", "description": "Enables ability to generate printable geometry from 2D image files.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Legacy Cura Profile Reader", "name": "Legacy Cura Profile Reader",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides support for importing profiles from legacy Cura versions.", "description": "Provides support for importing profiles from legacy Cura versions.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -13,7 +13,7 @@ import Cura 1.0 as Cura
Cura.MachineAction Cura.MachineAction
{ {
id: base id: base
property var extrudersModel: Cura.ExtrudersModel{} property var extrudersModel: CuraApplication.getExtrudersModel()
property int extruderTabsCount: 0 property int extruderTabsCount: 0
property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : "" property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : ""

View file

@ -1,8 +1,8 @@
{ {
"name": "Machine Settings action", "name": "Machine Settings action",
"author": "fieldOfView", "author": "fieldOfView",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).", "description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Model Checker", "name": "Model Checker",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "0.1", "version": "1.0.1",
"api": 5, "api": "6.0",
"description": "Checks models and print configuration for possible printing issues and give suggestions.", "description": "Checks models and print configuration for possible printing issues and give suggestions.",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -35,6 +35,6 @@ Item
property real maximumWidth: parent.width property real maximumWidth: parent.width
property real maximumHeight: parent.height property real maximumHeight: parent.height
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem : null
} }
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Monitor Stage", "name": "Monitor Stage",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides a monitor stage in Cura.", "description": "Provides a monitor stage in Cura.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Per Model Settings Tool", "name": "Per Model Settings Tool",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides the Per Model Settings.", "description": "Provides the Per Model Settings.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Post Processing", "name": "Post Processing",
"author": "Ultimaker", "author": "Ultimaker",
"version": "2.2", "version": "2.2.1",
"api": 5, "api": "6.0",
"description": "Extension that allows for user created scripts for post processing", "description": "Extension that allows for user created scripts for post processing",
"catalog": "cura" "catalog": "cura"
} }

View file

@ -100,7 +100,7 @@ Item
source: UM.Theme.getIcon("load") source: UM.Theme.getIcon("load")
width: UM.Theme.getSize("button_icon").width width: UM.Theme.getSize("button_icon").width
height: UM.Theme.getSize("button_icon").height height: UM.Theme.getSize("button_icon").height
color: UM.Theme.getColor("toolbar_button_text") color: UM.Theme.getColor("icon")
sourceSize.height: height sourceSize.height: height
} }

View file

@ -1,4 +1,4 @@
# Copyright (c) 2017 Ultimaker B.V. # Copyright (c) 2018 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.
import os.path import os.path
from UM.Application import Application from UM.Application import Application
@ -15,9 +15,5 @@ class PrepareStage(CuraStage):
Application.getInstance().engineCreatedSignal.connect(self._engineCreated) Application.getInstance().engineCreatedSignal.connect(self._engineCreated)
def _engineCreated(self): def _engineCreated(self):
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles),
"PrepareSidebar.qml")
menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("PrepareStage"), "PrepareMenu.qml") menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("PrepareStage"), "PrepareMenu.qml")
self.addDisplayComponent("menu", menu_component_path) self.addDisplayComponent("menu", menu_component_path)
self.addDisplayComponent("sidebar", sidebar_component_path)

View file

@ -1,8 +1,8 @@
{ {
"name": "Prepare Stage", "name": "Prepare Stage",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides a prepare stage in Cura.", "description": "Provides a prepare stage in Cura.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -2,6 +2,7 @@
// Cura is released under the terms of the LGPLv3 or higher. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import UM 1.3 as UM import UM 1.3 as UM
@ -19,12 +20,15 @@ Item
name: "cura" name: "cura"
} }
Row Row
{ {
id: stageMenuRow id: stageMenuRow
anchors.centerIn: parent anchors.centerIn: parent
height: parent.height height: parent.height
width: childrenRect.width
// We want this row to have a preferred with equals to the 85% of the parent
property int preferredWidth: Math.round(0.85 * previewMenu.width)
Cura.ViewsSelector Cura.ViewsSelector
{ {
@ -45,11 +49,12 @@ Item
color: UM.Theme.getColor("lining") color: UM.Theme.getColor("lining")
} }
// This component will grow freely up to complete the preferredWidth of the row.
Loader Loader
{ {
id: viewPanel id: viewPanel
height: parent.height height: parent.height
width: childrenRect.width width: source != "" ? (stageMenuRow.preferredWidth - viewsSelector.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width) : 0
source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : ""
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Preview Stage", "name": "Preview Stage",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides a preview stage in Cura.", "description": "Provides a preview stage in Cura.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -2,7 +2,7 @@
"name": "Removable Drive Output Device Plugin", "name": "Removable Drive Output Device Plugin",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"description": "Provides removable drive hotplugging and writing support.", "description": "Provides removable drive hotplugging and writing support.",
"version": "1.0.0", "version": "1.0.1",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -15,7 +15,6 @@ Cura.ExpandableComponent
{ {
id: base id: base
width: UM.Theme.getSize("layerview_menu_size").width
contentHeaderTitle: catalog.i18nc("@label", "Color scheme") contentHeaderTitle: catalog.i18nc("@label", "Color scheme")
Connections Connections
@ -35,14 +34,36 @@ Cura.ExpandableComponent
} }
} }
headerItem: Label headerItem: Item
{ {
id: layerViewTypesLabel Label
text: catalog.i18nc("@label", "Color scheme") {
font: UM.Theme.getFont("default") id: colorSchemeLabel
color: UM.Theme.getColor("setting_control_text") text: catalog.i18nc("@label", "Color scheme")
height: base.height verticalAlignment: Text.AlignVCenter
verticalAlignment: Text.AlignVCenter height: parent.height
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
renderType: Text.NativeRendering
}
Label
{
text: layerTypeCombobox.currentText
verticalAlignment: Text.AlignVCenter
anchors
{
left: colorSchemeLabel.right
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
}
height: parent.height
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
} }
contentItem: Column contentItem: Column
@ -125,7 +146,7 @@ Cura.ExpandableComponent
Label Label
{ {
id: compatibilityModeLabel id: compatibilityModeLabel
text: catalog.i18nc("@label","Compatibility Mode") text: catalog.i18nc("@label", "Compatibility Mode")
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
visible: UM.SimulationView.compatibilityMode visible: UM.SimulationView.compatibilityMode
@ -136,13 +157,13 @@ Cura.ExpandableComponent
Item // Spacer Item // Spacer
{ {
height: Math.round(UM.Theme.getSize("default_margin").width / 2) height: UM.Theme.getSize("narrow_margin").width
width: width width: width
} }
Repeater Repeater
{ {
model: Cura.ExtrudersModel{} model: CuraApplication.getExtrudersModel()
CheckBox CheckBox
{ {
@ -161,17 +182,16 @@ Cura.ExpandableComponent
style: UM.Theme.styles.checkbox style: UM.Theme.styles.checkbox
Rectangle
UM.RecolorImage
{ {
id: swatch
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: extrudersModelCheckBox.right anchors.right: extrudersModelCheckBox.right
width: UM.Theme.getSize("layerview_legend_size").width width: UM.Theme.getSize("layerview_legend_size").width
height: UM.Theme.getSize("layerview_legend_size").height height: UM.Theme.getSize("layerview_legend_size").height
source: UM.Theme.getIcon("extruder_button")
color: model.color color: model.color
radius: Math.round(width / 2)
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
visible: !viewSettings.show_legend && !viewSettings.show_gradient
} }
Label Label
@ -201,25 +221,25 @@ Cura.ExpandableComponent
Component.onCompleted: Component.onCompleted:
{ {
typesLegendModel.append({ typesLegendModel.append({
label: catalog.i18nc("@label", "Show Travels"), label: catalog.i18nc("@label", "Travels"),
initialValue: viewSettings.show_travel_moves, initialValue: viewSettings.show_travel_moves,
preference: "layerview/show_travel_moves", preference: "layerview/show_travel_moves",
colorId: "layerview_move_combing" colorId: "layerview_move_combing"
}); });
typesLegendModel.append({ typesLegendModel.append({
label: catalog.i18nc("@label", "Show Helpers"), label: catalog.i18nc("@label", "Helpers"),
initialValue: viewSettings.show_helpers, initialValue: viewSettings.show_helpers,
preference: "layerview/show_helpers", preference: "layerview/show_helpers",
colorId: "layerview_support" colorId: "layerview_support"
}); });
typesLegendModel.append({ typesLegendModel.append({
label: catalog.i18nc("@label", "Show Shell"), label: catalog.i18nc("@label", "Shell"),
initialValue: viewSettings.show_skin, initialValue: viewSettings.show_skin,
preference: "layerview/show_skin", preference: "layerview/show_skin",
colorId: "layerview_inset_0" colorId: "layerview_inset_0"
}); });
typesLegendModel.append({ typesLegendModel.append({
label: catalog.i18nc("@label", "Show Infill"), label: catalog.i18nc("@label", "Infill"),
initialValue: viewSettings.show_infill, initialValue: viewSettings.show_infill,
preference: "layerview/show_infill", preference: "layerview/show_infill",
colorId: "layerview_infill" colorId: "layerview_infill"

View file

@ -1,8 +1,8 @@
{ {
"name": "Simulation View", "name": "Simulation View",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides the Simulation view.", "description": "Provides the Simulation view.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Slice info", "name": "Slice info",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Submits anonymous slice info. Can be disabled through preferences.", "description": "Submits anonymous slice info. Can be disabled through preferences.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -12,7 +12,6 @@ from UM.Math.Color import Color
from UM.View.GL.OpenGL import OpenGL from UM.View.GL.OpenGL import OpenGL
from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ExtrudersModel import ExtrudersModel
import math import math
@ -29,13 +28,16 @@ class SolidView(View):
self._non_printing_shader = None self._non_printing_shader = None
self._support_mesh_shader = None self._support_mesh_shader = None
self._extruders_model = ExtrudersModel() self._extruders_model = None
self._theme = None self._theme = None
def beginRendering(self): def beginRendering(self):
scene = self.getController().getScene() scene = self.getController().getScene()
renderer = self.getRenderer() renderer = self.getRenderer()
if not self._extruders_model:
self._extruders_model = Application.getInstance().getExtrudersModel()
if not self._theme: if not self._theme:
self._theme = Application.getInstance().getTheme() self._theme = Application.getInstance().getTheme()

View file

@ -1,8 +1,8 @@
{ {
"name": "Solid View", "name": "Solid View",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides a normal solid mesh view.", "description": "Provides a normal solid mesh view.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Support Eraser", "name": "Support Eraser",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Creates an eraser mesh to block the printing of support in certain places", "description": "Creates an eraser mesh to block the printing of support in certain places",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,7 +1,7 @@
{ {
"name": "Toolbox", "name": "Toolbox",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"api": 5, "api": "6.0",
"description": "Find, manage and install new Cura packages." "description": "Find, manage and install new Cura packages."
} }

View file

@ -0,0 +1,106 @@
import QtQuick 2.7
import QtQuick.Controls 2.1
import UM 1.0 as UM
import Cura 1.1 as Cura
Item
{
id: ratingWidget
property real rating: 0
property int indexHovered: -1
property string packageId: ""
property int userRating: 0
property bool canRate: false
signal rated(int rating)
width: contentRow.width
height: contentRow.height
MouseArea
{
id: mouseArea
anchors.fill: parent
hoverEnabled: ratingWidget.canRate
acceptedButtons: Qt.NoButton
onExited:
{
if(ratingWidget.canRate)
{
ratingWidget.indexHovered = -1
}
}
Row
{
id: contentRow
height: childrenRect.height
Repeater
{
model: 5 // We need to get 5 stars
Button
{
id: control
hoverEnabled: true
onHoveredChanged:
{
if(hovered && ratingWidget.canRate)
{
indexHovered = index
}
}
ToolTip.visible: control.hovered && !ratingWidget.canRate
ToolTip.text: !Cura.API.account.isLoggedIn ? catalog.i18nc("@label", "You need to login first before you can rate"): catalog.i18nc("@label", "You need to install the package before you can rate")
property bool isStarFilled:
{
// If the entire widget is hovered, override the actual rating.
if(ratingWidget.indexHovered >= 0)
{
return indexHovered >= index
}
if(ratingWidget.userRating > 0)
{
return userRating >= index +1
}
return rating >= index + 1
}
contentItem: Item {}
height: UM.Theme.getSize("rating_star").height
width: UM.Theme.getSize("rating_star").width
background: UM.RecolorImage
{
source: UM.Theme.getIcon(control.isStarFilled ? "star_filled" : "star_empty")
sourceSize.width: width
sourceSize.height: height
// Unfilled stars should always have the default color. Only filled stars should change on hover
color:
{
if(!ratingWidget.canRate)
{
return UM.Theme.getColor("rating_star")
}
if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled)
{
return UM.Theme.getColor("primary")
}
return UM.Theme.getColor("rating_star")
}
}
onClicked:
{
if(ratingWidget.canRate)
{
rated(index + 1) // Notify anyone who cares about this.
}
}
}
}
}
}
}

View file

@ -0,0 +1,36 @@
import QtQuick 2.3
import QtQuick.Controls 1.4
import UM 1.1 as UM
import Cura 1.1 as Cura
Row
{
id: rating
height: UM.Theme.getSize("rating_star").height
visible: model.average_rating > 0 //Has a rating at all.
spacing: UM.Theme.getSize("thick_lining").width
width: starIcon.width + spacing + numRatingsLabel.width
UM.RecolorImage
{
id: starIcon
source: UM.Theme.getIcon("star_filled")
color: model.user_rating == 0 ? UM.Theme.getColor("rating_star") : UM.Theme.getColor("primary")
height: UM.Theme.getSize("rating_star").height
width: UM.Theme.getSize("rating_star").width
sourceSize.height: height
sourceSize.width: width
}
Label
{
id: numRatingsLabel
text: model.average_rating != undefined ? model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")": ""
verticalAlignment: Text.AlignVCenter
height: starIcon.height
width: contentWidth
anchors.verticalCenter: starIcon.verticalCenter
color: starIcon.color
font: UM.Theme.getFont("small")
renderType: Text.NativeRendering
}
}

View file

@ -6,6 +6,8 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import UM 1.1 as UM import UM 1.1 as UM
import Cura 1.1 as Cura
Item Item
{ {
id: page id: page
@ -24,7 +26,7 @@ Item
right: parent.right right: parent.right
rightMargin: UM.Theme.getSize("wide_margin").width rightMargin: UM.Theme.getSize("wide_margin").width
} }
height: UM.Theme.getSize("toolbox_detail_header").height height: childrenRect.height + 3 * UM.Theme.getSize("default_margin").width
Rectangle Rectangle
{ {
id: thumbnail id: thumbnail
@ -37,7 +39,7 @@ Item
leftMargin: UM.Theme.getSize("wide_margin").width leftMargin: UM.Theme.getSize("wide_margin").width
topMargin: UM.Theme.getSize("wide_margin").height topMargin: UM.Theme.getSize("wide_margin").height
} }
color: "white" //Always a white background for image (regardless of theme). color: UM.Theme.getColor("main_background")
Image Image
{ {
anchors.fill: parent anchors.fill: parent
@ -55,19 +57,23 @@ Item
top: thumbnail.top top: thumbnail.top
left: thumbnail.right left: thumbnail.right
leftMargin: UM.Theme.getSize("default_margin").width leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("wide_margin").width
bottomMargin: UM.Theme.getSize("default_margin").height
} }
text: details === null ? "" : (details.name || "") text: details === null ? "" : (details.name || "")
font: UM.Theme.getFont("large_bold") font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
wrapMode: Text.WordWrap width: contentWidth
width: parent.width height: contentHeight
height: UM.Theme.getSize("toolbox_property_label").height
renderType: Text.NativeRendering renderType: Text.NativeRendering
} }
SmallRatingWidget
{
anchors.left: title.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: title.verticalCenter
property var model: details
}
Column Column
{ {
id: properties id: properties
@ -81,6 +87,13 @@ Item
width: childrenRect.width width: childrenRect.width
height: childrenRect.height height: childrenRect.height
Label Label
{
text: catalog.i18nc("@label", "Your rating") + ":"
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
renderType: Text.NativeRendering
}
Label
{ {
text: catalog.i18nc("@label", "Version") + ":" text: catalog.i18nc("@label", "Version") + ":"
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
@ -121,6 +134,48 @@ Item
} }
spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) spacing: Math.floor(UM.Theme.getSize("narrow_margin").height)
height: childrenRect.height height: childrenRect.height
RatingWidget
{
id: rating
visible: details.type == "plugin"
packageId: details.id != undefined ? details.id: ""
userRating: details.user_rating != undefined ? details.user_rating: 0
canRate: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn
onRated:
{
toolbox.ratePackage(details.id, rating)
// HACK: This is a far from optimal solution, but without major refactoring, this is the best we can
// do. Since a rework of this is scheduled, it shouldn't live that long...
var index = toolbox.pluginsAvailableModel.find("id", details.id)
if(index != -1)
{
if(details.user_rating == 0) // User never rated before.
{
toolbox.pluginsAvailableModel.setProperty(index, "num_ratings", details.num_ratings + 1)
}
toolbox.pluginsAvailableModel.setProperty(index, "user_rating", rating)
// Hack; This is because the current selection is an outdated copy, so we need to re-copy it.
base.selection = toolbox.pluginsAvailableModel.getItem(index)
return
}
index = toolbox.pluginsShowcaseModel.find("id", details.id)
if(index != -1)
{
if(details.user_rating == 0) // User never rated before.
{
toolbox.pluginsShowcaseModel.setProperty(index, "user_rating", rating)
}
toolbox.pluginsShowcaseModel.setProperty(index, "num_ratings", details.num_ratings + 1)
// Hack; This is because the current selection is an outdated copy, so we need to re-copy it.
base.selection = toolbox.pluginsShowcaseModel.getItem(index)
}
}
}
Label Label
{ {
text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown"))
@ -170,13 +225,6 @@ Item
renderType: Text.NativeRendering renderType: Text.NativeRendering
} }
} }
Rectangle
{
color: UM.Theme.getColor("lining")
width: parent.width
height: UM.Theme.getSize("default_lining").height
anchors.bottom: parent.bottom
}
} }
ToolboxDetailList ToolboxDetailList
{ {

View file

@ -6,6 +6,7 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import UM 1.1 as UM import UM 1.1 as UM
import Cura 1.1 as Cura
Item Item
{ {
@ -14,94 +15,13 @@ Item
property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
height: childrenRect.height height: childrenRect.height
Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Rectangle
{
id: highlight
anchors.fill: parent
opacity: 0.0
color: UM.Theme.getColor("primary")
}
Row
{
width: parent.width
height: childrenRect.height
spacing: Math.floor(UM.Theme.getSize("narrow_margin").width)
Rectangle
{
id: thumbnail
width: UM.Theme.getSize("toolbox_thumbnail_small").width
height: UM.Theme.getSize("toolbox_thumbnail_small").height
color: "white"
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
Image
{
anchors.centerIn: parent
width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width
height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width
fillMode: Image.PreserveAspectFit
source: model.icon_url || "../images/logobot.svg"
mipmap: true
}
UM.RecolorImage
{
width: (parent.width * 0.4) | 0
height: (parent.height * 0.4) | 0
anchors
{
bottom: parent.bottom
right: parent.right
}
sourceSize.height: height
visible: installedPackages != 0
color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
source: "../images/installed_check.svg"
}
}
Column
{
width: parent.width - thumbnail.width - parent.spacing
spacing: Math.floor(UM.Theme.getSize("narrow_margin").width)
anchors.top: parent.top
anchors.topMargin: UM.Theme.getSize("default_margin").height
Label
{
id: name
text: model.name
width: parent.width
wrapMode: Text.WordWrap
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("default_bold")
renderType: Text.NativeRendering
}
Label
{
id: info
text: model.description
maximumLineCount: 2
elide: Text.ElideRight
width: parent.width
wrapMode: Text.WordWrap
color: UM.Theme.getColor("text_medium")
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
}
}
}
MouseArea MouseArea
{ {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onEntered: onEntered: thumbnail.border.color = UM.Theme.getColor("primary")
{ onExited: thumbnail.border.color = UM.Theme.getColor("lining")
thumbnail.border.color = UM.Theme.getColor("primary")
highlight.opacity = 0.1
}
onExited:
{
thumbnail.border.color = UM.Theme.getColor("lining")
highlight.opacity = 0.0
}
onClicked: onClicked:
{ {
base.selection = model base.selection = model
@ -131,4 +51,83 @@ Item
} }
} }
} }
Rectangle
{
id: thumbnail
width: UM.Theme.getSize("toolbox_thumbnail_small").width
height: UM.Theme.getSize("toolbox_thumbnail_small").height
color: UM.Theme.getColor("main_background")
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
Image
{
anchors.centerIn: parent
width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width
height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width
fillMode: Image.PreserveAspectFit
source: model.icon_url || "../images/logobot.svg"
mipmap: true
}
UM.RecolorImage
{
width: (parent.width * 0.4) | 0
height: (parent.height * 0.4) | 0
anchors
{
bottom: parent.bottom
right: parent.right
}
sourceSize.height: height
visible: installedPackages != 0
color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
source: "../images/installed_check.svg"
}
}
Item
{
anchors
{
left: thumbnail.right
leftMargin: Math.floor(UM.Theme.getSize("narrow_margin").width)
right: parent.right
top: parent.top
bottom: parent.bottom
}
Label
{
id: name
text: model.name
width: parent.width
elide: Text.ElideRight
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("default_bold")
}
Label
{
id: info
text: model.description
elide: Text.ElideRight
width: parent.width
wrapMode: Text.WordWrap
color: UM.Theme.getColor("text_medium")
font: UM.Theme.getFont("default")
anchors.top: name.bottom
anchors.bottom: rating.top
verticalAlignment: Text.AlignVCenter
maximumLineCount: 2
}
SmallRatingWidget
{
id: rating
anchors
{
bottom: parent.bottom
left: parent.left
right: parent.right
}
}
}
} }

View file

@ -13,91 +13,79 @@ Rectangle
property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
id: tileBase id: tileBase
width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width) width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width)
height: thumbnail.height + packageNameBackground.height + (2 * UM.Theme.getSize("default_lining").width) height: thumbnail.height + packageName.height + rating.height + UM.Theme.getSize("default_margin").width
border.width: UM.Theme.getSize("default_lining").width border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining") border.color: UM.Theme.getColor("lining")
color: "transparent" color: UM.Theme.getColor("main_background")
Rectangle Image
{ {
id: thumbnail id: thumbnail
color: "white" height: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("toolbox_thumbnail_large").width width: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
height: UM.Theme.getSize("toolbox_thumbnail_large").height fillMode: Image.PreserveAspectFit
source: model.icon_url || "../images/logobot.svg"
mipmap: true
anchors anchors
{ {
top: parent.top top: parent.top
topMargin: UM.Theme.getSize("default_margin").height
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter
topMargin: UM.Theme.getSize("default_lining").width
} }
Image }
Label
{
id: packageName
text: model.name
anchors
{ {
anchors.centerIn: parent horizontalCenter: parent.horizontalCenter
width: UM.Theme.getSize("toolbox_thumbnail_large").width - 2 * UM.Theme.getSize("default_margin").width top: thumbnail.bottom
height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height
fillMode: Image.PreserveAspectFit
source: model.icon_url || "../images/logobot.svg"
mipmap: true
} }
UM.RecolorImage verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
height: UM.Theme.getSize("toolbox_heading_label").height
width: parent.width - UM.Theme.getSize("default_margin").width
wrapMode: Text.WordWrap
elide: Text.ElideRight
font: UM.Theme.getFont("medium_bold")
}
UM.RecolorImage
{
width: (parent.width * 0.20) | 0
height: width
anchors
{ {
width: (parent.width * 0.3) | 0 bottom: bottomBorder.top
height: (parent.height * 0.3) | 0 right: parent.right
anchors
{
bottom: parent.bottom
right: parent.right
bottomMargin: UM.Theme.getSize("default_lining").width
}
visible: installedPackages != 0
color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
source: "../images/installed_check.svg"
} }
visible: installedPackages != 0
color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
source: "../images/installed_check.svg"
}
SmallRatingWidget
{
id: rating
anchors.bottom: parent.bottom
anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height
anchors.horizontalCenter: parent.horizontalCenter
} }
Rectangle Rectangle
{ {
id: packageNameBackground id: bottomBorder
color: UM.Theme.getColor("primary") color: UM.Theme.getColor("primary")
anchors anchors.bottom: parent.bottom
{
top: thumbnail.bottom
horizontalCenter: parent.horizontalCenter
}
height: UM.Theme.getSize("toolbox_heading_label").height
width: parent.width width: parent.width
Label height: UM.Theme.getSize("toolbox_header_highlight").height
{
id: packageName
text: model.name
anchors
{
horizontalCenter: parent.horizontalCenter
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
height: UM.Theme.getSize("toolbox_heading_label").height
width: parent.width
wrapMode: Text.WordWrap
color: UM.Theme.getColor("button_text")
font: UM.Theme.getFont("medium_bold")
renderType: Text.NativeRendering
}
} }
MouseArea MouseArea
{ {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onEntered: onEntered: tileBase.border.color = UM.Theme.getColor("primary")
{ onExited: tileBase.border.color = UM.Theme.getColor("lining")
packageName.color = UM.Theme.getColor("button_text_hover")
packageNameBackground.color = UM.Theme.getColor("primary_hover")
tileBase.border.color = UM.Theme.getColor("primary_hover")
}
onExited:
{
packageName.color = UM.Theme.getColor("button_text")
packageNameBackground.color = UM.Theme.getColor("primary")
tileBase.border.color = UM.Theme.getColor("lining")
}
onClicked: onClicked:
{ {
base.selection = model base.selection = model

View file

@ -2,21 +2,23 @@
// Toolbox is released under the terms of the LGPLv3 or higher. // Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 1.4 import QtQuick.Controls 2.3
import QtQuick.Controls.Styles 1.4
import UM 1.1 as UM import UM 1.1 as UM
import Cura 1.0 as Cura
Item Item
{ {
id: footer id: footer
width: parent.width width: parent.width
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
height: visible ? Math.floor(UM.Theme.getSize("toolbox_footer").height) : 0 height: visible ? UM.Theme.getSize("toolbox_footer").height : 0
Label Label
{ {
text: catalog.i18nc("@info", "You will need to restart Cura before changes in packages have effect.") text: catalog.i18nc("@info", "You will need to restart Cura before changes in packages have effect.")
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
height: Math.floor(UM.Theme.getSize("toolbox_footer_button").height) height: UM.Theme.getSize("toolbox_footer_button").height
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
anchors anchors
{ {
@ -28,10 +30,10 @@ Item
} }
renderType: Text.NativeRendering renderType: Text.NativeRendering
} }
Button
Cura.PrimaryButton
{ {
id: restartButton id: restartButton
text: catalog.i18nc("@info:button", "Quit Cura")
anchors anchors
{ {
top: parent.top top: parent.top
@ -39,27 +41,11 @@ Item
right: parent.right right: parent.right
rightMargin: UM.Theme.getSize("wide_margin").width rightMargin: UM.Theme.getSize("wide_margin").width
} }
iconName: "dialog-restart" height: UM.Theme.getSize("toolbox_footer_button").height
text: catalog.i18nc("@info:button", "Quit Cura")
onClicked: toolbox.restart() onClicked: toolbox.restart()
style: ButtonStyle
{
background: Rectangle
{
implicitWidth: UM.Theme.getSize("toolbox_footer_button").width
implicitHeight: Math.floor(UM.Theme.getSize("toolbox_footer_button").height)
color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary")
}
label: Label
{
color: UM.Theme.getColor("button_text")
font: UM.Theme.getFont("default_bold")
text: control.text
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
}
}
} }
ToolboxShadow ToolboxShadow
{ {
visible: footer.visible visible: footer.visible

View file

@ -41,6 +41,9 @@ class PackagesModel(ListModel):
self.addRoleName(Qt.UserRole + 20, "links") self.addRoleName(Qt.UserRole + 20, "links")
self.addRoleName(Qt.UserRole + 21, "website") self.addRoleName(Qt.UserRole + 21, "website")
self.addRoleName(Qt.UserRole + 22, "login_required") self.addRoleName(Qt.UserRole + 22, "login_required")
self.addRoleName(Qt.UserRole + 23, "average_rating")
self.addRoleName(Qt.UserRole + 24, "num_ratings")
self.addRoleName(Qt.UserRole + 25, "user_rating")
# List of filters for queries. The result is the union of the each list of results. # List of filters for queries. The result is the union of the each list of results.
self._filter = {} # type: Dict[str, str] self._filter = {} # type: Dict[str, str]
@ -101,7 +104,10 @@ class PackagesModel(ListModel):
"tags": package["tags"] if "tags" in package else [], "tags": package["tags"] if "tags" in package else [],
"links": links_dict, "links": links_dict,
"website": package["website"] if "website" in package else None, "website": package["website"] if "website" in package else None,
"login_required": "login-required" in package.get("tags", []) "login_required": "login-required" in package.get("tags", []),
"average_rating": float(package.get("rating", {}).get("average", 0)),
"num_ratings": package.get("rating", {}).get("count", 0),
"user_rating": package.get("rating", {}).get("user_rating", 0)
}) })
# Filter on all the key-word arguments. # Filter on all the key-word arguments.

View file

@ -13,7 +13,6 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkRepl
from UM.Logger import Logger from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from UM.Extension import Extension from UM.Extension import Extension
from UM.Qt.ListModel import ListModel
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Version import Version from UM.Version import Version
@ -50,17 +49,10 @@ class Toolbox(QObject, Extension):
self._download_progress = 0 # type: float self._download_progress = 0 # type: float
self._is_downloading = False # type: bool self._is_downloading = False # type: bool
self._network_manager = None # type: Optional[QNetworkAccessManager] self._network_manager = None # type: Optional[QNetworkAccessManager]
self._request_header = [ self._request_headers = [] # type: List[Tuple[bytes, bytes]]
b"User-Agent", self._updateRequestHeader()
str.encode(
"%s/%s (%s %s)" % (
self._application.getApplicationName(),
self._application.getVersion(),
platform.system(),
platform.machine(),
)
)
]
self._request_urls = {} # type: Dict[str, QUrl] self._request_urls = {} # type: Dict[str, QUrl]
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
self._old_plugin_ids = set() # type: Set[str] self._old_plugin_ids = set() # type: Set[str]
@ -115,6 +107,7 @@ class Toolbox(QObject, Extension):
self._restart_dialog_message = "" # type: str self._restart_dialog_message = "" # type: str
self._application.initializationFinished.connect(self._onAppInitialized) self._application.initializationFinished.connect(self._onAppInitialized)
self._application.getCuraAPI().account.loginStateChanged.connect(self._updateRequestHeader)
# Signals: # Signals:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
@ -134,12 +127,38 @@ class Toolbox(QObject, Extension):
showLicenseDialog = pyqtSignal() showLicenseDialog = pyqtSignal()
uninstallVariablesChanged = pyqtSignal() uninstallVariablesChanged = pyqtSignal()
def _updateRequestHeader(self):
self._request_headers = [
(b"User-Agent",
str.encode(
"%s/%s (%s %s)" % (
self._application.getApplicationName(),
self._application.getVersion(),
platform.system(),
platform.machine(),
)
))
]
access_token = self._application.getCuraAPI().account.accessToken
if access_token:
self._request_headers.append((b"Authorization", "Bearer {}".format(access_token).encode()))
def _resetUninstallVariables(self) -> None: def _resetUninstallVariables(self) -> None:
self._package_id_to_uninstall = None # type: Optional[str] self._package_id_to_uninstall = None # type: Optional[str]
self._package_name_to_uninstall = "" self._package_name_to_uninstall = ""
self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]] self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]]
self._package_used_qualities = [] # type: List[Tuple[GlobalStack, str, str]] self._package_used_qualities = [] # type: List[Tuple[GlobalStack, str, str]]
@pyqtSlot(str, int)
def ratePackage(self, package_id: str, rating: int) -> None:
url = QUrl("{base_url}/packages/{package_id}/ratings".format(base_url=self._api_url, package_id = package_id))
self._rate_request = QNetworkRequest(url)
for header_name, header_value in self._request_headers:
cast(QNetworkRequest, self._rate_request).setRawHeader(header_name, header_value)
data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(self._application.getVersion()), rating)
self._rate_reply = cast(QNetworkAccessManager, self._network_manager).put(self._rate_request, data.encode())
@pyqtSlot(result = str) @pyqtSlot(result = str)
def getLicenseDialogPluginName(self) -> str: def getLicenseDialogPluginName(self) -> str:
return self._license_dialog_plugin_name return self._license_dialog_plugin_name
@ -563,7 +582,8 @@ class Toolbox(QObject, Extension):
def _makeRequestByType(self, request_type: str) -> None: def _makeRequestByType(self, request_type: str) -> None:
Logger.log("i", "Requesting %s metadata from server.", request_type) Logger.log("i", "Requesting %s metadata from server.", request_type)
request = QNetworkRequest(self._request_urls[request_type]) request = QNetworkRequest(self._request_urls[request_type])
request.setRawHeader(*self._request_header) for header_name, header_value in self._request_headers:
request.setRawHeader(header_name, header_value)
if self._network_manager: if self._network_manager:
self._network_manager.get(request) self._network_manager.get(request)
@ -578,7 +598,8 @@ class Toolbox(QObject, Extension):
if hasattr(QNetworkRequest, "RedirectPolicyAttribute"): if hasattr(QNetworkRequest, "RedirectPolicyAttribute"):
# Patch for Qt 5.9+ # Patch for Qt 5.9+
cast(QNetworkRequest, self._download_request).setAttribute(QNetworkRequest.RedirectPolicyAttribute, True) cast(QNetworkRequest, self._download_request).setAttribute(QNetworkRequest.RedirectPolicyAttribute, True)
cast(QNetworkRequest, self._download_request).setRawHeader(*self._request_header) for header_name, header_value in self._request_headers:
cast(QNetworkRequest, self._download_request).setRawHeader(header_name, header_value)
self._download_reply = cast(QNetworkAccessManager, self._network_manager).get(self._download_request) self._download_reply = cast(QNetworkAccessManager, self._network_manager).get(self._download_request)
self.setDownloadProgress(0) self.setDownloadProgress(0)
self.setIsDownloading(True) self.setIsDownloading(True)
@ -660,7 +681,7 @@ class Toolbox(QObject, Extension):
else: else:
self.setViewPage("errored") self.setViewPage("errored")
self.resetDownload() self.resetDownload()
else: elif reply.operation() == QNetworkAccessManager.PutOperation:
# Ignore any operation that is not a get operation # Ignore any operation that is not a get operation
pass pass

View file

@ -1,8 +1,8 @@
{ {
"name": "UFP Writer", "name": "UFP Writer",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides support for writing Ultimaker Format Packages.", "description": "Provides support for writing Ultimaker Format Packages.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -2,7 +2,7 @@
"name": "UM3 Network Connection", "name": "UM3 Network Connection",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"description": "Manages network connections to Ultimaker 3 printers.", "description": "Manages network connections to Ultimaker 3 printers.",
"version": "1.0.0", "version": "1.0.1",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -8,11 +8,13 @@ import UM 1.3 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
Rectangle { Rectangle {
id: base
property var iconSource: null; property var iconSource: null;
color: "#0a0850" // TODO: Theme! color: "#0a0850" // TODO: Theme!
height: width; height: width;
radius: Math.round(0.5 * width); radius: Math.round(0.5 * width);
width: 24 * screenScaleFactor; width: 24 * screenScaleFactor;
property var enabled: true
UM.RecolorImage { UM.RecolorImage {
id: icon; id: icon;
@ -29,12 +31,18 @@ Rectangle {
MouseArea { MouseArea {
id: clickArea; id: clickArea;
anchors.fill: parent; anchors.fill: parent;
hoverEnabled: true; hoverEnabled: base.enabled
onClicked: { onClicked: {
if (OutputDevice.activeCameraUrl != "") { if (base.enabled)
OutputDevice.setActiveCameraUrl(""); {
} else { if (OutputDevice.activeCameraUrl != "")
OutputDevice.setActiveCameraUrl(modelData.cameraUrl); {
OutputDevice.setActiveCameraUrl("")
}
else
{
OutputDevice.setActiveCameraUrl(modelData.cameraUrl)
}
} }
} }
} }

View file

@ -28,7 +28,7 @@ Cura.MachineAction
// Check if there is another instance with the same key // Check if there is another instance with the same key
if (!manager.existsKey(printerKey)) if (!manager.existsKey(printerKey))
{ {
manager.setKey(printerKey) manager.associateActiveMachineWithPrinterDevice(base.selectedDevice)
manager.setGroupName(printerName) // TODO To change when the groups have a name manager.setGroupName(printerName) // TODO To change when the groups have a name
completed() completed()
} }

View file

@ -16,9 +16,9 @@ Item
property bool expanded: false property bool expanded: false
property var borderWidth: 1 property var borderWidth: 1
property color borderColor: "#EAEAEC" property color borderColor: "#CCCCCC"
property color headerBackgroundColor: "white" property color headerBackgroundColor: "white"
property color headerHoverColor: "#f5f5f5" property color headerHoverColor: "#e8f2fc"
property color drawerBackgroundColor: "white" property color drawerBackgroundColor: "white"
property alias headerItem: header.children property alias headerItem: header.children
property alias drawerItem: drawer.children property alias drawerItem: drawer.children

View file

@ -0,0 +1,248 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
import UM 1.3 as UM
Item
{
id: base
property var currentIndex: 0
property var tileWidth: 834 * screenScaleFactor // TODO: Theme!
property var tileHeight: 216 * screenScaleFactor // TODO: Theme!
property var tileSpacing: 60 * screenScaleFactor // TODO: Theme!
property var maxOffset: (OutputDevice.printers.length - 1) * (tileWidth + tileSpacing)
height: centerSection.height
width: maximumWidth
Item
{
id: leftHint
anchors
{
right: leftButton.left
rightMargin: 12 * screenScaleFactor // TODO: Theme!
left: parent.left
}
height: parent.height
z: 10
LinearGradient
{
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(leftHint.width, 0)
gradient: Gradient
{
GradientStop
{
position: 0.0
color: "#fff6f6f6" // TODO: Theme!
}
GradientStop
{
position: 1.0
color: "#66f6f6f6" // TODO: Theme!
}
}
}
MouseArea
{
anchors.fill: parent
onClicked: navigateTo(currentIndex - 1)
}
}
Button
{
id: leftButton
anchors
{
verticalCenter: parent.verticalCenter
right: centerSection.left
rightMargin: 12 * screenScaleFactor // TODO: Theme!
}
width: 36 * screenScaleFactor // TODO: Theme!
height: 72 * screenScaleFactor // TODO: Theme!
visible: currentIndex > 0
hoverEnabled: true
z: 10
onClicked: navigateTo(currentIndex - 1)
background: Rectangle
{
color: leftButton.hovered ? "#e8f2fc" : "#ffffff" // TODO: Theme!
border.width: 1 * screenScaleFactor // TODO: Theme!
border.color: "#cccccc" // TODO: Theme!
radius: 2 * screenScaleFactor // TODO: Theme!
}
contentItem: Item
{
anchors.fill: parent
UM.RecolorImage
{
anchors.centerIn: parent
width: 18 // TODO: Theme!
height: width // TODO: Theme!
sourceSize.width: width // TODO: Theme!
sourceSize.height: width // TODO: Theme!
color: "#152950" // TODO: Theme!
source: UM.Theme.getIcon("arrow_left")
}
}
}
Item
{
id: centerSection
anchors
{
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
width: tileWidth
height: tiles.height
z: 1
Row
{
id: tiles
height: childrenRect.height
width: 5 * tileWidth + 4 * tileSpacing // TODO: Theme!
x: 0
z: 0
Behavior on x
{
NumberAnimation
{
duration: 200
easing.type: Easing.InOutCubic
}
}
spacing: 60 * screenScaleFactor // TODO: Theme!
Repeater
{
model: OutputDevice.printers
MonitorPrinterCard
{
printer: modelData
enabled: model.index == currentIndex
}
}
}
}
Button
{
id: rightButton
anchors
{
verticalCenter: parent.verticalCenter
left: centerSection.right
leftMargin: 12 * screenScaleFactor // TODO: Theme!
}
width: 36 * screenScaleFactor // TODO: Theme!
height: 72 * screenScaleFactor // TODO: Theme!
z: 10
visible: currentIndex < OutputDevice.printers.length - 1
onClicked: navigateTo(currentIndex + 1)
hoverEnabled: true
background: Rectangle
{
color: rightButton.hovered ? "#e8f2fc" : "#ffffff" // TODO: Theme!
border.width: 1 * screenScaleFactor // TODO: Theme!
border.color: "#cccccc" // TODO: Theme!
radius: 2 * screenScaleFactor // TODO: Theme!
}
contentItem: Item
{
anchors.fill: parent
UM.RecolorImage
{
anchors.centerIn: parent
width: 18 // TODO: Theme!
height: width // TODO: Theme!
sourceSize.width: width // TODO: Theme!
sourceSize.height: width // TODO: Theme!
color: "#152950" // TODO: Theme!
source: UM.Theme.getIcon("arrow_right")
}
}
}
Item
{
id: rightHint
anchors
{
left: rightButton.right
leftMargin: 12 * screenScaleFactor // TODO: Theme!
right: parent.right
}
height: centerSection.height
z: 10
LinearGradient
{
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(rightHint.width, 0)
gradient: Gradient
{
GradientStop
{
position: 0.0
color: "#66f6f6f6" // TODO: Theme!
}
GradientStop
{
position: 1.0
color: "#fff6f6f6" // TODO: Theme!
}
}
}
MouseArea
{
anchors.fill: parent
onClicked: navigateTo(currentIndex + 1)
}
}
Row
{
id: navigationDots
anchors
{
horizontalCenter: centerSection.horizontalCenter
top: centerSection.bottom
topMargin: 36 * screenScaleFactor // TODO: Theme!
}
spacing: 8 * screenScaleFactor // TODO: Theme!
Repeater
{
model: OutputDevice.printers
Button
{
background: Rectangle
{
color: model.index == currentIndex ? "#777777" : "#d8d8d8" // TODO: Theme!
radius: Math.floor(width / 2)
width: 12 * screenScaleFactor // TODO: Theme!
height: width // TODO: Theme!
}
onClicked: navigateTo(model.index)
}
}
}
function navigateTo( i ) {
if (i >= 0 && i < OutputDevice.printers.length)
{
tiles.x = -1 * i * (tileWidth + tileSpacing)
currentIndex = i
}
}
}

View file

@ -26,7 +26,7 @@ Item
ExpandableCard ExpandableCard
{ {
borderColor: printJob.configurationChanges.length !== 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! borderColor: printJob.configurationChanges.length !== 0 ? "#f5a623" : "#CCCCCC" // TODO: Theme!
headerItem: Row headerItem: Row
{ {
height: 48 * screenScaleFactor // TODO: Theme! height: 48 * screenScaleFactor // TODO: Theme!
@ -97,6 +97,7 @@ Item
return "" return ""
} }
visible: printJob visible: printJob
width: 120 * screenScaleFactor // TODO: Theme!
// FIXED-LINE-HEIGHT: // FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme!

View file

@ -25,8 +25,13 @@ Item
property var borderSize: 1 * screenScaleFactor // TODO: Theme, and remove from here property var borderSize: 1 * screenScaleFactor // TODO: Theme, and remove from here
// If the printer card's controls are enabled. This is used by the carousel
// to prevent opening the context menu or camera while the printer card is not
// "in focus"
property var enabled: true
width: 834 * screenScaleFactor // TODO: Theme! width: 834 * screenScaleFactor // TODO: Theme!
height: 216 * screenScaleFactor // TODO: Theme! height: childrenRect.height
// Printer portion // Printer portion
Rectangle Rectangle
@ -34,7 +39,7 @@ Item
id: printerInfo id: printerInfo
border border
{ {
color: "#EAEAEC" // TODO: Theme! color: "#CCCCCC" // TODO: Theme!
width: borderSize // TODO: Remove once themed width: borderSize // TODO: Remove once themed
} }
color: "white" // TODO: Theme! color: "white" // TODO: Theme!
@ -124,6 +129,7 @@ Item
printJob: printer.activePrintJob printJob: printer.activePrintJob
width: 36 * screenScaleFactor // TODO: Theme! width: 36 * screenScaleFactor // TODO: Theme!
height: 36 * screenScaleFactor // TODO: Theme! height: 36 * screenScaleFactor // TODO: Theme!
enabled: base.enabled
} }
CameraButton CameraButton
{ {
@ -136,6 +142,7 @@ Item
bottomMargin: 20 * screenScaleFactor // TODO: Theme! bottomMargin: 20 * screenScaleFactor // TODO: Theme!
} }
iconSource: "../svg/icons/camera.svg" iconSource: "../svg/icons/camera.svg"
enabled: base.enabled
} }
} }
@ -151,7 +158,7 @@ Item
} }
border border
{ {
color: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! color: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "#CCCCCC" // TODO: Theme!
width: borderSize // TODO: Remove once themed width: borderSize // TODO: Remove once themed
} }
color: "white" // TODO: Theme! color: "white" // TODO: Theme!
@ -320,7 +327,7 @@ Item
implicitHeight: 32 * screenScaleFactor // TODO: Theme! implicitHeight: 32 * screenScaleFactor // TODO: Theme!
implicitWidth: 96 * screenScaleFactor // TODO: Theme! implicitWidth: 96 * screenScaleFactor // TODO: Theme!
visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0
onClicked: overrideConfirmationDialog.open() onClicked: base.enabled ? overrideConfirmationDialog.open() : {}
} }
} }

View file

@ -12,7 +12,19 @@ import UM 1.2 as UM
Item Item
{ {
// The printer name // The printer name
property alias text: printerNameLabel.text; property var text: ""
property var tagText: {
switch(text) {
case "Ultimaker 3":
return "UM 3"
case "Ultimaker 3 Extended":
return "UM 3 EXT"
case "Ultimaker S5":
return "UM S5"
default:
return text
}
}
implicitHeight: 18 * screenScaleFactor // TODO: Theme! implicitHeight: 18 * screenScaleFactor // TODO: Theme!
implicitWidth: printerNameLabel.contentWidth + 12 // TODO: Theme! implicitWidth: printerNameLabel.contentWidth + 12 // TODO: Theme!
@ -28,7 +40,7 @@ Item
id: printerNameLabel id: printerNameLabel
anchors.centerIn: parent anchors.centerIn: parent
color: "#535369" // TODO: Theme! color: "#535369" // TODO: Theme!
text: "" text: tagText
font.pointSize: 10 font.pointSize: 10
} }
} }

View file

@ -0,0 +1,167 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.3 as UM
import Cura 1.0 as Cura
/**
* This component contains the print job queue, extracted from the primary
* MonitorStage.qml file not for reusability but simply to keep it lean and more
* readable.
*/
Item
{
Label
{
id: queuedLabel
anchors
{
left: queuedPrintJobs.left
top: parent.top
}
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("large_nonbold")
text: catalog.i18nc("@label", "Queued")
}
Item
{
id: manageQueueLabel
anchors
{
right: queuedPrintJobs.right
verticalCenter: queuedLabel.verticalCenter
}
height: 18 * screenScaleFactor // TODO: Theme!
width: childrenRect.width
UM.RecolorImage
{
id: externalLinkIcon
anchors.verticalCenter: manageQueueLabel.verticalCenter
color: UM.Theme.getColor("primary")
source: "../svg/icons/external_link.svg"
width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
}
Label
{
id: manageQueueText
anchors
{
left: externalLinkIcon.right
leftMargin: 6 * screenScaleFactor // TODO: Theme!
verticalCenter: externalLinkIcon.verticalCenter
}
color: UM.Theme.getColor("primary")
font: UM.Theme.getFont("default") // 12pt, regular
linkColor: UM.Theme.getColor("primary")
text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect")
}
}
MouseArea
{
anchors.fill: manageQueueLabel
hoverEnabled: true
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
onEntered:
{
manageQueueText.font.underline = true
}
onExited:
{
manageQueueText.font.underline = false
}
}
Row
{
id: printJobQueueHeadings
anchors
{
left: queuedPrintJobs.left
leftMargin: 6 * screenScaleFactor // TODO: Theme!
top: queuedLabel.bottom
topMargin: 24 * screenScaleFactor // TODO: Theme!
}
spacing: 18 * screenScaleFactor // TODO: Theme!
Label
{
text: catalog.i18nc("@label", "Print jobs")
color: "#666666"
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
width: 284 * screenScaleFactor // TODO: Theme! (Should match column size)
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
}
Label
{
text: catalog.i18nc("@label", "Total print time")
color: "#666666"
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
}
Label
{
text: catalog.i18nc("@label", "Waiting for")
color: "#666666"
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
}
}
ScrollView
{
id: queuedPrintJobs
anchors
{
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
top: printJobQueueHeadings.bottom
topMargin: 12 * screenScaleFactor // TODO: Theme!
}
style: UM.Theme.styles.scrollview
visible: OutputDevice.receivedPrintJobs
width: parent.width
ListView
{
id: printJobList
anchors.fill: parent
delegate: MonitorPrintJobCard
{
anchors
{
left: parent.left
right: parent.right
}
printJob: modelData
}
model: OutputDevice.queuedPrintJobs
spacing: 6 // TODO: Theme!
}
}
}

View file

@ -8,16 +8,13 @@ import UM 1.3 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
// Root component for the monitor tab (stage) // This is the root component for the monitor stage.
Component Component
{ {
Item Item
{ {
id: monitorFrame id: monitorFrame
property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight")
property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width
height: maximumHeight height: maximumHeight
onVisibleChanged: onVisibleChanged:
{ {
@ -34,212 +31,52 @@ Component
name: "cura" name: "cura"
} }
LinearGradient { LinearGradient
anchors.fill: parent
gradient: Gradient {
GradientStop {
position: 0.0
color: "#f6f6f6"
}
GradientStop {
position: 1.0
color: "#ffffff"
}
}
}
ScrollView
{ {
id: printers anchors.fill: parent
anchors gradient: Gradient
{ {
left: queue.left GradientStop
right: queue.right
top: parent.top
topMargin: 48 * screenScaleFactor // TODO: Theme!
}
height: 264 * screenScaleFactor // TODO: Theme!
Row
{
spacing: 60 * screenScaleFactor // TODO: Theme!
Repeater
{ {
model: OutputDevice.printers position: 0.0
color: "#f6f6f6" // TODO: Theme!
MonitorPrinterCard }
{ GradientStop
printer: modelData {
} position: 1.0
color: "#ffffff" // TODO: Theme!
} }
} }
} }
Item Item
{
id: printers
anchors
{
top: parent.top
topMargin: 48 * screenScaleFactor // TODO: Theme!
}
width: parent.width
height: 264 * screenScaleFactor // TODO: Theme!
MonitorCarousel {}
}
MonitorQueue
{ {
id: queue id: queue
width: Math.min(834 * screenScaleFactor, maximumWidth) width: Math.min(834 * screenScaleFactor, maximumWidth)
anchors
anchors { {
bottom: parent.bottom bottom: parent.bottom
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter
top: printers.bottom top: printers.bottom
topMargin: 48 * screenScaleFactor // TODO: Theme! topMargin: 48 * screenScaleFactor // TODO: Theme!
} }
Label
{
id: queuedLabel
anchors
{
left: queuedPrintJobs.left
top: parent.top
}
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("large")
text: catalog.i18nc("@label", "Queued")
}
Item
{
id: manageQueueLabel
anchors
{
right: queuedPrintJobs.right
verticalCenter: queuedLabel.verticalCenter
}
height: 18 * screenScaleFactor // TODO: Theme!
width: childrenRect.width
UM.RecolorImage
{
id: externalLinkIcon
anchors.verticalCenter: manageQueueLabel.verticalCenter
color: UM.Theme.getColor("primary")
source: "../svg/icons/external_link.svg"
width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
}
Label
{
id: manageQueueText
anchors
{
left: externalLinkIcon.right
leftMargin: 6 * screenScaleFactor // TODO: Theme!
verticalCenter: externalLinkIcon.verticalCenter
}
color: UM.Theme.getColor("primary")
font: UM.Theme.getFont("default") // 12pt, regular
linkColor: UM.Theme.getColor("primary")
text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect")
}
}
MouseArea
{
anchors.fill: manageQueueLabel
hoverEnabled: true
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
onEntered:
{
manageQueueText.font.underline = true
}
onExited:
{
manageQueueText.font.underline = false
}
}
Row
{
id: printJobQueueHeadings
anchors
{
left: queuedPrintJobs.left
leftMargin: 6 * screenScaleFactor // TODO: Theme!
top: queuedLabel.bottom
topMargin: 24 * screenScaleFactor // TODO: Theme!
}
spacing: 18 * screenScaleFactor // TODO: Theme!
Label
{
text: catalog.i18nc("@label", "Print jobs")
color: "#666666"
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
width: 284 * screenScaleFactor // TODO: Theme! (Should match column size)
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
}
Label
{
text: catalog.i18nc("@label", "Total print time")
color: "#666666"
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
}
Label
{
text: catalog.i18nc("@label", "Waiting for")
color: "#666666"
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
}
}
ScrollView
{
id: queuedPrintJobs
anchors {
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
top: printJobQueueHeadings.bottom
topMargin: 12 * screenScaleFactor // TODO: Theme!
}
style: UM.Theme.styles.scrollview
visible: OutputDevice.receivedPrintJobs
width: parent.width
ListView
{
id: printJobList
anchors.fill: parent
delegate: MonitorPrintJobCard
{
anchors
{
left: parent.left
right: parent.right
}
printJob: modelData
}
model: OutputDevice.queuedPrintJobs
spacing: 6
}
}
} }
PrinterVideoStream { PrinterVideoStream
{
anchors.fill: parent anchors.fill: parent
cameraUrl: OutputDevice.activeCameraUrl cameraUrl: OutputDevice.activeCameraUrl
visible: OutputDevice.activeCameraUrl != "" visible: OutputDevice.activeCameraUrl != ""

View file

@ -13,6 +13,7 @@ Item {
property var printJob: null; property var printJob: null;
property var started: isStarted(printJob); property var started: isStarted(printJob);
property var assigned: isAssigned(printJob); property var assigned: isAssigned(printJob);
property var enabled: true
Button { Button {
id: button; id: button;
@ -31,8 +32,8 @@ Item {
verticalAlignment: Text.AlignVCenter; verticalAlignment: Text.AlignVCenter;
} }
height: width; height: width;
hoverEnabled: true; hoverEnabled: base.enabled
onClicked: parent.switchPopupState(); onClicked: base.enabled ? parent.switchPopupState() : {}
text: "\u22EE"; //Unicode; Three stacked points. text: "\u22EE"; //Unicode; Three stacked points.
visible: { visible: {
if (!printJob) { if (!printJob) {

View file

@ -13,8 +13,40 @@ Item {
property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId; property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId;
property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null; property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null;
property bool printerConnected: Cura.MachineManager.printerConnected; property bool printerConnected: Cura.MachineManager.printerConnected;
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands; property bool printerAcceptsCommands:
property bool authenticationRequested: printerConnected && (Cura.MachineManager.printerOutputDevices[0].authenticationState == 2 || Cura.MachineManager.printerOutputDevices[0].authenticationState == 5); // AuthState.AuthenticationRequested or AuthenticationReceived. {
if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
{
return Cura.MachineManager.printerOutputDevices[0].acceptsCommands
}
return false
}
property bool authenticationRequested:
{
if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
{
var device = Cura.MachineManager.printerOutputDevices[0]
// AuthState.AuthenticationRequested or AuthState.AuthenticationReceived
return device.authenticationState == 2 || device.authenticationState == 5
}
return false
}
property var materialNames:
{
if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
{
return Cura.MachineManager.printerOutputDevices[0].materialNames
}
return null
}
property var hotendIds:
{
if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
{
return Cura.MachineManager.printerOutputDevices[0].hotendIds
}
return null
}
UM.I18nCatalog { UM.I18nCatalog {
id: catalog; id: catalog;
@ -83,9 +115,7 @@ Item {
Column { Column {
Repeater { Repeater {
model: Cura.ExtrudersModel { model: CuraApplication.getExtrudersModel()
simpleNames: true;
}
Label { Label {
text: model.name; text: model.name;
@ -96,7 +126,7 @@ Item {
Column { Column {
Repeater { Repeater {
id: nozzleColumn; id: nozzleColumn;
model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].hotendIds : null; model: hotendIds
Label { Label {
text: nozzleColumn.model[index]; text: nozzleColumn.model[index];
@ -107,7 +137,7 @@ Item {
Column { Column {
Repeater { Repeater {
id: materialColumn; id: materialColumn;
model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].materialNames : null; model: materialNames
Label { Label {
text: materialColumn.model[index]; text: materialColumn.model[index];

View file

@ -22,6 +22,7 @@ from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationM
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
from cura.PrinterOutputDevice import ConnectionType
from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController
from .SendMaterialJob import SendMaterialJob from .SendMaterialJob import SendMaterialJob
@ -54,7 +55,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
clusterPrintersChanged = pyqtSignal() clusterPrintersChanged = pyqtSignal()
def __init__(self, device_id, address, properties, parent = None) -> None: def __init__(self, device_id, address, properties, parent = None) -> None:
super().__init__(device_id = device_id, address = address, properties=properties, parent = parent) super().__init__(device_id = device_id, address = address, properties=properties, connection_type = ConnectionType.NetworkConnection, parent = parent)
self._api_prefix = "/cluster-api/v1/" self._api_prefix = "/cluster-api/v1/"
self._number_of_extruders = 2 self._number_of_extruders = 2

View file

@ -3,7 +3,7 @@
import os.path import os.path
import time import time
from typing import cast, Optional from typing import Optional, TYPE_CHECKING
from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject
@ -16,6 +16,9 @@ from cura.MachineAction import MachineAction
from .UM3OutputDevicePlugin import UM3OutputDevicePlugin from .UM3OutputDevicePlugin import UM3OutputDevicePlugin
if TYPE_CHECKING:
from cura.PrinterOutputDevice import PrinterOutputDevice
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
@ -116,22 +119,30 @@ class DiscoverUM3Action(MachineAction):
# Ensure that the connection states are refreshed. # Ensure that the connection states are refreshed.
self._network_plugin.reCheckConnections() self._network_plugin.reCheckConnections()
@pyqtSlot(str) # Associates the currently active machine with the given printer device. The network connection information will be
def setKey(self, key: str) -> None: # stored into the metadata of the currently active machine.
Logger.log("d", "Attempting to set the network key of the active machine to %s", key) @pyqtSlot(QObject)
def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None:
Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key)
global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
if global_container_stack: if global_container_stack:
meta_data = global_container_stack.getMetaData() meta_data = global_container_stack.getMetaData()
if "um_network_key" in meta_data: if "um_network_key" in meta_data:
previous_network_key= meta_data["um_network_key"] previous_network_key= meta_data["um_network_key"]
global_container_stack.setMetaDataEntry("um_network_key", key) global_container_stack.setMetaDataEntry("um_network_key", printer_device.key)
# Delete old authentication data. # Delete old authentication data.
Logger.log("d", "Removing old authentication id %s for device %s", global_container_stack.getMetaDataEntry("network_authentication_id", None), key) Logger.log("d", "Removing old authentication id %s for device %s", global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key)
global_container_stack.removeMetaDataEntry("network_authentication_id") global_container_stack.removeMetaDataEntry("network_authentication_id")
global_container_stack.removeMetaDataEntry("network_authentication_key") global_container_stack.removeMetaDataEntry("network_authentication_key")
CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = key) CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = printer_device.key)
if "connection_type" in meta_data:
previous_connection_type = meta_data["connection_type"]
global_container_stack.setMetaDataEntry("connection_type", printer_device.getConnectionType().value)
CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connection_type", value = previous_connection_type, new_value = printer_device.getConnectionType().value)
else: else:
global_container_stack.setMetaDataEntry("um_network_key", key) global_container_stack.setMetaDataEntry("um_network_key", printer_device.key)
global_container_stack.setMetaDataEntry("connection_type", printer_device.getConnectionType().value)
if self._network_plugin: if self._network_plugin:
# Ensure that the connection states are refreshed. # Ensure that the connection states are refreshed.

View file

@ -7,6 +7,7 @@ from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutp
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
from cura.PrinterOutputDevice import ConnectionType
from cura.Settings.ContainerManager import ContainerManager from cura.Settings.ContainerManager import ContainerManager
from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderManager import ExtruderManager
@ -43,7 +44,7 @@ i18n_catalog = i18nCatalog("cura")
# 5. As a final step, we verify the authentication, as this forces the QT manager to setup the authenticator. # 5. As a final step, we verify the authentication, as this forces the QT manager to setup the authenticator.
class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
def __init__(self, device_id, address: str, properties, parent = None) -> None: def __init__(self, device_id, address: str, properties, parent = None) -> None:
super().__init__(device_id = device_id, address = address, properties = properties, parent = parent) super().__init__(device_id = device_id, address = address, properties = properties, connection_type = ConnectionType.NetworkConnection, parent = parent)
self._api_prefix = "/api/v1/" self._api_prefix = "/api/v1/"
self._number_of_extruders = 2 self._number_of_extruders = 2

View file

@ -283,6 +283,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
global_container_stack = Application.getInstance().getGlobalContainerStack() global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"): if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"):
global_container_stack.setMetaDataEntry("connection_type", device.getConnectionType().value)
device.connect() device.connect()
device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged) device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged)

View file

@ -13,6 +13,8 @@ Component
{ {
Rectangle Rectangle
{ {
color: UM.Theme.getColor("main_background")
anchors.right: parent.right anchors.right: parent.right
width: parent.width * 0.3 width: parent.width * 0.3
anchors.top: parent.top anchors.top: parent.top

View file

@ -7,7 +7,7 @@ from UM.i18n import i18nCatalog
from UM.Qt.Duration import DurationFormat from UM.Qt.Duration import DurationFormat
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.GenericOutputController import GenericOutputController from cura.PrinterOutput.GenericOutputController import GenericOutputController
@ -29,7 +29,7 @@ catalog = i18nCatalog("cura")
class USBPrinterOutputDevice(PrinterOutputDevice): class USBPrinterOutputDevice(PrinterOutputDevice):
def __init__(self, serial_port: str, baud_rate: Optional[int] = None) -> None: def __init__(self, serial_port: str, baud_rate: Optional[int] = None) -> None:
super().__init__(serial_port) super().__init__(serial_port, connection_type = ConnectionType.UsbConnection)
self.setName(catalog.i18nc("@item:inmenu", "USB printing")) self.setName(catalog.i18nc("@item:inmenu", "USB printing"))
self.setShortDescription(catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print via USB")) self.setShortDescription(catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print via USB"))
self.setDescription(catalog.i18nc("@info:tooltip", "Print via USB")) self.setDescription(catalog.i18nc("@info:tooltip", "Print via USB"))
@ -179,7 +179,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
return return
CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
self._onGlobalContainerStackChanged() self._onGlobalContainerStackChanged()
self.setConnectionState(ConnectionState.connected) self.setConnectionState(ConnectionState.Connected)
self._update_thread.start() self._update_thread.start()
def _onGlobalContainerStackChanged(self): def _onGlobalContainerStackChanged(self):
@ -208,7 +208,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._sendCommand(command) self._sendCommand(command)
def _sendCommand(self, command: Union[str, bytes]): def _sendCommand(self, command: Union[str, bytes]):
if self._serial is None or self._connection_state != ConnectionState.connected: if self._serial is None or self._connection_state != ConnectionState.Connected:
return return
new_command = cast(bytes, command) if type(command) is bytes else cast(str, command).encode() # type: bytes new_command = cast(bytes, command) if type(command) is bytes else cast(str, command).encode() # type: bytes
@ -222,7 +222,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._command_received.set() self._command_received.set()
def _update(self): def _update(self):
while self._connection_state == ConnectionState.connected and self._serial is not None: while self._connection_state == ConnectionState.Connected and self._serial is not None:
try: try:
line = self._serial.readline() line = self._serial.readline()
except: except:

View file

@ -66,7 +66,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin):
return return
changed_device = self._usb_output_devices[serial_port] changed_device = self._usb_output_devices[serial_port]
if changed_device.connectionState == ConnectionState.connected: if changed_device.connectionState == ConnectionState.Connected:
self.getOutputDeviceManager().addOutputDevice(changed_device) self.getOutputDeviceManager().addOutputDevice(changed_device)
else: else:
self.getOutputDeviceManager().removeOutputDevice(serial_port) self.getOutputDeviceManager().removeOutputDevice(serial_port)

View file

@ -1,8 +1,8 @@
{ {
"name": "USB printing", "name": "USB printing",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.1", "version": "1.0.2",
"api": 5, "api": "6.0",
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.", "description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Ultimaker machine actions", "name": "Ultimaker machine actions",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).", "description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "UserAgreement", "name": "UserAgreement",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Ask the user once if he/she agrees with our license.", "description": "Ask the user once if he/she agrees with our license.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 2.1 to 2.2", "name": "Version Upgrade 2.1 to 2.2",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.", "description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 2.2 to 2.4", "name": "Version Upgrade 2.2 to 2.4",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.", "description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 2.5 to 2.6", "name": "Version Upgrade 2.5 to 2.6",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.", "description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 2.6 to 2.7", "name": "Version Upgrade 2.6 to 2.7",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.", "description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 2.7 to 3.0", "name": "Version Upgrade 2.7 to 3.0",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.", "description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 3.0 to 3.1", "name": "Version Upgrade 3.0 to 3.1",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.", "description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 3.2 to 3.3", "name": "Version Upgrade 3.2 to 3.3",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.", "description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 3.3 to 3.4", "name": "Version Upgrade 3.3 to 3.4",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.", "description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Version Upgrade 3.4 to 3.5", "name": "Version Upgrade 3.4 to 3.5",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.", "description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "X3D Reader", "name": "X3D Reader",
"author": "Seva Alekseyev", "author": "Seva Alekseyev",
"version": "0.5.0", "version": "1.0.1",
"description": "Provides support for reading X3D files.", "description": "Provides support for reading X3D files.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "X-Ray View", "name": "X-Ray View",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides the X-Ray view.", "description": "Provides the X-Ray view.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -1,8 +1,8 @@
{ {
"name": "Material Profiles", "name": "Material Profiles",
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.0", "version": "1.0.1",
"description": "Provides capabilities to read and write XML-based material profiles.", "description": "Provides capabilities to read and write XML-based material profiles.",
"api": 5, "api": "6.0",
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View file

@ -5,8 +5,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "3MF Reader", "display_name": "3MF Reader",
"description": "Provides support for reading 3MF files.", "description": "Provides support for reading 3MF files.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -22,8 +22,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "3MF Writer", "display_name": "3MF Writer",
"description": "Provides support for writing 3MF files.", "description": "Provides support for writing 3MF files.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -39,8 +39,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Change Log", "display_name": "Change Log",
"description": "Shows changes since latest checked version.", "description": "Shows changes since latest checked version.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -56,8 +56,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "CuraEngine Backend", "display_name": "CuraEngine Backend",
"description": "Provides the link to the CuraEngine slicing backend.", "description": "Provides the link to the CuraEngine slicing backend.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -73,8 +73,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Cura Profile Reader", "display_name": "Cura Profile Reader",
"description": "Provides support for importing Cura profiles.", "description": "Provides support for importing Cura profiles.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -90,8 +90,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Cura Profile Writer", "display_name": "Cura Profile Writer",
"description": "Provides support for exporting Cura profiles.", "description": "Provides support for exporting Cura profiles.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -107,8 +107,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Firmware Update Checker", "display_name": "Firmware Update Checker",
"description": "Checks for firmware updates.", "description": "Checks for firmware updates.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -124,8 +124,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Firmware Updater", "display_name": "Firmware Updater",
"description": "Provides a machine actions for updating firmware.", "description": "Provides a machine actions for updating firmware.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -141,8 +141,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Compressed G-code Reader", "display_name": "Compressed G-code Reader",
"description": "Reads g-code from a compressed archive.", "description": "Reads g-code from a compressed archive.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -158,8 +158,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Compressed G-code Writer", "display_name": "Compressed G-code Writer",
"description": "Writes g-code to a compressed archive.", "description": "Writes g-code to a compressed archive.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -175,8 +175,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "G-Code Profile Reader", "display_name": "G-Code Profile Reader",
"description": "Provides support for importing profiles from g-code files.", "description": "Provides support for importing profiles from g-code files.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -192,8 +192,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "G-Code Reader", "display_name": "G-Code Reader",
"description": "Allows loading and displaying G-code files.", "description": "Allows loading and displaying G-code files.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "VictorLarchenko", "author_id": "VictorLarchenko",
@ -209,8 +209,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "G-Code Writer", "display_name": "G-Code Writer",
"description": "Writes g-code to a file.", "description": "Writes g-code to a file.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -226,8 +226,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Image Reader", "display_name": "Image Reader",
"description": "Enables ability to generate printable geometry from 2D image files.", "description": "Enables ability to generate printable geometry from 2D image files.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -243,8 +243,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Legacy Cura Profile Reader", "display_name": "Legacy Cura Profile Reader",
"description": "Provides support for importing profiles from legacy Cura versions.", "description": "Provides support for importing profiles from legacy Cura versions.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -260,8 +260,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Machine Settings Action", "display_name": "Machine Settings Action",
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).", "description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "fieldOfView", "author_id": "fieldOfView",
@ -277,8 +277,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Model Checker", "display_name": "Model Checker",
"description": "Checks models and print configuration for possible printing issues and give suggestions.", "description": "Checks models and print configuration for possible printing issues and give suggestions.",
"package_version": "0.1.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -294,8 +294,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Monitor Stage", "display_name": "Monitor Stage",
"description": "Provides a monitor stage in Cura.", "description": "Provides a monitor stage in Cura.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -311,8 +311,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Per-Object Settings Tool", "display_name": "Per-Object Settings Tool",
"description": "Provides the per-model settings.", "description": "Provides the per-model settings.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -328,8 +328,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Post Processing", "display_name": "Post Processing",
"description": "Extension that allows for user created scripts for post processing.", "description": "Extension that allows for user created scripts for post processing.",
"package_version": "2.2.0", "package_version": "2.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -345,8 +345,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Prepare Stage", "display_name": "Prepare Stage",
"description": "Provides a prepare stage in Cura.", "description": "Provides a prepare stage in Cura.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -362,8 +362,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Preview Stage", "display_name": "Preview Stage",
"description": "Provides a preview stage in Cura.", "description": "Provides a preview stage in Cura.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -379,8 +379,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Removable Drive Output Device", "display_name": "Removable Drive Output Device",
"description": "Provides removable drive hotplugging and writing support.", "description": "Provides removable drive hotplugging and writing support.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -396,8 +396,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Simulation View", "display_name": "Simulation View",
"description": "Provides the Simulation view.", "description": "Provides the Simulation view.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -413,8 +413,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Slice Info", "display_name": "Slice Info",
"description": "Submits anonymous slice info. Can be disabled through preferences.", "description": "Submits anonymous slice info. Can be disabled through preferences.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -430,8 +430,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Solid View", "display_name": "Solid View",
"description": "Provides a normal solid mesh view.", "description": "Provides a normal solid mesh view.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -447,8 +447,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Support Eraser Tool", "display_name": "Support Eraser Tool",
"description": "Creates an eraser mesh to block the printing of support in certain places.", "description": "Creates an eraser mesh to block the printing of support in certain places.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -464,8 +464,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Toolbox", "display_name": "Toolbox",
"description": "Find, manage and install new Cura packages.", "description": "Find, manage and install new Cura packages.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -481,8 +481,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "UFP Writer", "display_name": "UFP Writer",
"description": "Provides support for writing Ultimaker Format Packages.", "description": "Provides support for writing Ultimaker Format Packages.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -498,8 +498,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Ultimaker Machine Actions", "display_name": "Ultimaker Machine Actions",
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).", "description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -515,8 +515,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "UM3 Network Printing", "display_name": "UM3 Network Printing",
"description": "Manages network connections to Ultimaker 3 printers.", "description": "Manages network connections to Ultimaker 3 printers.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -532,8 +532,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "USB Printing", "display_name": "USB Printing",
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.", "description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
"package_version": "1.0.1", "package_version": "1.0.2",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -549,8 +549,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "User Agreement", "display_name": "User Agreement",
"description": "Ask the user once if he/she agrees with our license.", "description": "Ask the user once if he/she agrees with our license.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -566,8 +566,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 2.1 to 2.2", "display_name": "Version Upgrade 2.1 to 2.2",
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.", "description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -583,8 +583,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 2.2 to 2.4", "display_name": "Version Upgrade 2.2 to 2.4",
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.", "description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -600,8 +600,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 2.5 to 2.6", "display_name": "Version Upgrade 2.5 to 2.6",
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.", "description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -617,8 +617,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 2.6 to 2.7", "display_name": "Version Upgrade 2.6 to 2.7",
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.", "description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -634,8 +634,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 2.7 to 3.0", "display_name": "Version Upgrade 2.7 to 3.0",
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.", "description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -651,8 +651,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 3.0 to 3.1", "display_name": "Version Upgrade 3.0 to 3.1",
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.", "description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -668,8 +668,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 3.2 to 3.3", "display_name": "Version Upgrade 3.2 to 3.3",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.", "description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -685,8 +685,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 3.3 to 3.4", "display_name": "Version Upgrade 3.3 to 3.4",
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.", "description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -702,8 +702,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "Version Upgrade 3.4 to 3.5", "display_name": "Version Upgrade 3.4 to 3.5",
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.", "description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -719,8 +719,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "X3D Reader", "display_name": "X3D Reader",
"description": "Provides support for reading X3D files.", "description": "Provides support for reading X3D files.",
"package_version": "0.5.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "SevaAlekseyev", "author_id": "SevaAlekseyev",
@ -736,8 +736,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "XML Material Profiles", "display_name": "XML Material Profiles",
"description": "Provides capabilities to read and write XML-based material profiles.", "description": "Provides capabilities to read and write XML-based material profiles.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -753,8 +753,8 @@
"package_type": "plugin", "package_type": "plugin",
"display_name": "X-Ray View", "display_name": "X-Ray View",
"description": "Provides the X-Ray view.", "description": "Provides the X-Ray view.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com", "website": "https://ultimaker.com",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -770,8 +770,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic ABS", "display_name": "Generic ABS",
"description": "The generic ABS profile which other profiles can be based upon.", "description": "The generic ABS profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -788,8 +788,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic BAM", "display_name": "Generic BAM",
"description": "The generic BAM profile which other profiles can be based upon.", "description": "The generic BAM profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -806,8 +806,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic CFF CPE", "display_name": "Generic CFF CPE",
"description": "The generic CFF CPE profile which other profiles can be based upon.", "description": "The generic CFF CPE profile which other profiles can be based upon.",
"package_version": "1.1.0", "package_version": "1.1.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -824,8 +824,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic CFF PA", "display_name": "Generic CFF PA",
"description": "The generic CFF PA profile which other profiles can be based upon.", "description": "The generic CFF PA profile which other profiles can be based upon.",
"package_version": "1.1.0", "package_version": "1.1.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -842,8 +842,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic CPE", "display_name": "Generic CPE",
"description": "The generic CPE profile which other profiles can be based upon.", "description": "The generic CPE profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -860,8 +860,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic CPE+", "display_name": "Generic CPE+",
"description": "The generic CPE+ profile which other profiles can be based upon.", "description": "The generic CPE+ profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -878,8 +878,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic GFF CPE", "display_name": "Generic GFF CPE",
"description": "The generic GFF CPE profile which other profiles can be based upon.", "description": "The generic GFF CPE profile which other profiles can be based upon.",
"package_version": "1.1.0", "package_version": "1.1.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -896,8 +896,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic GFF PA", "display_name": "Generic GFF PA",
"description": "The generic GFF PA profile which other profiles can be based upon.", "description": "The generic GFF PA profile which other profiles can be based upon.",
"package_version": "1.1.0", "package_version": "1.1.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -914,8 +914,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic HIPS", "display_name": "Generic HIPS",
"description": "The generic HIPS profile which other profiles can be based upon.", "description": "The generic HIPS profile which other profiles can be based upon.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -932,8 +932,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic Nylon", "display_name": "Generic Nylon",
"description": "The generic Nylon profile which other profiles can be based upon.", "description": "The generic Nylon profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -950,8 +950,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic PC", "display_name": "Generic PC",
"description": "The generic PC profile which other profiles can be based upon.", "description": "The generic PC profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -968,8 +968,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic PETG", "display_name": "Generic PETG",
"description": "The generic PETG profile which other profiles can be based upon.", "description": "The generic PETG profile which other profiles can be based upon.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -986,8 +986,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic PLA", "display_name": "Generic PLA",
"description": "The generic PLA profile which other profiles can be based upon.", "description": "The generic PLA profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -1004,8 +1004,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic PP", "display_name": "Generic PP",
"description": "The generic PP profile which other profiles can be based upon.", "description": "The generic PP profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -1022,8 +1022,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic PVA", "display_name": "Generic PVA",
"description": "The generic PVA profile which other profiles can be based upon.", "description": "The generic PVA profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -1040,8 +1040,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic Tough PLA", "display_name": "Generic Tough PLA",
"description": "The generic Tough PLA profile which other profiles can be based upon.", "description": "The generic Tough PLA profile which other profiles can be based upon.",
"package_version": "1.0.1", "package_version": "1.0.2",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -1058,8 +1058,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Generic TPU", "display_name": "Generic TPU",
"description": "The generic TPU profile which other profiles can be based upon.", "description": "The generic TPU profile which other profiles can be based upon.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://github.com/Ultimaker/fdm_materials", "website": "https://github.com/Ultimaker/fdm_materials",
"author": { "author": {
"author_id": "Generic", "author_id": "Generic",
@ -1076,8 +1076,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Dagoma Chromatik PLA", "display_name": "Dagoma Chromatik PLA",
"description": "Filament testé et approuvé pour les imprimantes 3D Dagoma. Chromatik est l'idéal pour débuter et suivre les tutoriels premiers pas. Il vous offre qualité et résistance pour chacune de vos impressions.", "description": "Filament testé et approuvé pour les imprimantes 3D Dagoma. Chromatik est l'idéal pour débuter et suivre les tutoriels premiers pas. Il vous offre qualité et résistance pour chacune de vos impressions.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://dagoma.fr/boutique/filaments.html", "website": "https://dagoma.fr/boutique/filaments.html",
"author": { "author": {
"author_id": "Dagoma", "author_id": "Dagoma",
@ -1093,8 +1093,8 @@
"package_type": "material", "package_type": "material",
"display_name": "FABtotum ABS", "display_name": "FABtotum ABS",
"description": "This material is easy to be extruded but it is not the simplest to use. It is one of the most used in 3D printing to get very well finished objects. It is not sustainable and its smoke can be dangerous if inhaled. The reason to prefer this filament to PLA is mainly because of its precision and mechanical specs. ABS (for plastic) stands for Acrylonitrile Butadiene Styrene and it is a thermoplastic which is widely used in everyday objects. It can be printed with any FFF 3D printer which can get to high temperatures as it must be extruded in a range between 220° and 245°, so its compatible with all versions of the FABtotum Personal fabricator.", "description": "This material is easy to be extruded but it is not the simplest to use. It is one of the most used in 3D printing to get very well finished objects. It is not sustainable and its smoke can be dangerous if inhaled. The reason to prefer this filament to PLA is mainly because of its precision and mechanical specs. ABS (for plastic) stands for Acrylonitrile Butadiene Styrene and it is a thermoplastic which is widely used in everyday objects. It can be printed with any FFF 3D printer which can get to high temperatures as it must be extruded in a range between 220° and 245°, so its compatible with all versions of the FABtotum Personal fabricator.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=40", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=40",
"author": { "author": {
"author_id": "FABtotum", "author_id": "FABtotum",
@ -1110,8 +1110,8 @@
"package_type": "material", "package_type": "material",
"display_name": "FABtotum Nylon", "display_name": "FABtotum Nylon",
"description": "When 3D printing started this material was not listed among the extrudable filaments. It is flexible as well as resistant to tractions. It is well known for its uses in textile but also in industries which require a strong and flexible material. There are different kinds of Nylon: 3D printing mostly uses Nylon 6 and Nylon 6.6, which are the most common. It requires higher temperatures to be printed, so a 3D printer must be able to reach them (around 240°C): the FABtotum, of course, can.", "description": "When 3D printing started this material was not listed among the extrudable filaments. It is flexible as well as resistant to tractions. It is well known for its uses in textile but also in industries which require a strong and flexible material. There are different kinds of Nylon: 3D printing mostly uses Nylon 6 and Nylon 6.6, which are the most common. It requires higher temperatures to be printed, so a 3D printer must be able to reach them (around 240°C): the FABtotum, of course, can.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=53", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=53",
"author": { "author": {
"author_id": "FABtotum", "author_id": "FABtotum",
@ -1127,8 +1127,8 @@
"package_type": "material", "package_type": "material",
"display_name": "FABtotum PLA", "display_name": "FABtotum PLA",
"description": "It is the most common filament used for 3D printing. It is studied to be bio-degradable as it comes from corn starchs sugar mainly. It is completely made of renewable sources and has no footprint on polluting. PLA stands for PolyLactic Acid and it is a thermoplastic that today is still considered the easiest material to be 3D printed. It can be extruded at lower temperatures: the standard range of FABtotums one is between 185° and 195°.", "description": "It is the most common filament used for 3D printing. It is studied to be bio-degradable as it comes from corn starchs sugar mainly. It is completely made of renewable sources and has no footprint on polluting. PLA stands for PolyLactic Acid and it is a thermoplastic that today is still considered the easiest material to be 3D printed. It can be extruded at lower temperatures: the standard range of FABtotums one is between 185° and 195°.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=39", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=39",
"author": { "author": {
"author_id": "FABtotum", "author_id": "FABtotum",
@ -1144,8 +1144,8 @@
"package_type": "material", "package_type": "material",
"display_name": "FABtotum TPU Shore 98A", "display_name": "FABtotum TPU Shore 98A",
"description": "", "description": "",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=66", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=66",
"author": { "author": {
"author_id": "FABtotum", "author_id": "FABtotum",
@ -1161,8 +1161,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Fiberlogy HD PLA", "display_name": "Fiberlogy HD PLA",
"description": "With our HD PLA you have many more options. You can use this material in two ways. Choose the one you like best. You can use it as a normal PLA and get prints characterized by a very good adhesion between the layers and high precision. You can also make your prints acquire similar properties to that of ABS better impact resistance and high temperature resistance. All you need is an oven. Yes, an oven! By annealing our HD PLA in an oven, in accordance with the manual, you will avoid all the inconveniences of printing with ABS, such as unpleasant odour or hazardous fumes.", "description": "With our HD PLA you have many more options. You can use this material in two ways. Choose the one you like best. You can use it as a normal PLA and get prints characterized by a very good adhesion between the layers and high precision. You can also make your prints acquire similar properties to that of ABS better impact resistance and high temperature resistance. All you need is an oven. Yes, an oven! By annealing our HD PLA in an oven, in accordance with the manual, you will avoid all the inconveniences of printing with ABS, such as unpleasant odour or hazardous fumes.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "http://fiberlogy.com/en/fiberlogy-filaments/filament-hd-pla/", "website": "http://fiberlogy.com/en/fiberlogy-filaments/filament-hd-pla/",
"author": { "author": {
"author_id": "Fiberlogy", "author_id": "Fiberlogy",
@ -1178,8 +1178,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Filo3D PLA", "display_name": "Filo3D PLA",
"description": "Fast, safe and reliable printing. PLA is ideal for the fast and reliable printing of parts and prototypes with a great surface quality.", "description": "Fast, safe and reliable printing. PLA is ideal for the fast and reliable printing of parts and prototypes with a great surface quality.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://dagoma.fr", "website": "https://dagoma.fr",
"author": { "author": {
"author_id": "Dagoma", "author_id": "Dagoma",
@ -1195,8 +1195,8 @@
"package_type": "material", "package_type": "material",
"display_name": "IMADE3D JellyBOX PETG", "display_name": "IMADE3D JellyBOX PETG",
"description": "", "description": "",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "http://shop.imade3d.com/filament.html", "website": "http://shop.imade3d.com/filament.html",
"author": { "author": {
"author_id": "IMADE3D", "author_id": "IMADE3D",
@ -1212,8 +1212,8 @@
"package_type": "material", "package_type": "material",
"display_name": "IMADE3D JellyBOX PLA", "display_name": "IMADE3D JellyBOX PLA",
"description": "", "description": "",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "http://shop.imade3d.com/filament.html", "website": "http://shop.imade3d.com/filament.html",
"author": { "author": {
"author_id": "IMADE3D", "author_id": "IMADE3D",
@ -1229,8 +1229,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Octofiber PLA", "display_name": "Octofiber PLA",
"description": "PLA material from Octofiber.", "description": "PLA material from Octofiber.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://nl.octofiber.com/3d-printing-filament/pla.html", "website": "https://nl.octofiber.com/3d-printing-filament/pla.html",
"author": { "author": {
"author_id": "Octofiber", "author_id": "Octofiber",
@ -1246,8 +1246,8 @@
"package_type": "material", "package_type": "material",
"display_name": "PolyFlex™ PLA", "display_name": "PolyFlex™ PLA",
"description": "PolyFlex™ is a highly flexible yet easy to print 3D printing material. Featuring good elasticity and a large strain-to- failure, PolyFlex™ opens up a completely new realm of applications.", "description": "PolyFlex™ is a highly flexible yet easy to print 3D printing material. Featuring good elasticity and a large strain-to- failure, PolyFlex™ opens up a completely new realm of applications.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "http://www.polymaker.com/shop/polyflex/", "website": "http://www.polymaker.com/shop/polyflex/",
"author": { "author": {
"author_id": "Polymaker", "author_id": "Polymaker",
@ -1263,8 +1263,8 @@
"package_type": "material", "package_type": "material",
"display_name": "PolyMax™ PLA", "display_name": "PolyMax™ PLA",
"description": "PolyMax™ PLA is a 3D printing material with excellent mechanical properties and printing quality. PolyMax™ PLA has an impact resistance of up to nine times that of regular PLA, and better overall mechanical properties than ABS.", "description": "PolyMax™ PLA is a 3D printing material with excellent mechanical properties and printing quality. PolyMax™ PLA has an impact resistance of up to nine times that of regular PLA, and better overall mechanical properties than ABS.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "http://www.polymaker.com/shop/polymax/", "website": "http://www.polymaker.com/shop/polymax/",
"author": { "author": {
"author_id": "Polymaker", "author_id": "Polymaker",
@ -1280,8 +1280,8 @@
"package_type": "material", "package_type": "material",
"display_name": "PolyPlus™ PLA True Colour", "display_name": "PolyPlus™ PLA True Colour",
"description": "PolyPlus™ PLA is a premium PLA designed for all desktop FDM/FFF 3D printers. It is produced with our patented Jam-Free™ technology that ensures consistent extrusion and prevents jams.", "description": "PolyPlus™ PLA is a premium PLA designed for all desktop FDM/FFF 3D printers. It is produced with our patented Jam-Free™ technology that ensures consistent extrusion and prevents jams.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "http://www.polymaker.com/shop/polyplus-true-colour/", "website": "http://www.polymaker.com/shop/polyplus-true-colour/",
"author": { "author": {
"author_id": "Polymaker", "author_id": "Polymaker",
@ -1297,8 +1297,8 @@
"package_type": "material", "package_type": "material",
"display_name": "PolyWood™ PLA", "display_name": "PolyWood™ PLA",
"description": "PolyWood™ is a wood mimic printing material that contains no actual wood ensuring a clean Jam-Free™ printing experience.", "description": "PolyWood™ is a wood mimic printing material that contains no actual wood ensuring a clean Jam-Free™ printing experience.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "http://www.polymaker.com/shop/polywood/", "website": "http://www.polymaker.com/shop/polywood/",
"author": { "author": {
"author_id": "Polymaker", "author_id": "Polymaker",
@ -1314,8 +1314,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker ABS", "display_name": "Ultimaker ABS",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/abs", "website": "https://ultimaker.com/products/materials/abs",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1333,8 +1333,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker Breakaway", "display_name": "Ultimaker Breakaway",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/breakaway", "website": "https://ultimaker.com/products/materials/breakaway",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1352,8 +1352,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker CPE", "display_name": "Ultimaker CPE",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/abs", "website": "https://ultimaker.com/products/materials/abs",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1371,8 +1371,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker CPE+", "display_name": "Ultimaker CPE+",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/cpe", "website": "https://ultimaker.com/products/materials/cpe",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1390,8 +1390,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker Nylon", "display_name": "Ultimaker Nylon",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/abs", "website": "https://ultimaker.com/products/materials/abs",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1409,8 +1409,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker PC", "display_name": "Ultimaker PC",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/pc", "website": "https://ultimaker.com/products/materials/pc",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1428,8 +1428,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker PLA", "display_name": "Ultimaker PLA",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/abs", "website": "https://ultimaker.com/products/materials/abs",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1447,8 +1447,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker PP", "display_name": "Ultimaker PP",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/pp", "website": "https://ultimaker.com/products/materials/pp",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1466,8 +1466,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker PVA", "display_name": "Ultimaker PVA",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/abs", "website": "https://ultimaker.com/products/materials/abs",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1485,8 +1485,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker TPU 95A", "display_name": "Ultimaker TPU 95A",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.0", "package_version": "1.2.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/tpu-95a", "website": "https://ultimaker.com/products/materials/tpu-95a",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1504,8 +1504,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Ultimaker Tough PLA", "display_name": "Ultimaker Tough PLA",
"description": "Example package for material and quality profiles for Ultimaker materials.", "description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.0.2", "package_version": "1.0.3",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://ultimaker.com/products/materials/tough-pla", "website": "https://ultimaker.com/products/materials/tough-pla",
"author": { "author": {
"author_id": "UltimakerPackages", "author_id": "UltimakerPackages",
@ -1523,8 +1523,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Vertex Delta ABS", "display_name": "Vertex Delta ABS",
"description": "ABS material and quality files for the Delta Vertex K8800.", "description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://vertex3dprinter.eu", "website": "https://vertex3dprinter.eu",
"author": { "author": {
"author_id": "Velleman", "author_id": "Velleman",
@ -1540,8 +1540,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Vertex Delta PET", "display_name": "Vertex Delta PET",
"description": "ABS material and quality files for the Delta Vertex K8800.", "description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://vertex3dprinter.eu", "website": "https://vertex3dprinter.eu",
"author": { "author": {
"author_id": "Velleman", "author_id": "Velleman",
@ -1557,8 +1557,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Vertex Delta PLA", "display_name": "Vertex Delta PLA",
"description": "ABS material and quality files for the Delta Vertex K8800.", "description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://vertex3dprinter.eu", "website": "https://vertex3dprinter.eu",
"author": { "author": {
"author_id": "Velleman", "author_id": "Velleman",
@ -1574,8 +1574,8 @@
"package_type": "material", "package_type": "material",
"display_name": "Vertex Delta TPU", "display_name": "Vertex Delta TPU",
"description": "ABS material and quality files for the Delta Vertex K8800.", "description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.0", "package_version": "1.0.1",
"sdk_version": 5, "sdk_version": "6.0",
"website": "https://vertex3dprinter.eu", "website": "https://vertex3dprinter.eu",
"author": { "author": {
"author_id": "Velleman", "author_id": "Velleman",

View file

@ -3385,7 +3385,7 @@
"retraction_combing": "retraction_combing":
{ {
"label": "Combing Mode", "label": "Combing Mode",
"description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases.", "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill.",
"type": "enum", "type": "enum",
"options": "options":
{ {

View file

@ -16,7 +16,8 @@
{ {
"0": "ultimaker_original_plus_extruder_0" "0": "ultimaker_original_plus_extruder_0"
}, },
"firmware_file": "MarlinUltimaker-UMOP-{baudrate}.hex" "firmware_file": "MarlinUltimaker-UMOP-{baudrate}.hex",
"firmware_hbk_file": "MarlinUltimaker-UMOP-{baudrate}.hex"
}, },
"overrides": { "overrides": {

View file

@ -43,12 +43,13 @@ Button
contentItem: Row contentItem: Row
{ {
spacing: UM.Theme.getSize("narrow_margin").width
//Left side icon. Only displayed if !isIconOnRightSide. //Left side icon. Only displayed if !isIconOnRightSide.
UM.RecolorImage UM.RecolorImage
{ {
id: buttonIconLeft id: buttonIconLeft
source: "" source: ""
height: buttonText.height height: UM.Theme.getSize("action_button_icon").height
width: visible ? height : 0 width: visible ? height : 0
sourceSize.width: width sourceSize.width: width
sourceSize.height: height sourceSize.height: height
@ -76,7 +77,7 @@ Button
{ {
id: buttonIconRight id: buttonIconRight
source: buttonIconLeft.source source: buttonIconLeft.source
height: buttonText.height height: UM.Theme.getSize("action_button_icon").height
width: visible ? height : 0 width: visible ? height : 0
sourceSize.width: width sourceSize.width: width
sourceSize.height: height sourceSize.height: height

View file

@ -12,6 +12,12 @@ Item
{ {
id: widget id: widget
function requestWriteToDevice()
{
UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName,
{ "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats });
}
Cura.PrimaryButton Cura.PrimaryButton
{ {
id: saveToButton id: saveToButton
@ -32,9 +38,8 @@ Item
onClicked: onClicked:
{ {
forceActiveFocus(); forceActiveFocus()
UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, widget.requestWriteToDevice()
{ "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats });
} }
} }
@ -81,6 +86,7 @@ Item
delegate: Cura.ActionButton delegate: Cura.ActionButton
{ {
text: model.description text: model.description
visible: model.id != UM.OutputDeviceManager.activeDevice // Don't show the active device in the list
color: "transparent" color: "transparent"
cornerRadius: 0 cornerRadius: 0
hoverColor: UM.Theme.getColor("primary") hoverColor: UM.Theme.getColor("primary")
@ -88,6 +94,7 @@ Item
onClicked: onClicked:
{ {
UM.OutputDeviceManager.setActiveDevice(model.id) UM.OutputDeviceManager.setActiveDevice(model.id)
widget.requestWriteToDevice()
popup.close() popup.close()
} }
} }

View file

@ -41,7 +41,7 @@ Column
{ {
left: parent.left left: parent.left
right: printInformationPanel.left right: printInformationPanel.left
rightMargin: UM.Theme.getSize("thin_margin").height rightMargin: printInformationPanel.visible ? UM.Theme.getSize("thin_margin").width : 0
} }
Cura.IconWithText Cura.IconWithText
@ -119,9 +119,9 @@ Column
} }
height: UM.Theme.getSize("action_button").height height: UM.Theme.getSize("action_button").height
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@button", "Preview") text: catalog.i18nc("@button", "Preview")
tooltip: text
fixedWidthMode: true
onClicked: UM.Controller.setActiveStage("PreviewStage") onClicked: UM.Controller.setActiveStage("PreviewStage")
visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage"

View file

@ -12,10 +12,10 @@ UM.RecolorImage
id: widget id: widget
source: UM.Theme.getIcon("info") source: UM.Theme.getIcon("info")
width: UM.Theme.getSize("section_icon").width width: visible ? UM.Theme.getSize("section_icon").width : 0
height: UM.Theme.getSize("section_icon").height height: UM.Theme.getSize("section_icon").height
color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") color: UM.Theme.getColor("icon")
MouseArea MouseArea
{ {

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