mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-25 15:44:04 -06:00
Merge branch 'master' into WIP_improve_initialization
This commit is contained in:
commit
e38b31c0eb
21 changed files with 358 additions and 215 deletions
|
@ -297,7 +297,6 @@ class CuraApplication(QtApplication):
|
|||
if not hasattr(sys, "frozen"):
|
||||
resource_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources")
|
||||
Resources.addSearchPath(resource_path)
|
||||
Resources.setBundledResourcesPath(resource_path)
|
||||
|
||||
# Adds custom property types, settings types, and extra operators (functions) that need to be registered in
|
||||
# SettingDefinition and SettingFunction.
|
||||
|
@ -397,6 +396,7 @@ class CuraApplication(QtApplication):
|
|||
def __setLatestResouceVersionsForVersionUpgrade(self):
|
||||
self._version_upgrade_manager.setCurrentVersions(
|
||||
{
|
||||
("quality", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||
("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityChangesInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||
("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
|
||||
("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
|
||||
|
|
|
@ -18,9 +18,6 @@ from UM.Version import Version
|
|||
class CuraPackageManager(QObject):
|
||||
Version = 1
|
||||
|
||||
# The prefix that's added to all files for an installed package to avoid naming conflicts with user created files.
|
||||
PREFIX_PLACE_HOLDER = "-CP;"
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
||||
|
@ -28,15 +25,19 @@ class CuraPackageManager(QObject):
|
|||
self._container_registry = self._application.getContainerRegistry()
|
||||
self._plugin_registry = self._application.getPluginRegistry()
|
||||
|
||||
# JSON file that keeps track of all installed packages.
|
||||
self._bundled_package_management_file_path = os.path.join(
|
||||
os.path.abspath(Resources.getBundledResourcesPath()),
|
||||
"packages.json"
|
||||
)
|
||||
self._user_package_management_file_path = os.path.join(
|
||||
os.path.abspath(Resources.getDataStoragePath()),
|
||||
"packages.json"
|
||||
)
|
||||
#JSON files that keep track of all installed packages.
|
||||
self._user_package_management_file_path = None
|
||||
self._bundled_package_management_file_path = None
|
||||
for search_path in Resources.getSearchPaths():
|
||||
candidate_bundled_path = os.path.join(search_path, "bundled_packages.json")
|
||||
if os.path.exists(candidate_bundled_path):
|
||||
self._bundled_package_management_file_path = candidate_bundled_path
|
||||
for search_path in (Resources.getDataStoragePath(), Resources.getConfigStoragePath()):
|
||||
candidate_user_path = os.path.join(search_path, "packages.json")
|
||||
if os.path.exists(candidate_user_path):
|
||||
self._user_package_management_file_path = candidate_user_path
|
||||
if self._user_package_management_file_path is None: #Doesn't exist yet.
|
||||
self._user_package_management_file_path = os.path.join(Resources.getDataStoragePath(), "packages.json")
|
||||
|
||||
self._bundled_package_dict = {} # A dict of all bundled packages
|
||||
self._installed_package_dict = {} # A dict of all installed packages
|
||||
|
@ -136,14 +137,14 @@ class CuraPackageManager(QObject):
|
|||
all_installed_ids = all_installed_ids.union(set(self._bundled_package_dict.keys()))
|
||||
if self._installed_package_dict.keys():
|
||||
all_installed_ids = all_installed_ids.union(set(self._installed_package_dict.keys()))
|
||||
all_installed_ids = all_installed_ids.difference(self._to_remove_package_set)
|
||||
# If it's going to be installed and to be removed, then the package is being updated and it should be listed.
|
||||
if self._to_install_package_dict.keys():
|
||||
all_installed_ids = all_installed_ids.union(set(self._to_install_package_dict.keys()))
|
||||
all_installed_ids = all_installed_ids.difference(self._to_remove_package_set)
|
||||
|
||||
# map of <package_type> -> <package_id> -> <package_info>
|
||||
installed_packages_dict = {}
|
||||
for package_id in all_installed_ids:
|
||||
|
||||
# Skip required plugins as they should not be tampered with
|
||||
if package_id in Application.getInstance().getRequiredPlugins():
|
||||
continue
|
||||
|
@ -168,7 +169,7 @@ class CuraPackageManager(QObject):
|
|||
package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id)
|
||||
|
||||
# If the package ID is in bundled, label it as such
|
||||
package_info["is_bundled"] = package_info["package_id"] in self._bundled_package_dict.keys()
|
||||
package_info["is_bundled"] = package_info["package_id"] in self._bundled_package_dict.keys() and not self.isUserInstalledPackage(package_info["package_id"])
|
||||
|
||||
# If there is not a section in the dict for this type, add it
|
||||
if package_info["package_type"] not in installed_packages_dict:
|
||||
|
@ -179,7 +180,7 @@ class CuraPackageManager(QObject):
|
|||
|
||||
return installed_packages_dict
|
||||
|
||||
# Checks if the given package is installed.
|
||||
# Checks if the given package is installed (at all).
|
||||
def isPackageInstalled(self, package_id: str) -> bool:
|
||||
return self.getInstalledPackageInfo(package_id) is not None
|
||||
|
||||
|
@ -194,11 +195,6 @@ class CuraPackageManager(QObject):
|
|||
return
|
||||
package_id = package_info["package_id"]
|
||||
|
||||
# Check the delayed installation and removal lists first
|
||||
if package_id in self._to_remove_package_set:
|
||||
self._to_remove_package_set.remove(package_id)
|
||||
has_changes = True
|
||||
|
||||
# Check if it is installed
|
||||
installed_package_info = self.getInstalledPackageInfo(package_info["package_id"])
|
||||
to_install_package = installed_package_info is None # Install if the package has not been installed
|
||||
|
@ -235,23 +231,35 @@ class CuraPackageManager(QObject):
|
|||
self.installedPackagesChanged.emit()
|
||||
|
||||
# Schedules the given package to be removed upon the next start.
|
||||
# \param package_id id of the package
|
||||
# \param force_add is used when updating. In that case you actually want to uninstall & install
|
||||
@pyqtSlot(str)
|
||||
def removePackage(self, package_id: str) -> None:
|
||||
def removePackage(self, package_id: str, force_add: bool = False) -> None:
|
||||
# Check the delayed installation and removal lists first
|
||||
if not self.isPackageInstalled(package_id):
|
||||
Logger.log("i", "Attempt to remove package [%s] that is not installed, do nothing.", package_id)
|
||||
return
|
||||
|
||||
# Remove from the delayed installation list if present
|
||||
if package_id in self._to_install_package_dict:
|
||||
del self._to_install_package_dict[package_id]
|
||||
# Extra safety check
|
||||
if package_id not in self._installed_package_dict and package_id in self._bundled_package_dict:
|
||||
Logger.log("i", "Not uninstalling [%s] because it is a bundled package.")
|
||||
return
|
||||
|
||||
if package_id not in self._to_install_package_dict or force_add:
|
||||
# Schedule for a delayed removal:
|
||||
self._to_remove_package_set.add(package_id)
|
||||
else:
|
||||
if package_id in self._to_install_package_dict:
|
||||
# Remove from the delayed installation list if present
|
||||
del self._to_install_package_dict[package_id]
|
||||
|
||||
self._saveManagementData()
|
||||
self.installedPackagesChanged.emit()
|
||||
|
||||
## Is the package an user installed package?
|
||||
def isUserInstalledPackage(self, package_id: str):
|
||||
return package_id in self._installed_package_dict
|
||||
|
||||
# Removes everything associated with the given package ID.
|
||||
def _purgePackage(self, package_id: str) -> None:
|
||||
# Iterate through all directories in the data storage directory and look for sub-directories that belong to
|
||||
|
@ -302,27 +310,15 @@ class CuraPackageManager(QObject):
|
|||
|
||||
if not os.path.exists(src_dir_path):
|
||||
continue
|
||||
|
||||
# Need to rename the container files so they don't get ID conflicts
|
||||
to_rename_files = sub_dir_name not in ("plugins",)
|
||||
self.__installPackageFiles(package_id, src_dir_path, dst_dir_path, need_to_rename_files= to_rename_files)
|
||||
self.__installPackageFiles(package_id, src_dir_path, dst_dir_path)
|
||||
|
||||
# Remove the file
|
||||
os.remove(filename)
|
||||
|
||||
def __installPackageFiles(self, package_id: str, src_dir: str, dst_dir: str, need_to_rename_files: bool = True) -> None:
|
||||
def __installPackageFiles(self, package_id: str, src_dir: str, dst_dir: str) -> None:
|
||||
Logger.log("i", "Moving package {package_id} from {src_dir} to {dst_dir}".format(package_id=package_id, src_dir=src_dir, dst_dir=dst_dir))
|
||||
shutil.move(src_dir, dst_dir)
|
||||
|
||||
# Rename files if needed
|
||||
if not need_to_rename_files:
|
||||
return
|
||||
for root, _, file_names in os.walk(dst_dir):
|
||||
for filename in file_names:
|
||||
new_filename = self.PREFIX_PLACE_HOLDER + package_id + "-" + filename
|
||||
old_file_path = os.path.join(root, filename)
|
||||
new_file_path = os.path.join(root, new_filename)
|
||||
os.rename(old_file_path, new_file_path)
|
||||
|
||||
# Gets package information from the given file.
|
||||
def getPackageInfo(self, filename: str) -> Dict[str, Any]:
|
||||
with zipfile.ZipFile(filename) as archive:
|
||||
|
@ -342,13 +338,7 @@ class CuraPackageManager(QObject):
|
|||
with zipfile.ZipFile(filename) as archive:
|
||||
# Go through all the files and use the first successful read as the result
|
||||
for file_info in archive.infolist():
|
||||
is_dir = lambda file_info: file_info.filename.endswith('/')
|
||||
if is_dir or not file_info.filename.startswith("files/"):
|
||||
continue
|
||||
|
||||
filename_parts = os.path.basename(file_info.filename.lower()).split(".")
|
||||
stripped_filename = filename_parts[0]
|
||||
if stripped_filename in ("license", "licence"):
|
||||
if file_info.filename.endswith("LICENSE"):
|
||||
Logger.log("d", "Found potential license file '%s'", file_info.filename)
|
||||
try:
|
||||
with archive.open(file_info.filename, "r") as f:
|
||||
|
|
|
@ -113,8 +113,6 @@ class MaterialManager(QObject):
|
|||
grouped_by_type_dict = dict()
|
||||
material_types_without_fallback = set()
|
||||
for root_material_id, material_node in self._material_group_map.items():
|
||||
if not self._container_registry.isReadOnly(root_material_id):
|
||||
continue
|
||||
material_type = material_node.root_material_node.metadata["material"]
|
||||
if material_type not in grouped_by_type_dict:
|
||||
grouped_by_type_dict[material_type] = {"generic": None,
|
||||
|
@ -127,9 +125,15 @@ class MaterialManager(QObject):
|
|||
diameter = material_node.root_material_node.metadata.get("approximate_diameter")
|
||||
if diameter != self._default_approximate_diameter_for_quality_search:
|
||||
to_add = False # don't add if it's not the default diameter
|
||||
|
||||
if to_add:
|
||||
# Checking this first allow us to differentiate between not read only materials:
|
||||
# - if it's in the list, it means that is a new material without fallback
|
||||
# - if it is not, then it is a custom material with a fallback material (parent)
|
||||
if material_type in material_types_without_fallback:
|
||||
grouped_by_type_dict[material_type] = material_node.root_material_node.metadata
|
||||
material_types_without_fallback.remove(material_type)
|
||||
|
||||
# Remove the materials that have no fallback materials
|
||||
for material_type in material_types_without_fallback:
|
||||
del grouped_by_type_dict[material_type]
|
||||
|
@ -147,9 +151,6 @@ class MaterialManager(QObject):
|
|||
material_group_dict = dict()
|
||||
keys_to_fetch = ("name", "material", "brand", "color")
|
||||
for root_material_id, machine_node in self._material_group_map.items():
|
||||
if not self._container_registry.isReadOnly(root_material_id):
|
||||
continue
|
||||
|
||||
root_material_metadata = machine_node.root_material_node.metadata
|
||||
|
||||
key_data = []
|
||||
|
@ -157,8 +158,13 @@ class MaterialManager(QObject):
|
|||
key_data.append(root_material_metadata.get(key))
|
||||
key_data = tuple(key_data)
|
||||
|
||||
# If the key_data doesn't exist, no matter if the material is read only...
|
||||
if key_data not in material_group_dict:
|
||||
material_group_dict[key_data] = dict()
|
||||
else:
|
||||
# ...but if key_data exists, we just overrite it if the material is read only, otherwise we skip it
|
||||
if not machine_node.is_read_only:
|
||||
continue
|
||||
approximate_diameter = root_material_metadata.get("approximate_diameter")
|
||||
material_group_dict[key_data][approximate_diameter] = root_material_metadata["id"]
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ class PrintInformation(QObject):
|
|||
except:
|
||||
Logger.log("w", "Unsupported Mime Type Database file extension")
|
||||
|
||||
if data is not None:
|
||||
if data is not None and check_name is not None:
|
||||
self._base_name = data
|
||||
else:
|
||||
self._base_name = ''
|
||||
|
|
BIN
plugins/Toolbox/resources/images/loading.gif
Normal file
BIN
plugins/Toolbox/resources/images/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
1
plugins/Toolbox/resources/images/loading.svg
Normal file
1
plugins/Toolbox/resources/images/loading.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="200px" height="200px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-rolling" style="animation-play-state: running; animation-delay: 0s; background-image: none; background-position: initial initial; background-repeat: initial initial;"><circle cx="50" cy="50" fill="none" ng-attr-stroke="{{config.color}}" ng-attr-stroke-width="{{config.width}}" ng-attr-r="{{config.radius}}" ng-attr-stroke-dasharray="{{config.dasharray}}" stroke="#0CA9E3" stroke-width="13" r="43" stroke-dasharray="202.63272615654165 69.54424205218055" style="animation-play-state: running; animation-delay: 0s;"><animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite" style="animation-play-state: running; animation-delay: 0s;"></animateTransform></circle></svg>
|
After Width: | Height: | Size: 903 B |
|
@ -20,7 +20,7 @@ Item
|
|||
{
|
||||
left: parent.left
|
||||
right: controls.left
|
||||
rightMargin: UM.Theme.getSize("default_margin").width
|
||||
rightMargin: UM.Theme.getSize("default_margin").width * 2 + UM.Theme.getSize("toolbox_loader").width
|
||||
top: parent.top
|
||||
}
|
||||
Label
|
||||
|
@ -53,60 +53,28 @@ Item
|
|||
anchors.top: tile.top
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
Button
|
||||
|
||||
ToolboxProgressButton
|
||||
{
|
||||
id: installButton
|
||||
text:
|
||||
active: toolbox.isDownloading && toolbox.activePackage == model
|
||||
complete: tile.installed
|
||||
readyAction: function()
|
||||
{
|
||||
if (installed)
|
||||
{
|
||||
return catalog.i18nc("@action:button", "Installed")
|
||||
toolbox.activePackage = model
|
||||
toolbox.startDownload(model.download_url)
|
||||
}
|
||||
else
|
||||
activeAction: function()
|
||||
{
|
||||
if (toolbox.isDownloading && toolbox.activePackage == model)
|
||||
{
|
||||
return catalog.i18nc("@action:button", "Cancel")
|
||||
toolbox.cancelDownload()
|
||||
}
|
||||
else
|
||||
{
|
||||
return catalog.i18nc("@action:button", "Install")
|
||||
}
|
||||
}
|
||||
}
|
||||
enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model) //Don't allow installing while another download is running.
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
|
||||
property alias installed: tile.installed
|
||||
style: UM.Theme.styles.toolbox_action_button
|
||||
onClicked:
|
||||
{
|
||||
if (installed)
|
||||
completeAction: function()
|
||||
{
|
||||
toolbox.viewCategory = "installed"
|
||||
}
|
||||
else
|
||||
{
|
||||
// if ( toolbox.isDownloading && toolbox.activePackage == model )
|
||||
if ( toolbox.isDownloading )
|
||||
{
|
||||
toolbox.cancelDownload();
|
||||
}
|
||||
else
|
||||
{
|
||||
toolbox.activePackage = model
|
||||
// toolbox.activePackage = model;
|
||||
if ( model.can_upgrade )
|
||||
{
|
||||
// toolbox.downloadAndInstallPlugin( model.update_url );
|
||||
}
|
||||
else
|
||||
{
|
||||
toolbox.startDownload( model.download_url );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Don't allow installing while another download is running
|
||||
enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model)
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,16 @@ Item
|
|||
color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining")
|
||||
linkColor: UM.Theme.getColor("text_link")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: model.version
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("toolbox_property_label").height
|
||||
color: UM.Theme.getColor("text")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
ToolboxInstalledTileActions
|
||||
{
|
||||
|
|
|
@ -11,56 +11,28 @@ Column
|
|||
width: UM.Theme.getSize("toolbox_action_button").width
|
||||
spacing: UM.Theme.getSize("narrow_margin").height
|
||||
|
||||
Item
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
visible: canUpdate
|
||||
Button
|
||||
ToolboxProgressButton
|
||||
{
|
||||
id: updateButton
|
||||
text: catalog.i18nc("@action:button", "Update")
|
||||
style: ButtonStyle
|
||||
active: toolbox.isDownloading && toolbox.activePackage == model
|
||||
readyLabel: catalog.i18nc("@action:button", "Update")
|
||||
activeLabel: catalog.i18nc("@action:button", "Updating")
|
||||
completeLabel: catalog.i18nc("@action:button", "Updated")
|
||||
readyAction: function()
|
||||
{
|
||||
background: Rectangle
|
||||
toolbox.activePackage = model
|
||||
toolbox.update(model.id)
|
||||
}
|
||||
activeAction: function()
|
||||
{
|
||||
implicitWidth: UM.Theme.getSize("toolbox_action_button").width
|
||||
implicitHeight: UM.Theme.getSize("toolbox_action_button").height
|
||||
color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary")
|
||||
}
|
||||
label: Label
|
||||
{
|
||||
text: control.text
|
||||
color: control.hovered ? UM.Theme.getColor("button_text") : UM.Theme.getColor("button_text_hover")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
}
|
||||
}
|
||||
onClicked: toolbox.update(model.id)
|
||||
}
|
||||
ProgressBar
|
||||
{
|
||||
id: progressbar
|
||||
width: parent.width
|
||||
value: toolbox.isDownloading ? toolbox.downloadProgress : 0
|
||||
visible: toolbox.isDownloading
|
||||
style: ProgressBarStyle
|
||||
{
|
||||
background: Rectangle
|
||||
{
|
||||
color: "transparent"
|
||||
implicitHeight: UM.Theme.getSize("toolbox_action_button").height
|
||||
}
|
||||
progress: Rectangle
|
||||
{
|
||||
// TODO Define a good color that fits the purpuse
|
||||
color: "blue"
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
toolbox.cancelDownload()
|
||||
}
|
||||
// Don't allow installing while another download is running
|
||||
enabled: !(toolbox.isDownloading && toolbox.activePackage != model)
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
visible: canUpdate
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: removeButton
|
||||
|
|
125
plugins/Toolbox/resources/qml/ToolboxProgressButton.qml
Normal file
125
plugins/Toolbox/resources/qml/ToolboxProgressButton.qml
Normal file
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import UM 1.1 as UM
|
||||
|
||||
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
|
||||
property var active: false
|
||||
property var complete: false
|
||||
|
||||
property var readyLabel: catalog.i18nc("@action:button", "Install")
|
||||
property var activeLabel: catalog.i18nc("@action:button", "Cancel")
|
||||
property var completeLabel: catalog.i18nc("@action:button", "Installed")
|
||||
|
||||
property var readyAction: null // Action when button is ready and clicked (likely install)
|
||||
property var activeAction: null // Action when button is active and clicked (likely cancel)
|
||||
property var completeAction: null // Action when button is complete and clicked (likely go to installed)
|
||||
|
||||
width: UM.Theme.getSize("toolbox_action_button").width
|
||||
height: UM.Theme.getSize("toolbox_action_button").height
|
||||
|
||||
Button
|
||||
{
|
||||
id: button
|
||||
text:
|
||||
{
|
||||
if (complete)
|
||||
{
|
||||
return completeLabel
|
||||
}
|
||||
else if (active)
|
||||
{
|
||||
return activeLabel
|
||||
}
|
||||
else
|
||||
{
|
||||
return readyLabel
|
||||
}
|
||||
}
|
||||
onClicked:
|
||||
{
|
||||
if (complete)
|
||||
{
|
||||
return completeAction()
|
||||
}
|
||||
else if (active)
|
||||
{
|
||||
return activeAction()
|
||||
}
|
||||
else
|
||||
{
|
||||
return readyAction()
|
||||
}
|
||||
}
|
||||
style: ButtonStyle
|
||||
{
|
||||
background: Rectangle
|
||||
{
|
||||
implicitWidth: UM.Theme.getSize("toolbox_action_button").width
|
||||
implicitHeight: UM.Theme.getSize("toolbox_action_button").height
|
||||
color:
|
||||
{
|
||||
if (base.complete)
|
||||
{
|
||||
return UM.Theme.getColor("action_button_disabled")
|
||||
}
|
||||
else
|
||||
{
|
||||
if (control.hovered)
|
||||
{
|
||||
return UM.Theme.getColor("primary_hover")
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("primary")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
label: Label
|
||||
{
|
||||
text: control.text
|
||||
color:
|
||||
{
|
||||
if (base.complete)
|
||||
{
|
||||
return UM.Theme.getColor("action_button_disabled_text")
|
||||
}
|
||||
else
|
||||
{
|
||||
if (control.hovered)
|
||||
{
|
||||
return UM.Theme.getColor("button_text_hover")
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("button_text")
|
||||
}
|
||||
}
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedImage
|
||||
{
|
||||
id: loader
|
||||
visible: active
|
||||
source: "../images/loading.gif"
|
||||
width: UM.Theme.getSize("toolbox_loader").width
|
||||
height: UM.Theme.getSize("toolbox_loader").height
|
||||
anchors.right: button.left
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.verticalCenter: button.verticalCenter
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ class Toolbox(QObject, Extension):
|
|||
self._plugin_registry = Application.getInstance().getPluginRegistry()
|
||||
self._packages_version = self._getPackagesVersion()
|
||||
self._api_version = 1
|
||||
self._api_url = "https://api-staging.ultimaker.com/cura-packages/v{api_version}/cura/v{package_version}".format( api_version = self._api_version, package_version = self._packages_version)
|
||||
self._api_url = "https://api.ultimaker.com/cura-packages/v{api_version}/cura/v{package_version}".format( api_version = self._api_version, package_version = self._packages_version)
|
||||
|
||||
# Network:
|
||||
self._get_packages_request = None
|
||||
|
@ -61,6 +61,7 @@ class Toolbox(QObject, Extension):
|
|||
"plugins_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)),
|
||||
"materials_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url))
|
||||
}
|
||||
self._to_update = [] # Package_ids that are waiting to be updated
|
||||
|
||||
# Data:
|
||||
self._metadata = {
|
||||
|
@ -216,13 +217,36 @@ class Toolbox(QObject, Extension):
|
|||
|
||||
@pyqtSlot(str)
|
||||
def uninstall(self, plugin_id: str) -> None:
|
||||
self._package_manager.removePackage(plugin_id)
|
||||
self._package_manager.removePackage(plugin_id, force_add = True)
|
||||
self.installChanged.emit()
|
||||
self._updateInstalledModels()
|
||||
self.metadataChanged.emit()
|
||||
self._restart_required = True
|
||||
self.restartRequiredChanged.emit()
|
||||
|
||||
## Actual update packages that are in self._to_update
|
||||
def _update(self) -> None:
|
||||
if self._to_update:
|
||||
plugin_id = self._to_update.pop(0)
|
||||
remote_package = self.getRemotePackage(plugin_id)
|
||||
if remote_package:
|
||||
download_url = remote_package["download_url"]
|
||||
Logger.log("d", "Updating package [%s]..." % plugin_id)
|
||||
if self._package_manager.isUserInstalledPackage(plugin_id):
|
||||
self.uninstall(plugin_id)
|
||||
self.startDownload(download_url)
|
||||
else:
|
||||
Logger.log("e", "Could not update package [%s] because there is no remote package info available.", plugin_id)
|
||||
|
||||
if self._to_update:
|
||||
self._application.callLater(self._update)
|
||||
|
||||
## Update a plugin by plugin_id
|
||||
@pyqtSlot(str)
|
||||
def update(self, plugin_id: str) -> None:
|
||||
self._to_update.append(plugin_id)
|
||||
self._application.callLater(self._update)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def enable(self, plugin_id: str) -> None:
|
||||
self._plugin_registry.enablePlugin(plugin_id)
|
||||
|
@ -251,6 +275,15 @@ class Toolbox(QObject, Extension):
|
|||
def restart(self):
|
||||
CuraApplication.getInstance().windowClosed()
|
||||
|
||||
def getRemotePackage(self, package_id: str) -> Optional[Dict]:
|
||||
# TODO: make the lookup in a dict, not a loop. canUpdate is called for every item.
|
||||
remote_package = None
|
||||
for package in self._metadata["packages"]:
|
||||
if package["package_id"] == package_id:
|
||||
remote_package = package
|
||||
break
|
||||
return remote_package
|
||||
|
||||
# Checks
|
||||
# --------------------------------------------------------------------------
|
||||
@pyqtSlot(str, result = bool)
|
||||
|
@ -259,16 +292,13 @@ class Toolbox(QObject, Extension):
|
|||
if local_package is None:
|
||||
return False
|
||||
|
||||
remote_package = None
|
||||
for package in self._metadata["packages"]:
|
||||
if package["package_id"] == package_id:
|
||||
remote_package = package
|
||||
remote_package = self.getRemotePackage(package_id)
|
||||
if remote_package is None:
|
||||
return False
|
||||
|
||||
local_version = local_package["package_version"]
|
||||
remote_version = remote_package["package_version"]
|
||||
return Version(remote_version) > Version(local_version)
|
||||
local_version = Version(local_package["package_version"])
|
||||
remote_version = Version(remote_package["package_version"])
|
||||
return remote_version > local_version
|
||||
|
||||
@pyqtSlot(str, result = bool)
|
||||
def isInstalled(self, package_id: str) -> bool:
|
||||
|
@ -321,8 +351,8 @@ class Toolbox(QObject, Extension):
|
|||
|
||||
def resetDownload(self) -> None:
|
||||
if self._download_reply:
|
||||
self._download_reply.abort()
|
||||
self._download_reply.downloadProgress.disconnect(self._onDownloadProgress)
|
||||
self._download_reply.abort()
|
||||
self._download_reply = None
|
||||
self._download_request = None
|
||||
self.setDownloadProgress(0)
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
"manufacturer": "101Hero",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform": "101hero-platform.stl",
|
||||
"supports_usb_connection": true
|
||||
"supports_usb_connection": true,
|
||||
"preferred_quality_type": "draft"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
@ -19,7 +20,6 @@
|
|||
"machine_depth": { "default_value": 149.86 },
|
||||
"machine_height": { "default_value": 99.822 },
|
||||
"machine_center_is_zero": { "default_value": true },
|
||||
"layer_height": { "default_value": 0.2 },
|
||||
"machine_nozzle_size": { "default_value": 0.4 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"machine_head_with_fans_polygon": {
|
||||
|
|
|
@ -3703,6 +3703,20 @@
|
|||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"support_wall_count":
|
||||
{
|
||||
"label": "Support Wall Line Count",
|
||||
"description": "The number of walls with which to surround support infill. Adding a wall can make support print more reliably and can support overhangs better, but increases print time and material used.",
|
||||
"default_value": 1,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "1 if support_pattern == 'concentric' else 0",
|
||||
"maximum_value_warning": "3",
|
||||
"type": "int",
|
||||
"value": "1 if (support_pattern == 'grid' or support_pattern == 'triangles' or support_pattern == 'concentric') else 0",
|
||||
"enabled": "support_enable",
|
||||
"limit_to_extruder": "support_infill_extruder_nr",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"zig_zaggify_support":
|
||||
{
|
||||
"label": "Connect Support Lines",
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
"manufacturer": "3DMaker",
|
||||
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "makerstarter_platform.stl"
|
||||
"platform": "makerstarter_platform.stl",
|
||||
"preferred_quality_type": "draft"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
@ -49,9 +50,6 @@
|
|||
"machine_nozzle_expansion_angle": {
|
||||
"default_value": 45
|
||||
},
|
||||
"layer_height": {
|
||||
"default_value": 0.2
|
||||
},
|
||||
"layer_height_0": {
|
||||
"default_value": 0.2
|
||||
},
|
||||
|
|
|
@ -675,7 +675,7 @@ msgstr "G 코드 수정"
|
|||
#: /home/ruben/Projects/Cura/plugins/SupportEraser/__init__.py:12
|
||||
msgctxt "@label"
|
||||
msgid "Support Blocker"
|
||||
msgstr "지지대 차단기"
|
||||
msgstr "서포트 차단기"
|
||||
|
||||
#: /home/ruben/Projects/Cura/plugins/SupportEraser/__init__.py:13
|
||||
msgctxt "@info:tooltip"
|
||||
|
@ -971,7 +971,7 @@ msgstr "펌웨어 업그레이드"
|
|||
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:14
|
||||
msgctxt "@action"
|
||||
msgid "Checkup"
|
||||
msgstr "대조"
|
||||
msgstr "검사"
|
||||
|
||||
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:21
|
||||
msgctxt "@action"
|
||||
|
@ -991,7 +991,7 @@ msgstr "내벽"
|
|||
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:98
|
||||
msgctxt "@tooltip"
|
||||
msgid "Skin"
|
||||
msgstr "외판"
|
||||
msgstr "스킨"
|
||||
|
||||
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:99
|
||||
msgctxt "@tooltip"
|
||||
|
@ -2348,7 +2348,7 @@ msgstr "밀리미터 단위의 빌드 플레이트에서 기저부 높이."
|
|||
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:61
|
||||
msgctxt "@action:label"
|
||||
msgid "Base (mm)"
|
||||
msgstr "바다 (mm)"
|
||||
msgstr "바닥 (mm)"
|
||||
|
||||
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:79
|
||||
msgctxt "@info:tooltip"
|
||||
|
@ -2420,7 +2420,7 @@ msgstr "서포터로 프린팅"
|
|||
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:84
|
||||
msgctxt "@label"
|
||||
msgid "Don't support overlap with other models"
|
||||
msgstr "다른 모델과 오버랩되도록 지지하지 않음"
|
||||
msgstr "다른 모델과 오버랩되도록 지원하지 않음"
|
||||
|
||||
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:92
|
||||
msgctxt "@label"
|
||||
|
@ -3631,7 +3631,7 @@ msgstr "버전: %1"
|
|||
#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:56
|
||||
msgctxt "@label"
|
||||
msgid "End-to-end solution for fused filament 3D printing."
|
||||
msgstr "3D 인쇄를 위해 필라멘트를 한줄로 용."
|
||||
msgstr "3D 프린팅을 위한 엔드 투 엔트 솔루션."
|
||||
|
||||
#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69
|
||||
msgctxt "@info:credit"
|
||||
|
|
|
@ -433,7 +433,7 @@ msgstr "Repetier"
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "machine_firmware_retract label"
|
||||
msgid "Firmware Retraction"
|
||||
msgstr "펌웨어 제거"
|
||||
msgstr "펌웨어 리트렉션"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "machine_firmware_retract description"
|
||||
|
@ -521,7 +521,7 @@ msgstr "노즐의 내경. 비표준 노즐 크기를 사용할 때 이 설정을
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "machine_use_extruder_offset_to_offset_coords label"
|
||||
msgid "Offset With Extruder"
|
||||
msgstr "압출기로 오프셋"
|
||||
msgstr "익스트루더로 오프셋"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "machine_use_extruder_offset_to_offset_coords description"
|
||||
|
@ -531,7 +531,7 @@ msgstr "익스트루더 오프셋을 좌표계에 적용하십시오."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "extruder_prime_pos_z label"
|
||||
msgid "Extruder Prime Z Position"
|
||||
msgstr "압출기 프라임 Z 포지션"
|
||||
msgstr "익스트루더 프라임 Z 포지션"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "extruder_prime_pos_z description"
|
||||
|
@ -543,7 +543,7 @@ msgstr "프린팅가 시작될 때 노즐 위치의 Z 좌표입니다."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "extruder_prime_pos_abs label"
|
||||
msgid "Absolute Extruder Prime Position"
|
||||
msgstr "독립 압출 기 프라임 포지션"
|
||||
msgstr "독립 익스트루더 프라임 포지션"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "extruder_prime_pos_abs description"
|
||||
|
@ -667,7 +667,7 @@ msgstr "Z 방향 모터의 기본 Jerk."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "machine_max_jerk_e label"
|
||||
msgid "Default Filament Jerk"
|
||||
msgstr "기본 Filament Jerk"
|
||||
msgstr "기본 필라멘트 Jerk"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "machine_max_jerk_e description"
|
||||
|
@ -1868,7 +1868,7 @@ msgstr "내부채움 패턴이 Y축을 따라 이 거리만큼 이동합니다."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "sub_div_rad_add label"
|
||||
msgid "Cubic Subdivision Shell"
|
||||
msgstr "입방 세분 내관"
|
||||
msgstr "입방 세분 쉘"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "sub_div_rad_add description"
|
||||
|
@ -2339,7 +2339,7 @@ msgctxt "material_flow description"
|
|||
msgid ""
|
||||
"Flow compensation: the amount of material extruded is multiplied by this "
|
||||
"value."
|
||||
msgstr "유량 보상: 압출 된 재료의 양에 이 값을 곱합니다."
|
||||
msgstr "압출량 보상: 압출 된 재료의 양에 이 값을 곱합니다."
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "material_flow_layer_0 label"
|
||||
|
@ -2420,7 +2420,7 @@ msgstr "리트렉션 이동 중에 필라멘트가 프라이밍되는 속도입
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "retraction_extra_prime_amount label"
|
||||
msgid "Retraction Extra Prime Amount"
|
||||
msgstr "후퇴 Extra 초기 속도"
|
||||
msgstr "추가적인 리트렉션 정도"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "retraction_extra_prime_amount description"
|
||||
|
@ -2433,7 +2433,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "retraction_min_travel label"
|
||||
msgid "Retraction Minimum Travel"
|
||||
msgstr "리트렉션 최소 움직임"
|
||||
msgstr "리트렉션 최소 이동"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "retraction_min_travel description"
|
||||
|
@ -2724,7 +2724,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "speed_travel label"
|
||||
msgid "Travel Speed"
|
||||
msgstr "움직임 속도"
|
||||
msgstr "이동 속도"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "speed_travel description"
|
||||
|
@ -2841,7 +2841,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "speed_equalize_flow_max label"
|
||||
msgid "Maximum Speed for Flow Equalization"
|
||||
msgstr "유량 균등화를위한 최대 속도"
|
||||
msgstr "압출량 균등화를위한 최대 속도"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "speed_equalize_flow_max description"
|
||||
|
@ -3008,7 +3008,7 @@ msgstr "프라임 타워가 프린팅되는 가속도."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "acceleration_travel label"
|
||||
msgid "Travel Acceleration"
|
||||
msgstr "움직임 가속"
|
||||
msgstr "이동 가속"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "acceleration_travel description"
|
||||
|
@ -3038,7 +3038,7 @@ msgstr "초기 레이어 프린팅 중 가속도."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "acceleration_travel_layer_0 label"
|
||||
msgid "Initial Layer Travel Acceleration"
|
||||
msgstr "초기 레이어 움직임 가속도"
|
||||
msgstr "초기 레이어 이동 가속도"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "acceleration_travel_layer_0 description"
|
||||
|
@ -3229,7 +3229,7 @@ msgstr "프라임 타워가 프린팅되는 최대 순간 속도 변화."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "jerk_travel label"
|
||||
msgid "Travel Jerk"
|
||||
msgstr "움직임 Jerk"
|
||||
msgstr "이동 Jerk"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "jerk_travel description"
|
||||
|
@ -3262,7 +3262,7 @@ msgstr "초기 층의 프린팅 중 최대 순간 속도 변화."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "jerk_travel_layer_0 label"
|
||||
msgid "Initial Layer Travel Jerk"
|
||||
msgstr "초기 레이어 움직임 Jerk"
|
||||
msgstr "초기 레이어 이동 Jerk"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "jerk_travel_layer_0 description"
|
||||
|
@ -3284,12 +3284,12 @@ msgstr "스커트와 브림이 프린팅되는 최대 순간 속도 변화."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "travel label"
|
||||
msgid "Travel"
|
||||
msgstr "움직임"
|
||||
msgstr "이동"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "travel description"
|
||||
msgid "travel"
|
||||
msgstr "움직임"
|
||||
msgstr "이동"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "retraction_combing label"
|
||||
|
@ -3320,7 +3320,7 @@ msgstr "모두"
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "retraction_combing option noskin"
|
||||
msgid "No Skin"
|
||||
msgstr "피부가 없다"
|
||||
msgstr "스킨이 없음"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "travel_retract_before_outer_wall label"
|
||||
|
@ -3349,7 +3349,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "travel_avoid_distance label"
|
||||
msgid "Travel Avoid Distance"
|
||||
msgstr "움직일 때 피하기 거리"
|
||||
msgstr "이동중 피하는 거리"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "travel_avoid_distance description"
|
||||
|
@ -3826,7 +3826,7 @@ msgstr "십자"
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "zig_zaggify_support label"
|
||||
msgid "Connect Support Lines"
|
||||
msgstr "지지대 선 연결"
|
||||
msgstr "서포트 선 연결"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "zig_zaggify_support description"
|
||||
|
@ -3966,7 +3966,7 @@ msgstr "X/Y 방향에서 오버행으로부터 서포트까지의 거리. "
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "support_bottom_stair_step_height label"
|
||||
msgid "Support Stair Step Height"
|
||||
msgstr "계단 Step Height 지지대"
|
||||
msgstr "계단 Step Height 서포트"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "support_bottom_stair_step_height description"
|
||||
|
@ -3998,7 +3998,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "support_join_distance label"
|
||||
msgid "Support Join Distance"
|
||||
msgstr "지지대 Join 거리"
|
||||
msgstr "서포트 Join 거리"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "support_join_distance description"
|
||||
|
@ -4013,7 +4013,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "support_offset label"
|
||||
msgid "Support Horizontal Expansion"
|
||||
msgstr "수평 확장 지지대"
|
||||
msgstr "수평 확장 서포트"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "support_offset description"
|
||||
|
@ -5879,7 +5879,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "support_zag_skip_count label"
|
||||
msgid "Support Chunk Line Count"
|
||||
msgstr "Chunk 라인 카운트 지지대"
|
||||
msgstr "Chunk 라인 카운트 서포트"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "support_zag_skip_count description"
|
||||
|
@ -6046,7 +6046,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "skin_alternate_rotation label"
|
||||
msgid "Alternate Skin Rotation"
|
||||
msgstr "대체 피부 회전"
|
||||
msgstr "대체 스킨 회전"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "skin_alternate_rotation description"
|
||||
|
@ -6429,7 +6429,7 @@ msgid ""
|
|||
"Flow compensation: the amount of material extruded is multiplied by this "
|
||||
"value. Only applies to Wire Printing."
|
||||
msgstr ""
|
||||
"유량 보상 : 압출 된 재료의 양에 이 값을 곱합니다. 와이어 프린팅에만 적용됩니"
|
||||
"압출량 보상 : 압출 된 재료의 양에 이 값을 곱합니다. 와이어 프린팅에만 적용됩니"
|
||||
"다."
|
||||
|
||||
#: fdmprinter.def.json
|
||||
|
@ -6440,7 +6440,7 @@ msgstr "WP 연결 흐름"
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "wireframe_flow_connection description"
|
||||
msgid "Flow compensation when going up or down. Only applies to Wire Printing."
|
||||
msgstr "위 또는 아래로 이동할 때 유량 보정. 와이어 프린팅에만 적용됩니다."
|
||||
msgstr "위 또는 아래로 이동할 때 압출량 보정. 와이어 프린팅에만 적용됩니다."
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "wireframe_flow_flat label"
|
||||
|
@ -6451,7 +6451,7 @@ msgstr "WP 플랫 플로우"
|
|||
msgctxt "wireframe_flow_flat description"
|
||||
msgid ""
|
||||
"Flow compensation when printing flat lines. Only applies to Wire Printing."
|
||||
msgstr "평평한 선을 프린팅 할 때 유량 보정. 와이어 프린팅에만 적용됩니다."
|
||||
msgstr "평평한 선을 프린팅 할 때 압출량 보정. 와이어 프린팅에만 적용됩니다."
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "wireframe_top_delay label"
|
||||
|
@ -6496,7 +6496,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "wireframe_up_half_speed label"
|
||||
msgid "WP Ease Upward"
|
||||
msgstr "WP는 쉽게 상향 조정"
|
||||
msgstr "WP 상향 조정"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "wireframe_up_half_speed description"
|
||||
|
@ -6761,7 +6761,7 @@ msgstr ""
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_wall_max_overhang label"
|
||||
msgid "Bridge Wall Max Overhang"
|
||||
msgstr "브리지 벽 최대 돌출"
|
||||
msgstr "브리지 벽 최대 오버행"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_wall_max_overhang description"
|
||||
|
@ -6808,7 +6808,7 @@ msgstr "브릿지 벽이 프린팅되는 속도."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_wall_material_flow label"
|
||||
msgid "Bridge Wall Flow"
|
||||
msgstr "브리지 벽 유량"
|
||||
msgstr "브리지 벽 압출량"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_wall_material_flow description"
|
||||
|
@ -6831,7 +6831,7 @@ msgstr "브릿지 스킨 층이 프린팅되는 속도."
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_skin_material_flow label"
|
||||
msgid "Bridge Skin Flow"
|
||||
msgstr "브리지 스킨 유량"
|
||||
msgstr "브리지 스킨 압출량"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_skin_material_flow description"
|
||||
|
@ -6892,7 +6892,7 @@ msgstr "두번째 브릿지 스킨 레이어를 인쇄 할 때 사용할 인쇄
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_skin_material_flow_2 label"
|
||||
msgid "Bridge Second Skin Flow"
|
||||
msgstr "브리지 두 번째 스킨 유량"
|
||||
msgstr "브리지 두 번째 스킨 압출량"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_skin_material_flow_2 description"
|
||||
|
@ -6939,7 +6939,7 @@ msgstr "세번째 브릿지 스킨 레이어를 인쇄 할 때 사용할 인쇄
|
|||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_skin_material_flow_3 label"
|
||||
msgid "Bridge Third Skin Flow"
|
||||
msgstr "브리지 세 번째 스킨 유량"
|
||||
msgstr "브리지 세 번째 스킨 압출량"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "bridge_skin_material_flow_3 description"
|
||||
|
|
|
@ -179,6 +179,15 @@ Item
|
|||
height: visible ? UM.Theme.getSize("setting_control").height : 0
|
||||
Behavior on height { NumberAnimation { duration: 100 } }
|
||||
|
||||
Timer
|
||||
{
|
||||
id: settingsSearchTimer
|
||||
onTriggered: filter.editingFinished()
|
||||
interval: 500
|
||||
running: false
|
||||
repeat: false
|
||||
}
|
||||
|
||||
TextField
|
||||
{
|
||||
id: filter;
|
||||
|
@ -201,6 +210,11 @@ Item
|
|||
property bool lastFindingSettings: false
|
||||
|
||||
onTextChanged:
|
||||
{
|
||||
settingsSearchTimer.restart()
|
||||
}
|
||||
|
||||
onEditingFinished:
|
||||
{
|
||||
definitionsModel.filter = {"i18n_label": "*" + text};
|
||||
findingSettings = (text.length > 0);
|
||||
|
|
|
@ -220,6 +220,7 @@ support_bottom_extruder_nr
|
|||
support_type
|
||||
support_angle
|
||||
support_pattern
|
||||
support_wall_count
|
||||
zig_zaggify_support
|
||||
support_connect_zigzags
|
||||
support_infill_rate
|
||||
|
|
|
@ -458,6 +458,7 @@
|
|||
"toolbox_header": [1.0, 4.0],
|
||||
"toolbox_progress_bar": [8.0, 0.5],
|
||||
"toolbox_chart_row": [1.0, 2.0],
|
||||
"toolbox_action_button": [8.0, 2.5]
|
||||
"toolbox_action_button": [8.0, 2.5],
|
||||
"toolbox_loader": [2.0, 2.0]
|
||||
}
|
||||
}
|
||||
|
|
13
resources/variants/ultimaker_s5_aluminum.inst.cfg
Normal file
13
resources/variants/ultimaker_s5_aluminum.inst.cfg
Normal file
|
@ -0,0 +1,13 @@
|
|||
[general]
|
||||
name = Aluminum
|
||||
version = 4
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 4
|
||||
type = variant
|
||||
hardware_type = buildplate
|
||||
|
||||
[values]
|
||||
material_bed_temperature = =default_material_bed_temperature + 10
|
||||
machine_buildplate_type = aluminum
|
Loading…
Add table
Add a link
Reference in a new issue