WorkspaceDialog.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. from PyQt5.QtCore import Qt, QUrl, pyqtSignal, pyqtSlot, QObject, pyqtProperty, QCoreApplication
  2. from PyQt5.QtQml import QQmlComponent, QQmlContext
  3. from UM.PluginRegistry import PluginRegistry
  4. from UM.Application import Application
  5. from UM.Logger import Logger
  6. import os
  7. import threading
  8. import time
  9. class WorkspaceDialog(QObject):
  10. showDialogSignal = pyqtSignal()
  11. def __init__(self, parent = None):
  12. super().__init__(parent)
  13. self._component = None
  14. self._context = None
  15. self._view = None
  16. self._qml_url = "WorkspaceDialog.qml"
  17. self._lock = threading.Lock()
  18. self._default_strategy = "override"
  19. self._result = {"machine": self._default_strategy,
  20. "quality_changes": self._default_strategy,
  21. "material": self._default_strategy}
  22. self._visible = False
  23. self.showDialogSignal.connect(self.__show)
  24. self._has_quality_changes_conflict = False
  25. self._has_machine_conflict = False
  26. self._has_material_conflict = False
  27. machineConflictChanged = pyqtSignal()
  28. qualityChangesConflictChanged = pyqtSignal()
  29. materialConflictChanged = pyqtSignal()
  30. @pyqtProperty(bool, notify = machineConflictChanged)
  31. def machineConflict(self):
  32. return self._has_machine_conflict
  33. @pyqtProperty(bool, notify=qualityChangesConflictChanged)
  34. def qualityChangesConflict(self):
  35. return self._has_quality_changes_conflict
  36. @pyqtProperty(bool, notify=materialConflictChanged)
  37. def materialConflict(self):
  38. return self._has_material_conflict
  39. @pyqtSlot(str, str)
  40. def setResolveStrategy(self, key, strategy):
  41. if key in self._result:
  42. self._result[key] = strategy
  43. def setMaterialConflict(self, material_conflict):
  44. self._has_material_conflict = material_conflict
  45. self.materialConflictChanged.emit()
  46. def setMachineConflict(self, machine_conflict):
  47. self._has_machine_conflict = machine_conflict
  48. self.machineConflictChanged.emit()
  49. def setQualityChangesConflict(self, quality_changes_conflict):
  50. self._has_quality_changes_conflict = quality_changes_conflict
  51. self.qualityChangesConflictChanged.emit()
  52. def getResult(self):
  53. if "machine" in self._result and not self._has_machine_conflict:
  54. self._result["machine"] = None
  55. if "quality_changes" in self._result and not self._has_quality_changes_conflict:
  56. self._result["quality_changes"] = None
  57. if "material" in self._result and not self._has_material_conflict:
  58. self._result["material"] = None
  59. return self._result
  60. def _createViewFromQML(self):
  61. path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url))
  62. self._component = QQmlComponent(Application.getInstance()._engine, path)
  63. self._context = QQmlContext(Application.getInstance()._engine.rootContext())
  64. self._context.setContextProperty("manager", self)
  65. self._view = self._component.create(self._context)
  66. if self._view is None:
  67. Logger.log("c", "QQmlComponent status %s", self._component.status())
  68. Logger.log("c", "QQmlComponent error string %s", self._component.errorString())
  69. def show(self):
  70. # Emit signal so the right thread actually shows the view.
  71. if threading.current_thread() != threading.main_thread():
  72. self._lock.acquire()
  73. # Reset the result
  74. self._result = {"machine": self._default_strategy,
  75. "quality_changes": self._default_strategy,
  76. "material": self._default_strategy}
  77. self._visible = True
  78. self.showDialogSignal.emit()
  79. @pyqtSlot()
  80. ## Used to notify the dialog so the lock can be released.
  81. def notifyClosed(self):
  82. if self._result is None:
  83. self._result = {}
  84. self._lock.release()
  85. def hide(self):
  86. self._visible = False
  87. self._lock.release()
  88. self._view.hide()
  89. @pyqtSlot()
  90. def onOkButtonClicked(self):
  91. self._view.hide()
  92. self.hide()
  93. @pyqtSlot()
  94. def onCancelButtonClicked(self):
  95. self._view.hide()
  96. self.hide()
  97. self._result = {}
  98. ## Block thread until the dialog is closed.
  99. def waitForClose(self):
  100. if self._visible:
  101. if threading.current_thread() != threading.main_thread():
  102. self._lock.acquire()
  103. self._lock.release()
  104. else:
  105. # If this is not run from a separate thread, we need to ensure that the events are still processed.
  106. while self._visible:
  107. time.sleep(1 / 50)
  108. QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
  109. def __show(self):
  110. if self._view is None:
  111. self._createViewFromQML()
  112. if self._view:
  113. self._view.show()