Merge branch 'master' of https://github.com/Ultimaker/Cura into master-CURA-1615

This commit is contained in:
Thomas Karl Pietrowski 2016-06-17 11:59:08 +02:00
commit 0275139a50
16 changed files with 24068 additions and 72 deletions

View File

@ -4,7 +4,7 @@
from UM.Qt.QtApplication import QtApplication from UM.Qt.QtApplication import QtApplication
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.Scene.Camera import Camera from UM.Scene.Camera import Camera
from UM.Scene.Platform import Platform from UM.Scene.Platform import Platform as Scene_Platform
from UM.Math.Vector import Vector from UM.Math.Vector import Vector
from UM.Math.Quaternion import Quaternion from UM.Math.Quaternion import Quaternion
from UM.Math.AxisAlignedBox import AxisAlignedBox from UM.Math.AxisAlignedBox import AxisAlignedBox
@ -14,6 +14,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Mesh.ReadMeshJob import ReadMeshJob from UM.Mesh.ReadMeshJob import ReadMeshJob
from UM.Logger import Logger from UM.Logger import Logger
from UM.Preferences import Preferences from UM.Preferences import Preferences
from UM.Platform import Platform
from UM.JobQueue import JobQueue from UM.JobQueue import JobQueue
from UM.SaveFile import SaveFile from UM.SaveFile import SaveFile
from UM.Scene.Selection import Selection from UM.Scene.Selection import Selection
@ -58,7 +59,7 @@ import urllib
numpy.seterr(all="ignore") numpy.seterr(all="ignore")
#WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612 #WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612
if platform.system() == "Linux": # Needed for platform.linux_distribution, which is not available on Windows and OSX if Platform.isLinux(): # Needed for platform.linux_distribution, which is not available on Windows and OSX
# For Ubuntu: https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/941826 # For Ubuntu: https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/941826
if platform.linux_distribution()[0] in ("Ubuntu", ): # TODO: Needs a "if X11_GFX == 'nvidia'" here. The workaround is only needed on Ubuntu+NVidia drivers. Other drivers are not affected, but fine with this fix. if platform.linux_distribution()[0] in ("Ubuntu", ): # TODO: Needs a "if X11_GFX == 'nvidia'" here. The workaround is only needed on Ubuntu+NVidia drivers. Other drivers are not affected, but fine with this fix.
import ctypes import ctypes
@ -340,7 +341,7 @@ class CuraApplication(QtApplication):
Selection.selectionChanged.connect(self.onSelectionChanged) Selection.selectionChanged.connect(self.onSelectionChanged)
root = controller.getScene().getRoot() root = controller.getScene().getRoot()
self._platform = Platform(root) self._platform = Scene_Platform(root)
self._volume = BuildVolume.BuildVolume(root) self._volume = BuildVolume.BuildVolume(root)

View File

@ -1,10 +1,14 @@
# Copyright (c) 2016 Ultimaker B.V. # Copyright (c) 2016 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher. # Cura is released under the terms of the AGPLv3 or higher.
import os import os
import os.path
import re
from PyQt5.QtWidgets import QMessageBox from PyQt5.QtWidgets import QMessageBox
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.InstanceContainer import InstanceContainer
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
from UM.Message import Message from UM.Message import Message
@ -13,12 +17,45 @@ from UM.PluginRegistry import PluginRegistry #For getting the possible profile w
from UM.Util import parseBool from UM.Util import parseBool
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
catalog = i18nCatalog("uranium") catalog = i18nCatalog("cura")
class CuraContainerRegistry(ContainerRegistry): class CuraContainerRegistry(ContainerRegistry):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
## Create a name that is not empty and unique
# \param container_type \type{string} Type of the container (machine, quality, ...)
# \param current_name \type{} Current name of the container, which may be an acceptable option
# \param new_name \type{string} Base name, which may not be unique
# \param fallback_name \type{string} Name to use when (stripped) new_name is empty
# \return \type{string} Name that is unique for the specified type and name/id
def createUniqueName(self, container_type, current_name, new_name, fallback_name):
new_name = new_name.strip()
num_check = re.compile("(.*?)\s*#\d+$").match(new_name)
if num_check:
new_name = num_check.group(1)
if new_name == "":
new_name = fallback_name
unique_name = new_name
i = 1
# In case we are renaming, the current name of the container is also a valid end-result
while self._containerExists(container_type, unique_name) and unique_name != current_name:
i += 1
unique_name = "%s #%d" % (new_name, i)
return unique_name
## Check if a container with of a certain type and a certain name or id exists
# Both the id and the name are checked, because they may not be the same and it is better if they are both unique
# \param container_type \type{string} Type of the container (machine, quality, ...)
# \param container_name \type{string} Name to check
def _containerExists(self, container_type, container_name):
container_class = ContainerStack if container_type == "machine" else InstanceContainer
return self.findContainers(container_class, id = container_name, type = container_type) or \
self.findContainers(container_class, name = container_name, type = container_type)
## Exports an profile to a file ## Exports an profile to a file
# #
# \param instance_id \type{str} the ID of the profile to export. # \param instance_id \type{str} the ID of the profile to export.
@ -73,14 +110,14 @@ class CuraContainerRegistry(ContainerRegistry):
# \param description # \param description
# \return The plugin object matching the given extension and description. # \return The plugin object matching the given extension and description.
def _findProfileWriter(self, extension, description): def _findProfileWriter(self, extension, description):
pr = PluginRegistry.getInstance() plugin_registry = PluginRegistry.getInstance()
for plugin_id, meta_data in self._getIOPlugins("profile_writer"): for plugin_id, meta_data in self._getIOPlugins("profile_writer"):
for supported_type in meta_data["profile_writer"]: # All file types this plugin can supposedly write. for supported_type in meta_data["profile_writer"]: # All file types this plugin can supposedly write.
supported_extension = supported_type.get("extension", None) supported_extension = supported_type.get("extension", None)
if supported_extension == extension: # This plugin supports a file type with the same extension. if supported_extension == extension: # This plugin supports a file type with the same extension.
supported_description = supported_type.get("description", None) supported_description = supported_type.get("description", None)
if supported_description == description: # The description is also identical. Assume it's the same file type. if supported_description == description: # The description is also identical. Assume it's the same file type.
return pr.getPluginObject(plugin_id) return plugin_registry.getPluginObject(plugin_id)
return None return None
## Imports a profile from a file ## Imports a profile from a file
@ -92,9 +129,9 @@ class CuraContainerRegistry(ContainerRegistry):
if not file_name: if not file_name:
return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, "Invalid path")} return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, "Invalid path")}
pr = PluginRegistry.getInstance() plugin_registry = PluginRegistry.getInstance()
for plugin_id, meta_data in self._getIOPlugins("profile_reader"): for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
profile_reader = pr.getPluginObject(plugin_id) profile_reader = plugin_registry.getPluginObject(plugin_id)
try: try:
profile = profile_reader.read(file_name) #Try to open the file with the profile reader. profile = profile_reader.read(file_name) #Try to open the file with the profile reader.
except Exception as e: except Exception as e:
@ -104,6 +141,11 @@ class CuraContainerRegistry(ContainerRegistry):
if profile: #Success! if profile: #Success!
profile.setReadOnly(False) profile.setReadOnly(False)
new_name = self.createUniqueName("quality", "", os.path.splitext(os.path.basename(file_name))[0],
catalog.i18nc("@label", "Custom profile"))
profile.setName(new_name)
profile._id = new_name
if self._machineHasOwnQualities(): if self._machineHasOwnQualities():
profile.setDefinition(self._activeDefinition()) profile.setDefinition(self._activeDefinition())
if self._machineHasOwnMaterials(): if self._machineHasOwnMaterials():
@ -120,12 +162,12 @@ class CuraContainerRegistry(ContainerRegistry):
## Gets a list of profile writer plugins ## Gets a list of profile writer plugins
# \return List of tuples of (plugin_id, meta_data). # \return List of tuples of (plugin_id, meta_data).
def _getIOPlugins(self, io_type): def _getIOPlugins(self, io_type):
pr = PluginRegistry.getInstance() plugin_registry = PluginRegistry.getInstance()
active_plugin_ids = pr.getActivePlugins() active_plugin_ids = plugin_registry.getActivePlugins()
result = [] result = []
for plugin_id in active_plugin_ids: for plugin_id in active_plugin_ids:
meta_data = pr.getMetaData(plugin_id) meta_data = plugin_registry.getMetaData(plugin_id)
if io_type in meta_data: if io_type in meta_data:
result.append( (plugin_id, meta_data) ) result.append( (plugin_id, meta_data) )
return result return result

View File

@ -67,12 +67,14 @@ class ExtruderManager(QObject):
self.activeExtruderChanged.emit() self.activeExtruderChanged.emit()
def getActiveExtruderStack(self): def getActiveExtruderStack(self):
try: global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] if global_container_stack:
except AttributeError: global_definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom()
return None if global_definition_container:
except KeyError: if global_definition_container.getId() in self._extruder_trains:
return None if str(self._active_extruder_index) in self._extruder_trains[global_definition_container.getId()]:
return self._extruder_trains[global_definition_container.getId()][str(self._active_extruder_index)]
## Adds all extruders of a specific machine definition to the extruder ## Adds all extruders of a specific machine definition to the extruder
# manager. # manager.
@ -180,7 +182,7 @@ class ExtruderManager(QObject):
quality = qualities[0] quality = qualities[0]
preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality") preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality")
if preferred_quality_id: if preferred_quality_id:
preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality") preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id, type = "quality")
if len(preferred_quality) >= 1: if len(preferred_quality) >= 1:
quality = preferred_quality[0] quality = preferred_quality[0]
else: else:

View File

@ -1,5 +1,5 @@
# Copyright (c) 2016 Ultimaker B.V.
import re # Cura is released under the terms of the AGPLv3 or higher.
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
from UM.Application import Application from UM.Application import Application
@ -8,6 +8,8 @@ from UM.Preferences import Preferences
import UM.Settings import UM.Settings
from UM.Settings.Validator import ValidatorState from UM.Settings.Validator import ValidatorState
from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.InstanceContainer import InstanceContainer
from cura.PrinterOutputDevice import PrinterOutputDevice
from UM.Settings.ContainerStack import ContainerStack from UM.Settings.ContainerStack import ContainerStack
from . import ExtruderManager from . import ExtruderManager
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
@ -49,6 +51,8 @@ class MachineManagerModel(QObject):
active_machine_id = Preferences.getInstance().getValue("cura/active_machine") active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
if active_machine_id != "": if active_machine_id != "":
# An active machine was saved, so restore it. # An active machine was saved, so restore it.
self.setActiveMachine(active_machine_id) self.setActiveMachine(active_machine_id)
@ -65,14 +69,10 @@ class MachineManagerModel(QObject):
blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly
@pyqtProperty("QVariantMap", notify = globalContainerChanged) outputDevicesChanged = pyqtSignal()
def extrudersIds(self):
## Find all extruders that reference the new stack def _onOutputDevicesChanged(self):
extruders = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(**{"machine": self._global_container_stack.getId()}) self.outputDevicesChanged.emit()
result = {}
for extruder in extruders:
result[extruder.getMetaDataEntry("position")] = extruder.getId()
return result
def _onGlobalPropertyChanged(self, key, property_name): def _onGlobalPropertyChanged(self, key, property_name):
if property_name == "value": if property_name == "value":
@ -164,6 +164,10 @@ class MachineManagerModel(QObject):
Application.getInstance().setGlobalContainerStack(new_global_stack) Application.getInstance().setGlobalContainerStack(new_global_stack)
@pyqtProperty("QVariantList", notify = outputDevicesChanged)
def printerOutputDevices(self):
return [printer_output_device for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices() if isinstance(printer_output_device, PrinterOutputDevice)]
## Create a name that is not empty and unique ## Create a name that is not empty and unique
# \param container_type \type{string} Type of the container (machine, quality, ...) # \param container_type \type{string} Type of the container (machine, quality, ...)
# \param current_name \type{} Current name of the container, which may be an acceptable option # \param current_name \type{} Current name of the container, which may be an acceptable option
@ -171,31 +175,7 @@ class MachineManagerModel(QObject):
# \param fallback_name \type{string} Name to use when (stripped) new_name is empty # \param fallback_name \type{string} Name to use when (stripped) new_name is empty
# \return \type{string} Name that is unique for the specified type and name/id # \return \type{string} Name that is unique for the specified type and name/id
def _createUniqueName(self, container_type, current_name, new_name, fallback_name): def _createUniqueName(self, container_type, current_name, new_name, fallback_name):
new_name = new_name.strip() return UM.Settings.ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name)
num_check = re.compile("(.*?)\s*#\d+$").match(new_name)
if num_check:
new_name = num_check.group(1)
if new_name == "":
new_name = fallback_name
unique_name = new_name
i = 1
# In case we are renaming, the current name of the container is also a valid end-result
while self._containerExists(container_type, unique_name) and unique_name != current_name:
i += 1
unique_name = "%s #%d" % (new_name, i)
return unique_name
## Check if a container with of a certain type and a certain name or id exists
# Both the id and the name are checked, because they may not be the same and it is better if they are both unique
# \param container_type \type{string} Type of the container (machine, quality, ...)
# \param container_name \type{string} Name to check
def _containerExists(self, container_type, container_name):
container_class = ContainerStack if container_type == "machine" else InstanceContainer
return UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, id = container_name, type = container_type) or \
UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, name = container_name, type = container_type)
## Convenience function to check if a stack has errors. ## Convenience function to check if a stack has errors.
def _checkStackForErrors(self, stack): def _checkStackForErrors(self, stack):
@ -446,7 +426,7 @@ class MachineManagerModel(QObject):
@pyqtProperty(str, notify = globalContainerChanged) @pyqtProperty(str, notify = globalContainerChanged)
def activeDefinitionId(self): def activeDefinitionId(self):
if self._active_container_stack: if self._global_container_stack:
definition = self._global_container_stack.getBottom() definition = self._global_container_stack.getBottom()
if definition: if definition:
return definition.id return definition.id
@ -480,14 +460,14 @@ class MachineManagerModel(QObject):
@pyqtProperty(bool, notify = globalContainerChanged) @pyqtProperty(bool, notify = globalContainerChanged)
def hasMaterials(self): def hasMaterials(self):
if self._active_container_stack: if self._global_container_stack:
return bool(self._global_container_stack.getMetaDataEntry("has_materials", False)) return bool(self._global_container_stack.getMetaDataEntry("has_materials", False))
return False return False
@pyqtProperty(bool, notify = globalContainerChanged) @pyqtProperty(bool, notify = globalContainerChanged)
def hasVariants(self): def hasVariants(self):
if self._active_container_stack: if self._global_container_stack:
return bool(self._global_container_stack.getMetaDataEntry("has_variants", False)) return bool(self._global_container_stack.getMetaDataEntry("has_variants", False))
return False return False

View File

@ -33,10 +33,11 @@ sys.excepthook = exceptHook
# first seems to prevent Sip from going into a state where it # first seems to prevent Sip from going into a state where it
# tries to create PyQt objects on a non-main thread. # tries to create PyQt objects on a non-main thread.
import Arcus #@UnusedImport import Arcus #@UnusedImport
from UM.Platform import Platform
import cura.CuraApplication import cura.CuraApplication
import cura.CuraContainerRegistry import cura.CuraContainerRegistry
if sys.platform == "win32" and hasattr(sys, "frozen"): if Platform.isWindows() and hasattr(sys, "frozen"):
dirpath = os.path.expanduser("~/AppData/Local/cura/") dirpath = os.path.expanduser("~/AppData/Local/cura/")
os.makedirs(dirpath, exist_ok = True) os.makedirs(dirpath, exist_ok = True)
sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w") sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w")

View File

@ -11,6 +11,7 @@ from UM.Message import Message
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from UM.Resources import Resources from UM.Resources import Resources
from UM.Settings.Validator import ValidatorState #To find if a setting is in an error state. We can't slice then. from UM.Settings.Validator import ValidatorState #To find if a setting is in an error state. We can't slice then.
from UM.Platform import Platform
from cura.ExtruderManager import ExtruderManager from cura.ExtruderManager import ExtruderManager
@ -42,7 +43,7 @@ class CuraEngineBackend(Backend):
default_engine_location = os.path.join(Application.getInstallPrefix(), "bin", "CuraEngine") default_engine_location = os.path.join(Application.getInstallPrefix(), "bin", "CuraEngine")
if hasattr(sys, "frozen"): if hasattr(sys, "frozen"):
default_engine_location = os.path.join(os.path.dirname(os.path.abspath(sys.executable)), "CuraEngine") default_engine_location = os.path.join(os.path.dirname(os.path.abspath(sys.executable)), "CuraEngine")
if sys.platform == "win32": if Platform.isWindows():
default_engine_location += ".exe" default_engine_location += ".exe"
default_engine_location = os.path.abspath(default_engine_location) default_engine_location = os.path.abspath(default_engine_location)
Preferences.getInstance().addPreference("backend/location", default_engine_location) Preferences.getInstance().addPreference("backend/location", default_engine_location)

View File

@ -232,7 +232,7 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin,
def getSerialPortList(self, only_list_usb = False): def getSerialPortList(self, only_list_usb = False):
base_list = [] base_list = []
if platform.system() == "Windows": if platform.system() == "Windows":
import winreg import winreg #@UnresolvedImport
try: try:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM") key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM")
i = 0 i = 0

View File

@ -23,8 +23,7 @@
"label": "Extruder", "label": "Extruder",
"description": "The extruder train used for printing. This is used in multi-extrusion.", "description": "The extruder train used for printing. This is used in multi-extrusion.",
"type": "extruder", "type": "extruder",
"default_value": 0, "default_value": "0",
"minimum_value": "0",
"settable_per_mesh": true, "settable_per_mesh": true,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false, "settable_per_meshgroup": false,

View File

@ -0,0 +1,94 @@
{
"id": "mendel90",
"name": "Mendel90",
"version": 2,
"inherits": "fdmprinter",
"metadata":
{
"visible": true,
"author": "Bo Herrmannsen",
"category": "Other",
"manufacturer": "Nophead",
"file_formats": "text/x-gcode",
"platform": "mendel90_platform.stl",
"platform_offset": [0, -23.6, 0]
},
"pages": [
"BedLeveling"
],
"overrides": {
"machine_start_gcode": {
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nG92 E0 ;zero the extruded length\nM107 ;start with the fan off\nG1 X90 Y200 F6000 ;go to the middle of the front\nG1 Z0.05 ;close to the bed\nG1 Z0.3 ;lift Z\n"
},
"machine_end_gcode": {
"default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nM107 ;carriage fan off\nG91 ;relative positioning\nG1 Z10 ;Move up Z 10mm\nG90 ;back to absolute mode\nG1 E-1 F1200 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG92 E0 ;zero the extruded length\nG1 Y200 F5000 ;Move Y to middle of bed cooling fan\nM42 P42 S255 ;Turn on Bed cooling fan on\nG4 S420 ;Wait 7 mins\nM42 P42 S0 ;Turn off bed cooling fan\nG1 Y10 F5000 ;Move Y to front\nM84 ;steppers off\n"
},
"material_bed_temp_wait": {
"default_value": true
},
"material_print_temp_prepend": {
"default_value": true
},
"machine_width": {
"default_value": 200
},
"machine_height": {
"default_value": 200
},
"machine_depth": {
"default_value": 200
},
"machine_heated_bed": {
"default_value": true
},
"machine_center_is_zero": {
"default_value": false
},
"machine_extruder_count": {
"default_value": 1
},
"machine_nozzle_tip_outer_diameter": {
"default_value": 1
},
"machine_nozzle_head_distance": {
"default_value": 5
},
"machine_nozzle_expansion_angle": {
"default_value": 45
},
"machine_heat_zone_length": {
"default_value": 16
},
"machine_nozzle_heat_up_speed": {
"default_value": 2.0
},
"machine_nozzle_cool_down_speed": {
"default_value": 2.0
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"gantry_height": {
"default_value": 55
},
"machine_nozzle_size": {
"default_value": 0.4
},
"material_diameter": {
"default_value": 1.75
},
"machine_head_with_fans_polygon":
{
"default_value": [
[ -12, 9 ],
[ -12, -9 ],
[ 14, 9 ],
[ 14, -9 ]
]
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -24,9 +24,10 @@ Button {
checkable: true checkable: true
checked: definition.expanded checked: definition.expanded
onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) onClicked: { forceActiveFocus(); definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) }
UM.SimpleButton { UM.SimpleButton
{
id: settingsButton id: settingsButton
visible: base.hovered || settingsButton.hovered visible: base.hovered || settingsButton.hovered
@ -60,7 +61,8 @@ Button {
height: parent.height / 2 height: parent.height / 2
width: height width: height
onClicked: { onClicked:
{
base.showAllHiddenInheritedSettings() base.showAllHiddenInheritedSettings()
} }
@ -68,11 +70,13 @@ Button {
hoverColor: UM.Theme.getColor("setting_control_button_hover") hoverColor: UM.Theme.getColor("setting_control_button_hover")
iconSource: UM.Theme.getIcon("notice") iconSource: UM.Theme.getIcon("notice")
onEntered: { onEntered:
{
base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible.")) base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible."))
} }
onExited: { onExited:
{
base.hideTooltip(); base.hideTooltip();
} }

View File

@ -31,7 +31,7 @@ SettingItem
} }
} }
onClicked: propertyProvider.setPropertyValue("value", !checked) onClicked: { forceActiveFocus(); propertyProvider.setPropertyValue("value", !checked) }
Rectangle Rectangle
{ {

View File

@ -86,7 +86,7 @@ SettingItem
} }
} }
onActivated: provider.setPropertyValue("value", definition.options[index].key) onActivated: { forceActiveFocus(); provider.setPropertyValue("value", definition.options[index].key) }
onModelChanged: updateCurrentIndex(); onModelChanged: updateCurrentIndex();
Connections Connections

View File

@ -102,7 +102,11 @@ SettingItem
} }
} }
onActivated: provider.setPropertyValue("value", extruders_model.getItem(index).index); onActivated:
{
forceActiveFocus();
provider.setPropertyValue("value", extruders_model.getItem(index).index)
}
onModelChanged: updateCurrentIndex(); onModelChanged: updateCurrentIndex();
Connections Connections

View File

@ -7,6 +7,7 @@ import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import UM 1.1 as UM import UM 1.1 as UM
import Cura 1.0 as Cura
Rectangle Rectangle
{ {
@ -14,6 +15,9 @@ Rectangle
property int currentModeIndex; property int currentModeIndex;
// Is there an output device for this printer?
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
color: UM.Theme.getColor("sidebar"); color: UM.Theme.getColor("sidebar");
UM.I18nCatalog { id: catalog; name:"cura"} UM.I18nCatalog { id: catalog; name:"cura"}

View File

@ -157,13 +157,19 @@ Column
Label Label
{ {
anchors.centerIn: parent anchors.verticalCenter: parent.verticalCenter
anchors.left: swatch.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width / 2
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2
color: control.checked ? UM.Theme.getColor("toggle_checked_text") : color: control.checked ? UM.Theme.getColor("toggle_checked_text") :
control.pressed ? UM.Theme.getColor("toggle_active_text") : control.pressed ? UM.Theme.getColor("toggle_active_text") :
control.hovered ? UM.Theme.getColor("toggle_hovered_text") : UM.Theme.getColor("toggle_unchecked_text") control.hovered ? UM.Theme.getColor("toggle_hovered_text") : UM.Theme.getColor("toggle_unchecked_text")
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
text: control.text; text: control.text
elide: Text.ElideRight
} }
} }
label: Item { } label: Item { }