diff --git a/cura/GlobalStacksModel.py b/cura/GlobalStacksModel.py index 289a03d1c4..406e7b6bb3 100644 --- a/cura/GlobalStacksModel.py +++ b/cura/GlobalStacksModel.py @@ -5,10 +5,8 @@ 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.CuraContainerRegistry import CuraContainerRegistry from cura.Settings.GlobalStack import GlobalStack @@ -25,14 +23,13 @@ class GlobalStacksModel(ListModel): 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) + CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged) + CuraContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerChanged) + CuraContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged) self._filter_dict = {} self._update() @@ -45,11 +42,14 @@ class GlobalStacksModel(ListModel): def _update(self) -> None: items = [] - container_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine") + container_stacks = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine") for container_stack in container_stacks: - connection_type = int(container_stack.getMetaDataEntry("connection_type", ConnectionType.NotConnected.value)) - has_remote_connection = connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] + has_remote_connection = False + + for connection_type in container_stack.configuredConnectionTypes: + has_remote_connection |= connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] + if container_stack.getMetaDataEntry("hidden", False) in ["True", True]: continue @@ -57,7 +57,6 @@ class GlobalStacksModel(ListModel): 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) diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py index a77ac81909..eb0d846415 100644 --- a/cura/PrinterOutput/PrintJobOutputModel.py +++ b/cura/PrinterOutput/PrintJobOutputModel.py @@ -132,8 +132,7 @@ class PrintJobOutputModel(QObject): @pyqtProperty(float, notify = timeElapsedChanged) def progress(self) -> float: - time_elapsed = max(float(self.timeElapsed), 1.0) # Prevent a division by zero exception - result = time_elapsed / self.timeTotal + result = float(self.timeElapsed) / max(self.timeTotal, 1.0) # Prevent a division by zero exception. return min(result, 1.0) # Never get a progress past 1.0 @pyqtProperty(str, notify=stateChanged) diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index 44ceee9511..2bb2cc7298 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -42,7 +42,12 @@ class GlobalStack(CuraContainerStack): # Per thread we have our own resolving_settings, or strange things sometimes occur. self._resolving_settings = defaultdict(set) #type: Dict[str, Set[str]] # keys are thread names + # Since the metadatachanged is defined in container stack, we can't use it here as a notifier for pyqt + # properties. So we need to tie them together like this. + self.metaDataChanged.connect(self.configuredConnectionTypesChanged) + extrudersChanged = pyqtSignal() + configuredConnectionTypesChanged = pyqtSignal() ## Get the list of extruders of this stack. # @@ -63,6 +68,34 @@ class GlobalStack(CuraContainerStack): def getLoadingPriority(cls) -> int: return 2 + # The configured connection types can be used to find out if the global stack is configured to be connected with + # a printer, without having to know all the details as to how this is exactly done (and without actually setting + # the stack to be active). This data can then in turn also be used when the global stack is active; If we can't + # get a network connection, but it is configured to have one, we can display a different icon to indicate the + # difference. + @pyqtProperty("QVariantList", notify=configuredConnectionTypesChanged) + def configuredConnectionTypes(self): + # Requesting it from the metadata actually gets them as strings (as that's what you get from serializing). + # But we do want them returned as a list of ints (so the rest of the code can directly compare) + connection_types = self.getMetaDataEntry("connection_type", "").split(",") + return [int(connection_type) for connection_type in connection_types if connection_type != ""] + + # \sa configuredConnectionTypes + def addConfiguredConnectionType(self, connection_type): + configured_connection_types = self.configuredConnectionTypes + if connection_type not in configured_connection_types: + # Store the values as a string. + configured_connection_types.append(str(connection_type)) + self.setMetaDataEntry("connection_type", ",".join(configured_connection_types)) + + # \sa configuredConnectionTypes + def removeConfiguredConnectionType(self, connection_type): + configured_connection_types = self.configuredConnectionTypes + if connection_type in self.configured_connection_types: + # Store the values as a string. + configured_connection_types.remove(str(connection_type)) + self.setMetaDataEntry("connection_type", ",".join(configured_connection_types)) + @classmethod def getConfigurationTypeFromSerialized(cls, serialized: str) -> Optional[str]: configuration_type = super().getConfigurationTypeFromSerialized(serialized) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 5f33be1c54..ae74d76734 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -528,8 +528,12 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasRemoteConnection(self) -> bool: if self._global_container_stack: - connection_type = int(self._global_container_stack.getMetaDataEntry("connection_type", ConnectionType.NotConnected.value)) - return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] + has_remote_connection = False + + for connection_type in self._global_container_stack.configuredConnectionTypes: + has_remote_connection |= connection_type in [ConnectionType.NetworkConnection.value, + ConnectionType.CloudConnection.value] + return has_remote_connection return False @pyqtProperty(bool, notify = printerConnectedStatusChanged) diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index 060f1496f1..c1a3baf864 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -3,7 +3,7 @@ import os from datetime import datetime -from typing import Optional, List, Dict, Any +from typing import Optional, List, Dict, Any, cast from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal @@ -68,7 +68,7 @@ class DrivePluginExtension(QObject, Extension): def showDriveWindow(self) -> None: if not self._drive_window: - plugin_dir_path = CuraApplication.getInstance().getPluginRegistry().getPluginPath("CuraDrive") + plugin_dir_path = cast(str, CuraApplication.getInstance().getPluginRegistry().getPluginPath("CuraDrive")) path = os.path.join(plugin_dir_path, "src", "qml", "main.qml") self._drive_window = CuraApplication.getInstance().createQmlComponent(path, {"CuraDrive": self}) self.refreshBackups() diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index ccd181cdbc..3fea73f9a4 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -37,7 +37,7 @@ class Toolbox(QObject, Extension): self._application = application # type: CuraApplication self._sdk_version = ApplicationMetadata.CuraSDKVersion # type: Union[str, int] - self._cloud_api_version = UltimakerCloudAuthentication.CuraCloudAPIVersion # type: int + self._cloud_api_version = UltimakerCloudAuthentication.CuraCloudAPIVersion # type: str self._cloud_api_root = UltimakerCloudAuthentication.CuraCloudAPIRoot # type: str self._api_url = None # type: Optional[str] diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml index 07eaa4f051..771bd4b8cf 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml @@ -53,7 +53,7 @@ Item } text: catalog.i18nc("@label", "Move to top"); visible: { - if (printJob && printJob.state == "queued" && !isAssigned(printJob)) { + if (printJob && (printJob.state == "queued" || printJob.state == "error") && !isAssigned(printJob)) { if (OutputDevice && OutputDevice.queuedPrintJobs[0]) { return OutputDevice.queuedPrintJobs[0].key != printJob.key; } @@ -72,7 +72,7 @@ Item if (!printJob) { return false; } - var states = ["queued", "sent_to_printer"]; + var states = ["queued", "error", "sent_to_printer"]; return states.indexOf(printJob.state) !== -1; } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 6b23ebf980..0bf3d0ca52 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -225,7 +225,7 @@ Item if (!printJob) { return false } - var states = ["queued", "sent_to_printer", "pre_print", "printing", "pausing", "paused", "resuming"] + var states = ["queued", "error", "sent_to_printer", "pre_print", "printing", "pausing", "paused", "resuming"] return states.indexOf(printJob.state) !== -1 } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 085bf774b5..0e541c484d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -179,7 +179,7 @@ Item if (!printer || !printer.activePrintJob) { return false } - var states = ["queued", "sent_to_printer", "pre_print", "printing", "pausing", "paused", "resuming"] + var states = ["queued", "error", "sent_to_printer", "pre_print", "printing", "pausing", "paused", "resuming"] return states.indexOf(printer.activePrintJob.state) !== -1 } } @@ -306,7 +306,7 @@ Item } if (printer && printer.state == "unreachable") { - return catalog.i18nc("@label:status", "Unavailable") + return catalog.i18nc("@label:status", "Unreachable") } if (printer && !printer.activePrintJob && printer.state == "idle") { @@ -398,6 +398,7 @@ Item font: UM.Theme.getFont("default") text: catalog.i18nc("@label:status", "Requires configuration changes") visible: printer && printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 && !printerStatus.visible + color: UM.Theme.getColor("monitor_text_primary") // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index b688ee9d7d..7072aef4cc 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -13,6 +13,7 @@ from UM.i18n import i18nCatalog from cura.CuraApplication import CuraApplication from cura.MachineAction import MachineAction +from cura.Settings.CuraContainerRegistry import CuraContainerRegistry from .UM3OutputDevicePlugin import UM3OutputDevicePlugin @@ -133,23 +134,29 @@ class DiscoverUM3Action(MachineAction): return meta_data = global_container_stack.getMetaData() - if "um_network_key" in meta_data: - previous_network_key = meta_data["um_network_key"] - global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) - # Delete old authentication data. - 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_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.connectionType.value) - CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connection_type", value = previous_connection_type, new_value = printer_device.connectionType.value) - else: + if "um_network_key" in meta_data: # Global stack already had a connection, but it's changed. + old_network_key = meta_data["um_network_key"] + # Since we might have a bunch of hidden stacks, we also need to change it there. + metadata_filter = {"um_network_key": old_network_key} + containers = CuraContainerRegistry.getInstance().findContainerStacks(type="machine", **metadata_filter) + + for container in containers: + container.setMetaDataEntry("um_network_key", printer_device.key) + + # Delete old authentication data. + Logger.log("d", "Removing old authentication id %s for device %s", + global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key) + + container.removeMetaDataEntry("network_authentication_id") + container.removeMetaDataEntry("network_authentication_key") + + # Ensure that these containers do know that they are configured for network connection + container.addConfiguredConnectionType(printer_device.connectionType.value) + + else: # Global stack didn't have a connection yet, configure it. global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) - global_container_stack.setMetaDataEntry("connection_type", printer_device.connectionType.value) + global_container_stack.addConfiguredConnectionType(printer_device.connectionType.value) if self._network_plugin: # Ensure that the connection states are refreshed. diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 4a510903dd..74d2d87b3b 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -9,7 +9,7 @@ from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange, ServiceInfo from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager from PyQt5.QtCore import QUrl -from UM.Application import Application +from cura.CuraApplication import CuraApplication from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin from UM.Logger import Logger from UM.Signal import Signal, signalemitter @@ -41,7 +41,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self.addDeviceSignal.connect(self._onAddDevice) self.removeDeviceSignal.connect(self._onRemoveDevice) - Application.getInstance().globalContainerStackChanged.connect(self.reCheckConnections) + CuraApplication.getInstance().globalContainerStackChanged.connect(self.reCheckConnections) self._discovered_devices = {} @@ -56,7 +56,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._cluster_api_prefix = "/cluster-api/v" + self._cluster_api_version + "/" # Get list of manual instances from preferences - self._preferences = Application.getInstance().getPreferences() + self._preferences = CuraApplication.getInstance().getPreferences() self._preferences.addPreference("um3networkprinting/manual_instances", "") # A comma-separated list of ip adresses or hostnames @@ -108,7 +108,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self.resetLastManualDevice() def reCheckConnections(self): - active_machine = Application.getInstance().getGlobalContainerStack() + active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return @@ -118,7 +118,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): if key == um_network_key: if not self._discovered_devices[key].isConnected(): Logger.log("d", "Attempting to connect with [%s]" % key) - active_machine.setMetaDataEntry("connection_type", self._discovered_devices[key].connectionType.value) + # It should already be set, but if it actually connects we know for sure it's supported! + active_machine.addConfiguredConnectionType(self._discovered_devices[key].connectionType.value) self._discovered_devices[key].connect() self._discovered_devices[key].connectionStateChanged.connect(self._onDeviceConnectionStateChanged) else: @@ -134,7 +135,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): return if self._discovered_devices[key].isConnected(): # Sometimes the status changes after changing the global container and maybe the device doesn't belong to this machine - um_network_key = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("um_network_key") + um_network_key = CuraApplication.getInstance().getGlobalContainerStack().getMetaDataEntry("um_network_key") if key == um_network_key: self.getOutputDeviceManager().addOutputDevice(self._discovered_devices[key]) else: @@ -287,9 +288,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._discovered_devices[device.getId()] = device self.discoveredDevicesChanged.emit() - global_container_stack = Application.getInstance().getGlobalContainerStack() + global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"): - global_container_stack.setMetaDataEntry("connection_type", device.connectionType.value) + # Ensure that the configured connection type is set. + global_container_stack.addConfiguredConnectionType(device.connectionType.value) device.connect() device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged) @@ -306,7 +308,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._service_changed_request_event.wait(timeout = 5.0) # Stop if the application is shutting down - if Application.getInstance().isShuttingDown(): + if CuraApplication.getInstance().isShuttingDown(): return self._service_changed_request_event.clear() diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 19a703e605..32203ffa6c 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -55,6 +55,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._update_thread = Thread(target = self._update, daemon = True) self._last_temperature_request = None # type: Optional[int] + self._firmware_idle_count = 0 self._is_printing = False # A print is being sent. diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml index 8bd5d5a0d3..7cd466c33f 100644 --- a/resources/qml/ActionPanel/PrintJobInformation.qml +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2019 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -36,30 +36,63 @@ Column Label { - property var printDuration: PrintInformation.currentPrintTime + id: byLineType - text: + property var printDuration: PrintInformation.currentPrintTime + property var columnWidthMultipliers: [ 0.4, 0.3, 0.3 ] + property var columnHorizontalAligns: [ TextInput.AlignLeft, TextInput.AlignHCenter, TextInput.AlignHCenter ] + + function getMaterialTable() { + var result = [] + // All the time information for the different features is achieved var printTime = PrintInformation.getFeaturePrintTimes() var totalSeconds = parseInt(printDuration.getDisplayString(UM.DurationFormat.Seconds)) // A message is created and displayed when the user hover the time label - var text = "" for(var feature in printTime) { if(!printTime[feature].isTotalDurationZero) { - text += "" + - "".arg(printTime[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) + - "".arg(Math.round(100 * parseInt(printTime[feature].getDisplayString(UM.DurationFormat.Seconds)) / totalSeconds)) + - "" + var row = [] + row.push(feature + ": ") + row.push("%1".arg(printTime[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3))) + row.push("%1%".arg(Math.round(100 * parseInt(printTime[feature].getDisplayString(UM.DurationFormat.Seconds)) / totalSeconds))) + result.push(row) } } - text += "
" + feature + ":  %1  %1%
" - return text + + return result } + + Column + { + Repeater + { + model: byLineType.getMaterialTable() + Row + { + Repeater + { + model: modelData + Label + { + width: Math.round(byLineType.width * byLineType.columnWidthMultipliers[index]) + height: contentHeight + horizontalAlignment: byLineType.columnHorizontalAligns[index] + font: UM.Theme.getFont("default") + wrapMode: Text.WrapAnywhere + text: modelData + renderType: Text.NativeRendering + } + } + } + } + } + width: parent.width - 2 * UM.Theme.getSize("default_margin").width + height: childrenRect.height color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") renderType: Text.NativeRendering @@ -85,31 +118,19 @@ Column Label { + id: byMaterialType + property var printMaterialLengths: PrintInformation.materialLengths property var printMaterialWeights: PrintInformation.materialWeights property var printMaterialCosts: PrintInformation.materialCosts property var printMaterialNames: PrintInformation.materialNames + property var columnWidthMultipliers: [ 0.4, 0.2, 0.2, 0.2 ] + property var columnHorizontalAligns: [ TextInput.AlignLeft, TextInput.AlignHCenter, TextInput.AlignHCenter, TextInput.AlignHCenter ] - function formatRow(items) + function getMaterialTable() { - var rowHTML = "" - for(var item = 0; item < items.length; item++) - { - if (item == 0) - { - rowHTML += "%1".arg(items[item]) - } - else - { - rowHTML += "  %1".arg(items[item]) - } - } - rowHTML += "" - return rowHTML - } + var result = [] - text: - { var lengths = [] var weights = [] var costs = [] @@ -135,21 +156,46 @@ Column costs = ["0.00"] } - var text = "" for(var index = 0; index < lengths.length; index++) { - text += formatRow([ - "%1:".arg(names[index]), - catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]), - catalog.i18nc("@label g for grams", "%1g").arg(weights[index]), - "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]), - ]) + var row = [] + row.push("%1".arg(names[index])) + row.push(catalog.i18nc("@label m for meter", "%1m").arg(lengths[index])) + row.push(catalog.i18nc("@label g for grams", "%1g").arg(weights[index])) + row.push("%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index])) + result.push(row) } - text += "
" - return text + return result } + + Column + { + Repeater + { + model: byMaterialType.getMaterialTable() + Row + { + Repeater + { + model: modelData + Label + { + width: Math.round(byMaterialType.width * byMaterialType.columnWidthMultipliers[index]) + height: contentHeight + horizontalAlignment: byLineType.columnHorizontalAligns[index] + font: UM.Theme.getFont("default") + wrapMode: Text.WrapAnywhere + text: modelData + renderType: Text.NativeRendering + } + } + } + } + } + width: parent.width - 2 * UM.Theme.getSize("default_margin").width + height: childrenRect.height color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") renderType: Text.NativeRendering