Merge branch 'master' into CURA-6793_performance

Conflicts:
	cura/Machines/MaterialManager.py -> File was deleted in Master but I changed things for the lazy loading.
	cura/Machines/Models/BaseMaterialsModel.py -> I clarified documentation on a line above a place where a timer was added in between.

Contributes to issue CURA-6793.
This commit is contained in:
Ghostkeeper 2019-10-23 09:58:08 +02:00
commit 94eb76a844
No known key found for this signature in database
GPG key ID: 59A4C0959592C05C
318 changed files with 881 additions and 2183 deletions

View file

@ -1,9 +1,9 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, Dict, Set
from typing import Dict, Set
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtProperty
from UM.Qt.ListModel import ListModel
@ -38,14 +38,25 @@ class BaseMaterialsModel(ListModel):
self._extruder_stack = None
self._enabled = True
# CURA-6904
# Updating the material model requires information from material nodes and containers. We use a timer here to
# make sure that an update function call will not be directly invoked by an event. Because the triggered event
# can be caused in the middle of a XMLMaterial loading, and the material container we try to find may not be
# in the system yet. This will cause an infinite recursion of (1) trying to load a material, (2) trying to
# update the material model, (3) cannot find the material container, load it, (4) repeat #1.
self._update_timer = QTimer()
self._update_timer.setInterval(100)
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._update)
# Update the stack and the model data when the machine changes
self._machine_manager.globalContainerChanged.connect(self._updateExtruderStack)
self._updateExtruderStack()
# Update this model when switching machines or tabs, when adding materials or changing their metadata.
self._machine_manager.activeStackChanged.connect(self._update)
self._machine_manager.activeStackChanged.connect(self._onChanged)
ContainerTree.getInstance().materialsChanged.connect(self._materialsListChanged)
self._application.getMaterialManagementModel().favoritesChanged.connect(self._update)
self._application.getMaterialManagementModel().favoritesChanged.connect(self._onChanged)
self.addRoleName(Qt.UserRole + 1, "root_material_id")
self.addRoleName(Qt.UserRole + 2, "id")
@ -64,14 +75,17 @@ class BaseMaterialsModel(ListModel):
self.addRoleName(Qt.UserRole + 15, "container_node")
self.addRoleName(Qt.UserRole + 16, "is_favorite")
def _onChanged(self) -> None:
self._update_timer.start()
def _updateExtruderStack(self):
global_stack = self._machine_manager.activeMachine
if global_stack is None:
return
if self._extruder_stack is not None:
self._extruder_stack.pyqtContainersChanged.disconnect(self._update)
self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._update)
self._extruder_stack.pyqtContainersChanged.disconnect(self._onChanged)
self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._onChanged)
try:
self._extruder_stack = global_stack.extruderList[self._extruder_position]
@ -79,10 +93,10 @@ class BaseMaterialsModel(ListModel):
self._extruder_stack = None
if self._extruder_stack is not None:
self._extruder_stack.pyqtContainersChanged.connect(self._update)
self._extruder_stack.approximateMaterialDiameterChanged.connect(self._update)
self._extruder_stack.pyqtContainersChanged.connect(self._onChanged)
self._extruder_stack.approximateMaterialDiameterChanged.connect(self._onChanged)
# Force update the model when the extruder stack changes
self._update()
self._onChanged()
def setExtruderPosition(self, position: int):
if self._extruder_stack is None or self._extruder_position != position:
@ -99,7 +113,7 @@ class BaseMaterialsModel(ListModel):
self._enabled = enabled
if self._enabled:
# ensure the data is there again.
self._update()
self._onChanged()
self.enabledChanged.emit()
@pyqtProperty(bool, fset = setEnabled, notify = enabledChanged)
@ -119,12 +133,12 @@ class BaseMaterialsModel(ListModel):
return
if material.variant.machine.container_id != global_stack.definition.getId():
return
self._update()
self._onChanged()
## Triggered when the list of favorite materials is changed.
def _favoritesChanged(self, material_base_file: str) -> None:
if material_base_file in self._available_materials:
self._update()
self._onChanged()
## This is an abstract method that needs to be implemented by the specific
# models themselves.