Merge branch '3.0' of github.com:Ultimaker/Cura

This commit is contained in:
Jaime van Kessel 2017-09-27 13:02:21 +02:00
commit e87f30cf09
30 changed files with 204 additions and 178 deletions

View file

@ -10,7 +10,6 @@ from PyQt5.QtWidgets import QSplashScreen
from UM.Resources import Resources from UM.Resources import Resources
from UM.Application import Application from UM.Application import Application
class CuraSplashScreen(QSplashScreen): class CuraSplashScreen(QSplashScreen):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -61,7 +60,7 @@ class CuraSplashScreen(QSplashScreen):
# draw version text # draw version text
font = QFont() # Using system-default font here font = QFont() # Using system-default font here
font.setPointSize(28) font.setPixelSize(37)
painter.setFont(font) painter.setFont(font)
painter.drawText(220, 66, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0]) painter.drawText(220, 66, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0])
if len(version) > 1: if len(version) > 1:
@ -81,7 +80,7 @@ class CuraSplashScreen(QSplashScreen):
# draw message text # draw message text
if self._current_message: if self._current_message:
font = QFont() # Using system-default font here font = QFont() # Using system-default font here
font.setPointSize(10) font.setPixelSize(13)
pen = QPen() pen = QPen()
pen.setColor(QColor(255, 255, 255, 255)) pen.setColor(QColor(255, 255, 255, 255))
painter.setPen(pen) painter.setPen(pen)
@ -107,5 +106,3 @@ class CuraSplashScreen(QSplashScreen):
self._to_stop = True self._to_stop = True
self._change_timer.stop() self._change_timer.stop()
super().close() super().close()

View file

@ -506,7 +506,7 @@ class ExtruderManager(QObject):
result.extend(self.getActiveExtruderStacks()) result.extend(self.getActiveExtruderStacks())
return result return result
## Returns the list of active extruder stacks. ## Returns the list of active extruder stacks, taking into account the machine extruder count.
# #
# \return \type{List[ContainerStack]} a list of # \return \type{List[ContainerStack]} a list of
def getActiveExtruderStacks(self) -> List["ExtruderStack"]: def getActiveExtruderStacks(self) -> List["ExtruderStack"]:
@ -516,7 +516,8 @@ class ExtruderManager(QObject):
if global_stack and global_stack.getId() in self._extruder_trains: if global_stack and global_stack.getId() in self._extruder_trains:
for extruder in sorted(self._extruder_trains[global_stack.getId()]): for extruder in sorted(self._extruder_trains[global_stack.getId()]):
result.append(self._extruder_trains[global_stack.getId()][extruder]) result.append(self._extruder_trains[global_stack.getId()][extruder])
return result
return result[:global_stack.getProperty("machine_extruder_count", "value")]
def __globalContainerStackChanged(self) -> None: def __globalContainerStackChanged(self) -> None:
global_container_stack = Application.getInstance().getGlobalContainerStack() global_container_stack = Application.getInstance().getGlobalContainerStack()

View file

@ -92,13 +92,22 @@ class ProfilesModel(InstanceContainersModel):
if global_container_stack is None: if global_container_stack is None:
return return
# Detecting if the machine has multiple extrusion
multiple_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
# Get the list of extruders and place the selected extruder at the front of the list. # Get the list of extruders and place the selected extruder at the front of the list.
extruder_manager = ExtruderManager.getInstance() extruder_manager = ExtruderManager.getInstance()
active_extruder = extruder_manager.getActiveExtruderStack() active_extruder = extruder_manager.getActiveExtruderStack()
extruder_stacks = extruder_manager.getActiveExtruderStacks() extruder_stacks = extruder_manager.getActiveExtruderStacks()
if active_extruder in extruder_stacks: if extruder_stacks:
extruder_stacks.remove(active_extruder) if multiple_extrusion:
extruder_stacks = [active_extruder] + extruder_stacks # Place the active extruder at the front of the list.
if active_extruder in extruder_stacks:
extruder_stacks.remove(active_extruder)
extruder_stacks = [active_extruder] + extruder_stacks
else:
# The active extruder is the first in the list and only the active extruder is use to compute the usable qualities
active_extruder = None
extruder_stacks = []
# Get a list of usable/available qualities for this machine and material # Get a list of usable/available qualities for this machine and material
qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack,

View file

@ -26,15 +26,21 @@ class QualityAndUserProfilesModel(ProfilesModel):
quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition) quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
# Detecting if the machine has multiple extrusion # Detecting if the machine has multiple extrusion
multiple_extrusion = False multiple_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
# Get the list of extruders and place the selected extruder at the front of the list. # Get the list of extruders
extruder_manager = ExtruderManager.getInstance() extruder_manager = ExtruderManager.getInstance()
active_extruder = extruder_manager.getActiveExtruderStack() active_extruder = extruder_manager.getActiveExtruderStack()
extruder_stacks = extruder_manager.getActiveExtruderStacks() extruder_stacks = extruder_manager.getActiveExtruderStacks()
if active_extruder in extruder_stacks: if extruder_stacks:
multiple_extrusion = True if multiple_extrusion:
extruder_stacks.remove(active_extruder) # Place the active extruder at the front of the list.
extruder_stacks = [active_extruder] + extruder_stacks if active_extruder in extruder_stacks:
extruder_stacks.remove(active_extruder)
extruder_stacks = [active_extruder] + extruder_stacks
else:
# The active extruder is the first in the list and only the active extruder is use to compute the usable qualities
active_extruder = None
extruder_stacks = []
# Fetch the list of useable qualities across all extruders. # Fetch the list of useable qualities across all extruders.
# The actual list of quality profiles come from the first extruder in the extruder list. # The actual list of quality profiles come from the first extruder in the extruder list.
@ -49,6 +55,6 @@ class QualityAndUserProfilesModel(ProfilesModel):
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") == active_extruder.definition.getId()] filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") == active_extruder.definition.getId()]
else: else:
# If not, the quality changes of the global stack are selected # If not, the quality changes of the global stack are selected
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set] filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") is None]
return quality_list + filtered_quality_changes return quality_list + filtered_quality_changes

View file

@ -26,15 +26,21 @@ class UserProfilesModel(ProfilesModel):
quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition) quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
# Detecting if the machine has multiple extrusion # Detecting if the machine has multiple extrusion
multiple_extrusion = False multiple_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
# Get the list of extruders and place the selected extruder at the front of the list. # Get the list of extruders and place the selected extruder at the front of the list.
extruder_manager = ExtruderManager.getInstance() extruder_manager = ExtruderManager.getInstance()
active_extruder = extruder_manager.getActiveExtruderStack() active_extruder = extruder_manager.getActiveExtruderStack()
extruder_stacks = extruder_manager.getActiveExtruderStacks() extruder_stacks = extruder_manager.getActiveExtruderStacks()
if active_extruder in extruder_stacks: if extruder_stacks:
multiple_extrusion = True if multiple_extrusion:
extruder_stacks.remove(active_extruder) # Place the active extruder at the front of the list.
extruder_stacks = [active_extruder] + extruder_stacks if active_extruder in extruder_stacks:
extruder_stacks.remove(active_extruder)
extruder_stacks = [active_extruder] + extruder_stacks
else:
# The active extruder is the first in the list and only the active extruder is use to compute the usable qualities
active_extruder = None
extruder_stacks = []
# Fetch the list of useable qualities across all extruders. # Fetch the list of useable qualities across all extruders.
# The actual list of quality profiles come from the first extruder in the extruder list. # The actual list of quality profiles come from the first extruder in the extruder list.
@ -49,6 +55,6 @@ class UserProfilesModel(ProfilesModel):
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") == active_extruder.definition.getId()] filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") == active_extruder.definition.getId()]
else: else:
# If not, the quality changes of the global stack are selected # If not, the quality changes of the global stack are selected
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set] filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") is None]
return filtered_quality_changes return filtered_quality_changes

View file

@ -12,11 +12,13 @@ UM.Dialog
{ {
title: catalog.i18nc("@title:window", "Open Project") title: catalog.i18nc("@title:window", "Open Project")
width: 500 minimumWidth: 500 * screenScaleFactor
height: 400 minimumHeight: 400 * screenScaleFactor
width: minimumWidth
height: minumumHeight
property int comboboxHeight: 15 property int comboboxHeight: 15 * screenScaleFactor
property int spacerHeight: 10 property int spacerHeight: 10 * screenScaleFactor
onClosing: manager.notifyClosed() onClosing: manager.notifyClosed()
onVisibleChanged: onVisibleChanged:
@ -31,7 +33,7 @@ UM.Dialog
Item Item
{ {
anchors.fill: parent anchors.fill: parent
anchors.margins: 20 anchors.margins: 20 * screenScaleFactor
UM.I18nCatalog UM.I18nCatalog
{ {
@ -59,7 +61,7 @@ UM.Dialog
Column Column
{ {
anchors.fill: parent anchors.fill: parent
spacing: 2 spacing: 2 * screenScaleFactor
Label Label
{ {
id: titleLabel id: titleLabel
@ -373,7 +375,7 @@ UM.Dialog
enabled: true enabled: true
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: ok_button.left anchors.right: ok_button.left
anchors.rightMargin:2 anchors.rightMargin: 2 * screenScaleFactor
} }
Button Button
{ {

View file

@ -39,7 +39,9 @@ class FirmwareUpdateCheckerJob(Job):
return return
try: try:
request = urllib.request.Request(self._url) application_name = Application.getInstance().getApplicationName()
headers = {"User-Agent": "%s - %s" % (application_name, Application.getInstance().getVersion())}
request = urllib.request.Request(self._url, headers = headers)
current_version_file = urllib.request.urlopen(request) current_version_file = urllib.request.urlopen(request)
reader = codecs.getreader("utf-8") reader = codecs.getreader("utf-8")

View file

@ -10,11 +10,11 @@ import UM 1.1 as UM
UM.Dialog UM.Dialog
{ {
width: 350 * Screen.devicePixelRatio; width: minimumWidth;
minimumWidth: 350 * Screen.devicePixelRatio; minimumWidth: 350 * screenScaleFactor;
height: 250 * Screen.devicePixelRatio; height: minimumHeight;
minimumHeight: 250 * Screen.devicePixelRatio; minimumHeight: 250 * screenScaleFactor;
title: catalog.i18nc("@title:window", "Convert Image...") title: catalog.i18nc("@title:window", "Convert Image...")
@ -23,8 +23,8 @@ UM.Dialog
UM.I18nCatalog{id: catalog; name:"cura"} UM.I18nCatalog{id: catalog; name:"cura"}
anchors.fill: parent; anchors.fill: parent;
Layout.fillWidth: true Layout.fillWidth: true
columnSpacing: 16 columnSpacing: 16 * screenScaleFactor
rowSpacing: 4 rowSpacing: 4 * screenScaleFactor
columns: 1 columns: 1
UM.TooltipArea { UM.TooltipArea {
@ -36,7 +36,7 @@ UM.Dialog
Label { Label {
text: catalog.i18nc("@action:label","Height (mm)") text: catalog.i18nc("@action:label","Height (mm)")
width: 150 width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
@ -44,7 +44,7 @@ UM.Dialog
id: peak_height id: peak_height
objectName: "Peak_Height" objectName: "Peak_Height"
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: -500; top: 500;} validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: -500; top: 500;}
width: 180 width: 180 * screenScaleFactor
onTextChanged: { manager.onPeakHeightChanged(text) } onTextChanged: { manager.onPeakHeightChanged(text) }
} }
} }
@ -59,7 +59,7 @@ UM.Dialog
Label { Label {
text: catalog.i18nc("@action:label","Base (mm)") text: catalog.i18nc("@action:label","Base (mm)")
width: 150 width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
@ -67,7 +67,7 @@ UM.Dialog
id: base_height id: base_height
objectName: "Base_Height" objectName: "Base_Height"
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 0; top: 500;} validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 0; top: 500;}
width: 180 width: 180 * screenScaleFactor
onTextChanged: { manager.onBaseHeightChanged(text) } onTextChanged: { manager.onBaseHeightChanged(text) }
} }
} }
@ -82,7 +82,7 @@ UM.Dialog
Label { Label {
text: catalog.i18nc("@action:label","Width (mm)") text: catalog.i18nc("@action:label","Width (mm)")
width: 150 width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
@ -91,7 +91,7 @@ UM.Dialog
objectName: "Width" objectName: "Width"
focus: true focus: true
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;} validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;}
width: 180 width: 180 * screenScaleFactor
onTextChanged: { manager.onWidthChanged(text) } onTextChanged: { manager.onWidthChanged(text) }
} }
} }
@ -106,7 +106,7 @@ UM.Dialog
Label { Label {
text: catalog.i18nc("@action:label","Depth (mm)") text: catalog.i18nc("@action:label","Depth (mm)")
width: 150 width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
TextField { TextField {
@ -114,7 +114,7 @@ UM.Dialog
objectName: "Depth" objectName: "Depth"
focus: true focus: true
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;} validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;}
width: 180 width: 180 * screenScaleFactor
onTextChanged: { manager.onDepthChanged(text) } onTextChanged: { manager.onDepthChanged(text) }
} }
} }
@ -130,14 +130,14 @@ UM.Dialog
//Empty label so 2 column layout works. //Empty label so 2 column layout works.
Label { Label {
text: "" text: ""
width: 150 width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
ComboBox { ComboBox {
id: image_color_invert id: image_color_invert
objectName: "Image_Color_Invert" objectName: "Image_Color_Invert"
model: [ catalog.i18nc("@item:inlistbox","Lighter is higher"), catalog.i18nc("@item:inlistbox","Darker is higher") ] model: [ catalog.i18nc("@item:inlistbox","Lighter is higher"), catalog.i18nc("@item:inlistbox","Darker is higher") ]
width: 180 width: 180 * screenScaleFactor
onCurrentIndexChanged: { manager.onImageColorInvertChanged(currentIndex) } onCurrentIndexChanged: { manager.onImageColorInvertChanged(currentIndex) }
} }
} }
@ -152,13 +152,13 @@ UM.Dialog
Label { Label {
text: catalog.i18nc("@action:label","Smoothing") text: catalog.i18nc("@action:label","Smoothing")
width: 150 width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Item { Item {
width: 180 width: 180 * screenScaleFactor
height: 20 height: 20 * screenScaleFactor
Layout.fillWidth: true Layout.fillWidth: true
Slider { Slider {

View file

@ -111,7 +111,7 @@ Item
visible: !UM.LayerView.compatibilityMode visible: !UM.LayerView.compatibilityMode
style: UM.Theme.styles.combobox style: UM.Theme.styles.combobox
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 10 anchors.rightMargin: 10 * screenScaleFactor
onActivated: onActivated:
{ {
@ -353,7 +353,7 @@ Item
property real minimumRangeHandleSize: UM.Theme.getSize("slider_handle").width / 2 property real minimumRangeHandleSize: UM.Theme.getSize("slider_handle").width / 2
property real trackThickness: UM.Theme.getSize("slider_groove").width property real trackThickness: UM.Theme.getSize("slider_groove").width
property real trackRadius: trackThickness / 2 property real trackRadius: trackThickness / 2
property real trackBorderWidth: UM.Theme.getSize("default_lining").width / 2 property real trackBorderWidth: UM.Theme.getSize("default_lining").width
property color upperHandleColor: UM.Theme.getColor("slider_handle") property color upperHandleColor: UM.Theme.getColor("slider_handle")
property color lowerHandleColor: UM.Theme.getColor("slider_handle") property color lowerHandleColor: UM.Theme.getColor("slider_handle")
property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill") property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill")
@ -602,7 +602,7 @@ Item
anchors.leftMargin: UM.Theme.getSize("default_margin").width / 2; anchors.leftMargin: UM.Theme.getSize("default_margin").width / 2;
anchors.verticalCenter: parent.verticalCenter; anchors.verticalCenter: parent.verticalCenter;
width: Math.max(UM.Theme.getSize("line").width * maxValue.length + 2, 20); width: Math.max(UM.Theme.getSize("line").width * maxValue.length + 2 * screenScaleFactor, 20 * screenScaleFactor);
style: TextFieldStyle style: TextFieldStyle
{ {
textColor: UM.Theme.getColor("setting_control_text"); textColor: UM.Theme.getColor("setting_control_text");

View file

@ -30,7 +30,7 @@ Item {
{ {
// This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar. // This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
// It kinda looks ugly otherwise (big panel, no content on it) // It kinda looks ugly otherwise (big panel, no content on it)
property int maximumHeight: 200 * Screen.devicePixelRatio property int maximumHeight: 200 * screenScaleFactor
height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight) height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight)
ScrollView ScrollView
@ -246,7 +246,7 @@ Item {
id: settingPickDialog id: settingPickDialog
title: catalog.i18nc("@title:window", "Select Settings to Customize for this model") title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
width: Screen.devicePixelRatio * 360; width: screenScaleFactor * 360;
property string labelFilter: "" property string labelFilter: ""

View file

@ -9,10 +9,10 @@ UM.Dialog
id: base id: base
title: catalog.i18nc("@title:window", "Find & Update plugins") title: catalog.i18nc("@title:window", "Find & Update plugins")
width: 600 * Screen.devicePixelRatio width: 600 * screenScaleFactor
height: 450 * Screen.devicePixelRatio height: 450 * screenScaleFactor
minimumWidth: 350 * Screen.devicePixelRatio minimumWidth: 350 * screenScaleFactor
minimumHeight: 350 * Screen.devicePixelRatio minimumHeight: 350 * screenScaleFactor
Item Item
{ {
anchors.fill: parent anchors.fill: parent

View file

@ -298,8 +298,8 @@ Cura.MachineAction
title: catalog.i18nc("@title:window", "Printer Address") title: catalog.i18nc("@title:window", "Printer Address")
minimumWidth: 400 * Screen.devicePixelRatio minimumWidth: 400 * screenScaleFactor
minimumHeight: 120 * Screen.devicePixelRatio minimumHeight: 120 * screenScaleFactor
width: minimumWidth width: minimumWidth
height: minimumHeight height: minimumHeight

View file

@ -205,16 +205,16 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
self._authentication_requested_message.setProgress(self._authentication_counter / self._max_authentication_counter * 100) self._authentication_requested_message.setProgress(self._authentication_counter / self._max_authentication_counter * 100)
if self._authentication_counter > self._max_authentication_counter: if self._authentication_counter > self._max_authentication_counter:
self._authentication_timer.stop() self._authentication_timer.stop()
Logger.log("i", "Authentication timer ended. Setting authentication to denied") Logger.log("i", "Authentication timer ended. Setting authentication to denied for printer: %s" % self._key)
self.setAuthenticationState(AuthState.AuthenticationDenied) self.setAuthenticationState(AuthState.AuthenticationDenied)
def _onAuthenticationRequired(self, reply, authenticator): def _onAuthenticationRequired(self, reply, authenticator):
if self._authentication_id is not None and self._authentication_key is not None: if self._authentication_id is not None and self._authentication_key is not None:
Logger.log("d", "Authentication was required. Setting up authenticator with ID %s and key %s", self._authentication_id, self._getSafeAuthKey()) Logger.log("d", "Authentication was required for printer: %s. Setting up authenticator with ID %s and key %s", self._key, self._authentication_id, self._getSafeAuthKey())
authenticator.setUser(self._authentication_id) authenticator.setUser(self._authentication_id)
authenticator.setPassword(self._authentication_key) authenticator.setPassword(self._authentication_key)
else: else:
Logger.log("d", "No authentication is available to use, but we did got a request for it.") Logger.log("d", "No authentication is available to use for %s, but we did got a request for it.", self._key)
def getProperties(self): def getProperties(self):
return self._properties return self._properties
@ -369,6 +369,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
if auth_state == self._authentication_state: if auth_state == self._authentication_state:
return # Nothing to do here. return # Nothing to do here.
Logger.log("d", "Attempting to update auth state from %s to %s for printer %s" % (self._authentication_state, auth_state, self._key))
if auth_state == AuthState.AuthenticationRequested: if auth_state == AuthState.AuthenticationRequested:
Logger.log("d", "Authentication state changed to authentication requested.") Logger.log("d", "Authentication state changed to authentication requested.")
self.setAcceptsCommands(False) self.setAcceptsCommands(False)
@ -421,6 +423,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
@pyqtSlot() @pyqtSlot()
def requestAuthentication(self, message_id = None, action_id = "Retry"): def requestAuthentication(self, message_id = None, action_id = "Retry"):
if action_id == "Request" or action_id == "Retry": if action_id == "Request" or action_id == "Retry":
Logger.log("d", "Requestion authentication for %s due to action %s" % (self._key, action_id))
self._authentication_failed_message.hide() self._authentication_failed_message.hide()
self._not_authenticated_message.hide() self._not_authenticated_message.hide()
self._authentication_state = AuthState.NotAuthenticated self._authentication_state = AuthState.NotAuthenticated
@ -652,7 +655,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
return return
elif self._authentication_state != AuthState.Authenticated: elif self._authentication_state != AuthState.Authenticated:
self._not_authenticated_message.show() self._not_authenticated_message.show()
Logger.log("d", "Attempting to perform an action without authentication. Auth state is %s", self._authentication_state) Logger.log("d", "Attempting to perform an action without authentication for printer %s. Auth state is %s", self._key, self._authentication_state)
return return
Application.getInstance().showPrintMonitor.emit(True) Application.getInstance().showPrintMonitor.emit(True)
@ -780,7 +783,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
if self._authentication_id is None and self._authentication_key is None: if self._authentication_id is None and self._authentication_key is None:
Logger.log("d", "No authentication found in metadata.") Logger.log("d", "No authentication found in metadata.")
else: else:
Logger.log("d", "Loaded authentication id %s and key %s from the metadata entry", self._authentication_id, self._getSafeAuthKey()) Logger.log("d", "Loaded authentication id %s and key %s from the metadata entry for printer %s", self._authentication_id, self._getSafeAuthKey(), self._key)
self._update_timer.start() self._update_timer.start()
@ -1084,7 +1087,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
if status_code == 401: if status_code == 401:
if self._authentication_state != AuthState.AuthenticationRequested: if self._authentication_state != AuthState.AuthenticationRequested:
# Only request a new authentication when we have not already done so. # Only request a new authentication when we have not already done so.
Logger.log("i", "Not authenticated (Current auth state is %s). Attempting to request authentication", self._authentication_state ) Logger.log("i", "Not authenticated (Current auth state is %s). Attempting to request authentication for printer %s", self._authentication_state, self._key )
self._requestAuthentication() self._requestAuthentication()
elif status_code == 403: elif status_code == 403:
# If we already had an auth (eg; didn't request one), we only need a single 403 to see it as denied. # If we already had an auth (eg; didn't request one), we only need a single 403 to see it as denied.
@ -1139,7 +1142,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
return return
global_container_stack = Application.getInstance().getGlobalContainerStack() global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack: # Remove any old data. if global_container_stack: # Remove any old data.
Logger.log("d", "Removing old network authentication data as a new one was requested.") Logger.log("d", "Removing old network authentication data for %s as a new one was requested.", self._key)
global_container_stack.removeMetaDataEntry("network_authentication_key") global_container_stack.removeMetaDataEntry("network_authentication_key")
global_container_stack.removeMetaDataEntry("network_authentication_id") global_container_stack.removeMetaDataEntry("network_authentication_id")
Application.getInstance().saveStack(global_container_stack) # Force saving so we don't keep wrong auth data. Application.getInstance().saveStack(global_container_stack) # Force saving so we don't keep wrong auth data.

View file

@ -11,10 +11,10 @@ UM.Dialog
{ {
id: base; id: base;
width: 500 * Screen.devicePixelRatio; width: minimumWidth;
minimumWidth: 500 * Screen.devicePixelRatio; minimumWidth: 500 * screenScaleFactor;
height: 100 * Screen.devicePixelRatio; height: minimumHeight;
minimumHeight: 100 * Screen.devicePixelRatio; minimumHeight: 100 * screenScaleFactor;
visible: true; visible: true;
modality: Qt.ApplicationModal; modality: Qt.ApplicationModal;

View file

@ -3391,46 +3391,6 @@
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
}, },
"support_skip_some_zags": {
"label": "Break Up Support In Chunks",
"description": "Skip some support line connections to make the support structure easier to break away. This setting is applicable to the Zig Zag support infill pattern.",
"type": "bool",
"default_value": false,
"enabled": "support_enable and (support_pattern == 'zigzag')",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children": {
"support_skip_zag_per_mm": {
"label": "Support Chunk Size",
"description": "Leave out a connection between support lines once every N millimeter to make the support structure easier to break away.",
"type": "float",
"unit": "mm",
"default_value": 20,
"minimum_value": "0",
"minimum_value_warning": "support_line_distance",
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children": {
"support_zag_skip_count": {
"label": "Support Chunk Line Count",
"description": "Skip one in every N connection lines to make the support structure easier to break away.",
"type": "int",
"default_value": 5,
"value": "round(support_skip_zag_per_mm / support_line_distance)",
"minimum_value": "1",
"minimum_value_warning": "3",
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
}
}
},
"support_infill_rate": "support_infill_rate":
{ {
"label": "Support Density", "label": "Support Density",
@ -5050,6 +5010,46 @@
"default_value": false, "default_value": false,
"settable_per_mesh": true "settable_per_mesh": true
}, },
"support_skip_some_zags": {
"label": "Break Up Support In Chunks",
"description": "Skip some support line connections to make the support structure easier to break away. This setting is applicable to the Zig Zag support infill pattern.",
"type": "bool",
"default_value": false,
"enabled": "support_enable and (support_pattern == 'zigzag')",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children": {
"support_skip_zag_per_mm": {
"label": "Support Chunk Size",
"description": "Leave out a connection between support lines once every N millimeter to make the support structure easier to break away.",
"type": "float",
"unit": "mm",
"default_value": 20,
"minimum_value": "0",
"minimum_value_warning": "support_line_distance",
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children": {
"support_zag_skip_count": {
"label": "Support Chunk Line Count",
"description": "Skip one in every N connection lines to make the support structure easier to break away.",
"type": "int",
"default_value": 5,
"value": "round(support_skip_zag_per_mm / support_line_distance)",
"minimum_value": "1",
"minimum_value_warning": "3",
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
}
}
},
"draft_shield_enabled": "draft_shield_enabled":
{ {
"label": "Enable Draft Shield", "label": "Enable Draft Shield",

View file

@ -14,8 +14,8 @@ UM.Dialog
//: About dialog title //: About dialog title
title: catalog.i18nc("@title:window","About Cura") title: catalog.i18nc("@title:window","About Cura")
minimumWidth: 500 minimumWidth: 500 * screenScaleFactor
minimumHeight: 650 minimumHeight: 650 * screenScaleFactor
width: minimumWidth width: minimumWidth
height: minimumHeight height: minimumHeight

View file

@ -18,8 +18,8 @@ UM.Dialog
id: base id: base
title: catalog.i18nc("@title:window", "Open project file") title: catalog.i18nc("@title:window", "Open project file")
width: 450 width: 450 * screenScaleFactor
height: 150 height: 150 * screenScaleFactor
maximumHeight: height maximumHeight: height
maximumWidth: width maximumWidth: width
@ -61,10 +61,10 @@ UM.Dialog
Column Column
{ {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 20 anchors.leftMargin: 20 * screenScaleFactor
anchors.rightMargin: 20 anchors.rightMargin: 20 * screenScaleFactor
anchors.bottomMargin: 20 anchors.bottomMargin: 20 * screenScaleFactor
spacing: 10 spacing: 10 * screenScaleFactor
Label Label
{ {

View file

@ -14,8 +14,8 @@ UM.Dialog
id: base id: base
title: catalog.i18nc("@title:window", "Discard or Keep changes") title: catalog.i18nc("@title:window", "Discard or Keep changes")
width: 800 width: 800 * screenScaleFactor
height: 400 height: 400 * screenScaleFactor
property var changesModel: Cura.UserChangesModel{ id: userChangesModel} property var changesModel: Cura.UserChangesModel{ id: userChangesModel}
onVisibilityChanged: onVisibilityChanged:
{ {

View file

@ -67,7 +67,7 @@ Button
height: UM.Theme.getSize("extruder_button_material").height height: UM.Theme.getSize("extruder_button_material").height
radius: width / 2 radius: width / 2
border.width: 1 border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("extruder_button_material_border") border.color: UM.Theme.getColor("extruder_button_material_border")
opacity: !base.enabled ? 0.2 : 1.0 opacity: !base.enabled ? 0.2 : 1.0

View file

@ -17,8 +17,8 @@ UM.Dialog
id: base id: base
title: catalog.i18nc("@title:window", "Open file(s)") title: catalog.i18nc("@title:window", "Open file(s)")
width: 420 width: 420 * screenScaleFactor
height: 170 height: 170 * screenScaleFactor
maximumHeight: height maximumHeight: height
maximumWidth: width maximumWidth: width
@ -28,7 +28,7 @@ UM.Dialog
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal; modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
property var fileUrls: [] property var fileUrls: []
property int spacerHeight: 10 property int spacerHeight: 10 * screenScaleFactor
function loadProjectFile(projectFile) function loadProjectFile(projectFile)
{ {
@ -52,12 +52,12 @@ UM.Dialog
Column Column
{ {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 20 anchors.leftMargin: 20 * screenScaleFactor
anchors.rightMargin: 20 anchors.rightMargin: 20 * screenScaleFactor
anchors.bottomMargin: 20 anchors.bottomMargin: 20 * screenScaleFactor
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
spacing: 10 spacing: 10 * screenScaleFactor
Label Label
{ {

View file

@ -513,7 +513,7 @@ UM.PreferencesPage
Column Column
{ {
spacing: 4 spacing: 4 * screenScaleFactor
Label Label
{ {
@ -523,7 +523,7 @@ UM.PreferencesPage
ComboBox ComboBox
{ {
id: choiceOnOpenProjectDropDownButton id: choiceOnOpenProjectDropDownButton
width: 200 width: 200 * screenScaleFactor
model: ListModel model: ListModel
{ {
@ -572,7 +572,7 @@ UM.PreferencesPage
Column Column
{ {
spacing: 4 spacing: 4 * screenScaleFactor
Label Label
{ {
@ -583,7 +583,7 @@ UM.PreferencesPage
ComboBox ComboBox
{ {
id: choiceOnProfileOverrideDropDownButton id: choiceOnProfileOverrideDropDownButton
width: 200 width: 200 * screenScaleFactor
model: ListModel model: ListModel
{ {

View file

@ -91,7 +91,7 @@ UM.ManagementPage
Item Item
{ {
width: childrenRect.width + 2 width: childrenRect.width + 2 * screenScaleFactor
height: childrenRect.height height: childrenRect.height
Button Button
{ {
@ -112,8 +112,6 @@ UM.ManagementPage
{ {
id: actionDialog id: actionDialog
property var content property var content
minimumWidth: 350
minimumHeight: 350
onContentChanged: onContentChanged:
{ {
contents = content; contents = content;
@ -257,8 +255,8 @@ UM.ManagementPage
UM.RenameDialog UM.RenameDialog
{ {
id: renameDialog; id: renameDialog;
width: 300 width: 300 * screenScaleFactor
height: 150 height: 150 * screenScaleFactor
object: base.currentItem && base.currentItem.name ? base.currentItem.name : ""; object: base.currentItem && base.currentItem.name ? base.currentItem.name : "";
property var machine_name_validator: Cura.MachineNameValidator { } property var machine_name_validator: Cura.MachineNameValidator { }
validName: renameDialog.newName.match(renameDialog.machine_name_validator.machineNameRegex) != null; validName: renameDialog.newName.match(renameDialog.machine_name_validator.machineNameRegex) != null;

View file

@ -119,8 +119,8 @@ SettingItem
UM.RecolorImage { UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: parent.width/2.5 width: parent.width / 2.5
height: parent.height/2.5 height: parent.height / 2.5
sourceSize.width: width sourceSize.width: width
sourceSize.height: width sourceSize.height: width
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text");

View file

@ -86,8 +86,8 @@ SettingItem
source: UM.Theme.getIcon("arrow_bottom") source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width + 5 sourceSize.width: width + 5 * screenScaleFactor
sourceSize.height: width + 5 sourceSize.height: width + 5 * screenScaleFactor
color: UM.Theme.getColor("setting_control_text"); color: UM.Theme.getColor("setting_control_text");

View file

@ -137,8 +137,8 @@ SettingItem
source: UM.Theme.getIcon("arrow_bottom") source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width + 5 sourceSize.width: width + 5 * screenScaleFactor
sourceSize.height: width + 5 sourceSize.height: width + 5 * screenScaleFactor
color: UM.Theme.getColor("setting_control_text") color: UM.Theme.getColor("setting_control_text")
} }

View file

@ -156,8 +156,8 @@ SettingItem
source: UM.Theme.getIcon("arrow_bottom") source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width + 5 sourceSize.width: width + 5 * screenScaleFactor
sourceSize.height: width + 5 sourceSize.height: width + 5 * screenScaleFactor
color: UM.Theme.getColor("setting_control_text") color: UM.Theme.getColor("setting_control_text")
} }

View file

@ -213,7 +213,7 @@ Item
{ {
id: groovechildrect id: groovechildrect
width: base.width * 0.55 width: base.width * 0.55
height: 2 height: 2 * screenScaleFactor
color: UM.Theme.getColor("quality_slider_unavailable") color: UM.Theme.getColor("quality_slider_unavailable")
anchors.verticalCenter: qualitySlider.verticalCenter anchors.verticalCenter: qualitySlider.verticalCenter
x: 0 x: 0
@ -229,8 +229,8 @@ Item
{ {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
width: 1 width: 1 * screenScaleFactor
height: 6 height: 6 * screenScaleFactor
y: 0 y: 0
x: qualityModel.qualitySliderStepWidth * index x: qualityModel.qualitySliderStepWidth * index
} }
@ -260,18 +260,18 @@ Item
{ {
//Draw Available line //Draw Available line
groove: Rectangle { groove: Rectangle {
implicitHeight: 2 implicitHeight: 2 * screenScaleFactor
color: UM.Theme.getColor("quality_slider_available") color: UM.Theme.getColor("quality_slider_available")
radius: 1 radius: 1 * screenScaleFactor
} }
handle: Item { handle: Item {
Rectangle { Rectangle {
id: qualityhandleButton id: qualityhandleButton
anchors.centerIn: parent anchors.centerIn: parent
color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
implicitWidth: 10 implicitWidth: 10 * screenScaleFactor
implicitHeight: 10 implicitHeight: 10 * screenScaleFactor
radius: 10 radius: 10 * screenScaleFactor
} }
} }
} }
@ -372,7 +372,7 @@ Item
//anchors.top: parent.top //anchors.top: parent.top
anchors.left: infillSlider.left anchors.left: infillSlider.left
anchors.leftMargin: (infillSlider.value / infillSlider.stepSize) * (infillSlider.width / (infillSlider.maximumValue / infillSlider.stepSize)) - 10 anchors.leftMargin: (infillSlider.value / infillSlider.stepSize) * (infillSlider.width / (infillSlider.maximumValue / infillSlider.stepSize)) - 10 * screenScaleFactor
anchors.right: parent.right anchors.right: parent.right
text: infillSlider.value + "%" text: infillSlider.value + "%"
@ -413,8 +413,8 @@ Item
groove: Rectangle { groove: Rectangle {
id: groove id: groove
implicitWidth: 200 implicitWidth: 200 * screenScaleFactor
implicitHeight: 2 implicitHeight: 2 * screenScaleFactor
color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
radius: 1 radius: 1
} }
@ -424,9 +424,9 @@ Item
id: handleButton id: handleButton
anchors.centerIn: parent anchors.centerIn: parent
color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
implicitWidth: 10 implicitWidth: 10 * screenScaleFactor
implicitHeight: 10 implicitHeight: 10 * screenScaleFactor
radius: 10 radius: 10 * screenScaleFactor
} }
} }
@ -436,8 +436,8 @@ Item
Rectangle { Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
width: 1 width: 1 * screenScaleFactor
height: 6 height: 6 * screenScaleFactor
y: 0 y: 0
x: styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1)) x: styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))
} }
@ -489,7 +489,7 @@ Item
UM.RecolorImage { UM.RecolorImage {
anchors.fill: parent anchors.fill: parent
anchors.margins: 2 anchors.margins: 2 * screenScaleFactor
sourceSize.width: width sourceSize.width: width
sourceSize.height: width sourceSize.height: width
source: UM.Theme.getIcon(model.icon) source: UM.Theme.getIcon(model.icon)

View file

@ -67,7 +67,7 @@ Item
} }
} }
Item { height: UM.Theme.getSize("default_margin").height; width: 1; visible: extruders.count > 0 } Item { height: UM.Theme.getSize("default_margin").height; width: UM.Theme.getSize("default_lining").width; visible: extruders.count > 0 }
Repeater Repeater
{ {

View file

@ -13,10 +13,12 @@ UM.Dialog
{ {
title: catalog.i18nc("@title:window", "Save Project") title: catalog.i18nc("@title:window", "Save Project")
width: 500 minimumWidth: 500 * screenScaleFactor
height: 400 minimumHeight: 400 * screenScaleFactor
width: minimumWidth
height: minimumHeight
property int spacerHeight: 10 property int spacerHeight: 10 * screenScaleFactor
property bool dontShowAgain: true property bool dontShowAgain: true
@ -63,7 +65,7 @@ UM.Dialog
Column Column
{ {
anchors.fill: parent anchors.fill: parent
spacing: 2 spacing: 2 * screenScaleFactor
Label Label
{ {
id: titleLabel id: titleLabel

View file

@ -309,7 +309,7 @@ QtObject {
} }
Behavior on color { ColorAnimation { duration: 50; } } Behavior on color { ColorAnimation { duration: 50; } }
border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? 2 : 0 border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? 2 * screenScaleFactor : 0
border.color: Theme.getColor("tool_button_border") border.color: Theme.getColor("tool_button_border")
UM.RecolorImage { UM.RecolorImage {
@ -506,8 +506,8 @@ QtObject {
source: control.iconSource; source: control.iconSource;
width: Theme.getSize("section_icon").width; width: Theme.getSize("section_icon").width;
height: Theme.getSize("section_icon").height; height: Theme.getSize("section_icon").height;
sourceSize.width: width + 15 sourceSize.width: width + 15 * screenScaleFactor
sourceSize.height: width + 15 sourceSize.height: width + 15 * screenScaleFactor
} }
} }
@ -648,8 +648,8 @@ QtObject {
source: Theme.getIcon("arrow_bottom") source: Theme.getIcon("arrow_bottom")
width: Theme.getSize("standard_arrow").width width: Theme.getSize("standard_arrow").width
height: Theme.getSize("standard_arrow").height height: Theme.getSize("standard_arrow").height
sourceSize.width: width + 5 sourceSize.width: width + 5 * screenScaleFactor
sourceSize.height: width + 5 sourceSize.height: width + 5 * screenScaleFactor
color: Theme.getColor("setting_control_text"); color: Theme.getColor("setting_control_text");
} }
@ -707,8 +707,8 @@ QtObject {
source: UM.Theme.getIcon("arrow_bottom") source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width + 5 sourceSize.width: width + 5 * screenScaleFactor
sourceSize.height: width + 5 sourceSize.height: width + 5 * screenScaleFactor
color: UM.Theme.getColor("setting_control_text") color: UM.Theme.getColor("setting_control_text")
} }
@ -734,8 +734,8 @@ QtObject {
UM.RecolorImage { UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: parent.width/2.5 width: parent.width / 2.5
height: parent.height/2.5 height: parent.height / 2.5
sourceSize.width: width sourceSize.width: width
sourceSize.height: width sourceSize.height: width
color: Theme.getColor("checkbox_mark") color: Theme.getColor("checkbox_mark")