Merge branch 'master' into feature-backup-manager

This commit is contained in:
ChrisTerBeke 2018-05-15 16:50:25 +02:00
commit d27ac3cf31
7 changed files with 47 additions and 35 deletions

View file

@ -207,6 +207,7 @@ class CuraApplication(QtApplication):
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions( UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().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"), ("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"), ("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"), ("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),

View file

@ -18,9 +18,6 @@ from UM.Version import Version
class CuraPackageManager(QObject): class CuraPackageManager(QObject):
Version = 1 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): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
@ -171,7 +168,7 @@ class CuraPackageManager(QObject):
package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id)
# If the package ID is in bundled, label it as such # 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 there is not a section in the dict for this type, add it
if package_info["package_type"] not in installed_packages_dict: if package_info["package_type"] not in installed_packages_dict:
@ -182,7 +179,7 @@ class CuraPackageManager(QObject):
return installed_packages_dict 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: def isPackageInstalled(self, package_id: str) -> bool:
return self.getInstalledPackageInfo(package_id) is not None return self.getInstalledPackageInfo(package_id) is not None
@ -242,7 +239,7 @@ class CuraPackageManager(QObject):
Logger.log("i", "Attempt to remove package [%s] that is not installed, do nothing.", package_id) Logger.log("i", "Attempt to remove package [%s] that is not installed, do nothing.", package_id)
return return
# Temp hack # Extra safety check
if package_id not in self._installed_package_dict and package_id in self._bundled_package_dict: 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.") Logger.log("i", "Not uninstalling [%s] because it is a bundled package.")
return return
@ -258,6 +255,10 @@ class CuraPackageManager(QObject):
self._saveManagementData() self._saveManagementData()
self.installedPackagesChanged.emit() 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. # Removes everything associated with the given package ID.
def _purgePackage(self, package_id: str) -> None: def _purgePackage(self, package_id: str) -> None:
# Iterate through all directories in the data storage directory and look for sub-directories that belong to # Iterate through all directories in the data storage directory and look for sub-directories that belong to
@ -308,27 +309,15 @@ class CuraPackageManager(QObject):
if not os.path.exists(src_dir_path): if not os.path.exists(src_dir_path):
continue continue
self.__installPackageFiles(package_id, src_dir_path, dst_dir_path)
# 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)
# Remove the file # Remove the file
os.remove(filename) 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) 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. # Gets package information from the given file.
def getPackageInfo(self, filename: str) -> Dict[str, Any]: def getPackageInfo(self, filename: str) -> Dict[str, Any]:
with zipfile.ZipFile(filename) as archive: with zipfile.ZipFile(filename) as archive:

View file

@ -113,8 +113,6 @@ class MaterialManager(QObject):
grouped_by_type_dict = dict() grouped_by_type_dict = dict()
material_types_without_fallback = set() material_types_without_fallback = set()
for root_material_id, material_node in self._material_group_map.items(): 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"] material_type = material_node.root_material_node.metadata["material"]
if material_type not in grouped_by_type_dict: if material_type not in grouped_by_type_dict:
grouped_by_type_dict[material_type] = {"generic": None, 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") diameter = material_node.root_material_node.metadata.get("approximate_diameter")
if diameter != self._default_approximate_diameter_for_quality_search: if diameter != self._default_approximate_diameter_for_quality_search:
to_add = False # don't add if it's not the default diameter to_add = False # don't add if it's not the default diameter
if to_add: if to_add:
grouped_by_type_dict[material_type] = material_node.root_material_node.metadata # Checking this first allow us to differentiate between not read only materials:
material_types_without_fallback.remove(material_type) # - 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 # Remove the materials that have no fallback materials
for material_type in material_types_without_fallback: for material_type in material_types_without_fallback:
del grouped_by_type_dict[material_type] del grouped_by_type_dict[material_type]
@ -147,9 +151,6 @@ class MaterialManager(QObject):
material_group_dict = dict() material_group_dict = dict()
keys_to_fetch = ("name", "material", "brand", "color") keys_to_fetch = ("name", "material", "brand", "color")
for root_material_id, machine_node in self._material_group_map.items(): 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 root_material_metadata = machine_node.root_material_node.metadata
key_data = [] key_data = []
@ -157,8 +158,13 @@ class MaterialManager(QObject):
key_data.append(root_material_metadata.get(key)) key_data.append(root_material_metadata.get(key))
key_data = tuple(key_data) 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: if key_data not in material_group_dict:
material_group_dict[key_data] = 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") approximate_diameter = root_material_metadata.get("approximate_diameter")
material_group_dict[key_data][approximate_diameter] = root_material_metadata["id"] material_group_dict[key_data][approximate_diameter] = root_material_metadata["id"]

View file

@ -14,9 +14,9 @@ Item
property var active: false property var active: false
property var complete: false property var complete: false
property var readyLabel: "Install" property var readyLabel: catalog.i18nc("@action:button", "Install")
property var activeLabel: "Installing" property var activeLabel: catalog.i18nc("@action:button", "Cancel")
property var completeLabel: "Installed" property var completeLabel: catalog.i18nc("@action:button", "Installed")
property var readyAction: null // Action when button is ready and clicked (likely install) 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 activeAction: null // Action when button is active and clicked (likely cancel)
@ -32,15 +32,15 @@ Item
{ {
if (complete) if (complete)
{ {
return catalog.i18nc("@action:button", "Installed") return completeLabel
} }
else if (active) else if (active)
{ {
return catalog.i18nc("@action:button", "Cancel") return activeLabel
} }
else else
{ {
return catalog.i18nc("@action:button", "Install") return readyLabel
} }
} }
onClicked: onClicked:

View file

@ -250,7 +250,8 @@ class Toolbox(QObject, Extension):
if remote_package: if remote_package:
download_url = remote_package["download_url"] download_url = remote_package["download_url"]
Logger.log("d", "Updating package [%s]..." % plugin_id) Logger.log("d", "Updating package [%s]..." % plugin_id)
self.uninstall(plugin_id) if self._package_manager.isUserInstalledPackage(plugin_id):
self.uninstall(plugin_id)
self.startDownload(download_url) self.startDownload(download_url)
else: else:
Logger.log("e", "Could not update package [%s] because there is no remote package info available.", plugin_id) Logger.log("e", "Could not update package [%s] because there is no remote package info available.", plugin_id)

View file

@ -3703,6 +3703,20 @@
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "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": "zig_zaggify_support":
{ {
"label": "Connect Support Lines", "label": "Connect Support Lines",

View file

@ -220,6 +220,7 @@ support_bottom_extruder_nr
support_type support_type
support_angle support_angle
support_pattern support_pattern
support_wall_count
zig_zaggify_support zig_zaggify_support
support_connect_zigzags support_connect_zigzags
support_infill_rate support_infill_rate