ObjectManager.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from UM.Logger import Logger
  2. from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot
  3. from UM.Application import Application
  4. from UM.Qt.ListModel import ListModel
  5. from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
  6. from UM.Scene.SceneNode import SceneNode
  7. from UM.Scene.Selection import Selection
  8. from PyQt5.QtCore import Qt
  9. from PyQt5.QtWidgets import QApplication
  10. #from cura.Scene.CuraSceneNode import CuraSceneNode
  11. from UM.Preferences import Preferences
  12. ## Keep track of all objects in the project
  13. class ObjectManager(ListModel):
  14. def __init__(self):
  15. super().__init__()
  16. self._last_selected_index = 0
  17. self._build_plate_model = Application.getInstance().getBuildPlateModel()
  18. Application.getInstance().getController().getScene().sceneChanged.connect(self._update)
  19. Preferences.getInstance().preferenceChanged.connect(self._update)
  20. self._build_plate_model.activeBuildPlateChanged.connect(self._update)
  21. def _update(self, *args):
  22. nodes = []
  23. filter_current_build_plate = Preferences.getInstance().getValue("view/filter_current_build_plate")
  24. active_build_plate_number = self._build_plate_model.activeBuildPlate
  25. for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
  26. if not issubclass(type(node), SceneNode) or (not node.getMeshData() and not node.callDecoration("getLayerData")):
  27. continue
  28. if not node.callDecoration("isSliceable"):
  29. continue
  30. node_build_plate_number = node.callDecoration("getBuildPlateNumber")
  31. if filter_current_build_plate and node_build_plate_number != active_build_plate_number:
  32. continue
  33. nodes.append({
  34. "name": node.getName(),
  35. "isSelected": Selection.isSelected(node),
  36. "isOutsideBuildArea": node.isOutsideBuildArea(),
  37. "buildPlateNumber": node_build_plate_number,
  38. "node": node
  39. })
  40. nodes = sorted(nodes, key=lambda n: n["name"])
  41. self.setItems(nodes)
  42. self.itemsChanged.emit()
  43. ## Either select or deselect an item
  44. @pyqtSlot(int)
  45. def changeSelection(self, index):
  46. modifiers = QApplication.keyboardModifiers()
  47. ctrl_is_active = modifiers & Qt.ControlModifier
  48. shift_is_active = modifiers & Qt.ShiftModifier
  49. if ctrl_is_active:
  50. item = self.getItem(index)
  51. node = item["node"]
  52. if Selection.isSelected(node):
  53. Selection.remove(node)
  54. else:
  55. Selection.add(node)
  56. elif shift_is_active:
  57. polarity = 1 if index + 1 > self._last_selected_index else -1
  58. for i in range(self._last_selected_index, index + polarity, polarity):
  59. item = self.getItem(i)
  60. node = item["node"]
  61. Selection.add(node)
  62. else:
  63. # Single select
  64. item = self.getItem(index)
  65. node = item["node"]
  66. Selection.clear()
  67. Selection.add(node)
  68. build_plate_number = node.callDecoration("getBuildPlateNumber")
  69. if build_plate_number is not None and build_plate_number != -1:
  70. self._build_plate_model.setActiveBuildPlate(build_plate_number)
  71. self._last_selected_index = index
  72. # testing
  73. for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
  74. if node.callDecoration("getLayerData"):
  75. Logger.log("d", " ##### NODE: %s", node)
  76. @staticmethod
  77. def createObjectManager():
  78. return ObjectManager()