UCPDialog.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # Copyright (c) 2024 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import os
  4. from PyQt6.QtCore import pyqtSignal, QObject
  5. import UM
  6. from UM.FlameProfiler import pyqtSlot
  7. from UM.OutputDevice import OutputDeviceError
  8. from UM.Workspace.WorkspaceWriter import WorkspaceWriter
  9. from UM.i18n import i18nCatalog
  10. from UM.Logger import Logger
  11. from UM.Message import Message
  12. from cura.CuraApplication import CuraApplication
  13. from .SettingsExportModel import SettingsExportModel
  14. i18n_catalog = i18nCatalog("cura")
  15. class UCPDialog(QObject):
  16. finished = pyqtSignal(bool)
  17. def __init__(self, parent = None) -> None:
  18. super().__init__(parent)
  19. plugin_path = os.path.dirname(__file__)
  20. dialog_path = os.path.join(plugin_path, 'UCPDialog.qml')
  21. self._model = SettingsExportModel()
  22. self._view = CuraApplication.getInstance().createQmlComponent(
  23. dialog_path,
  24. {
  25. "manager": self,
  26. "settingsExportModel": self._model
  27. }
  28. )
  29. self._view.accepted.connect(self._onAccepted)
  30. self._view.rejected.connect(self._onRejected)
  31. self._finished = False
  32. self._accepted = False
  33. def show(self) -> None:
  34. self._finished = False
  35. self._accepted = False
  36. self._view.show()
  37. def getModel(self) -> SettingsExportModel:
  38. return self._model
  39. @pyqtSlot()
  40. def notifyClosed(self):
  41. self._onFinished()
  42. def save3mf(self):
  43. application = CuraApplication.getInstance()
  44. workspace_handler = application.getInstance().getWorkspaceFileHandler()
  45. # Set the model to the workspace writer
  46. mesh_writer = workspace_handler.getWriter("3MFWriter")
  47. mesh_writer.setExportModel(self._model)
  48. # Open file dialog and write the file
  49. device = application.getOutputDeviceManager().getOutputDevice("local_file")
  50. nodes = [application.getController().getScene().getRoot()]
  51. device.writeError.connect(lambda: self._onRejected())
  52. device.writeSuccess.connect(lambda: self._onSuccess())
  53. device.writeFinished.connect(lambda: self._onFinished())
  54. file_name = CuraApplication.getInstance().getPrintInformation().baseName
  55. try:
  56. device.requestWrite(
  57. nodes,
  58. file_name,
  59. ["application/vnd.ms-package.3dmanufacturing-3dmodel+xml"],
  60. workspace_handler,
  61. preferred_mimetype_list="application/vnd.ms-package.3dmanufacturing-3dmodel+xml"
  62. )
  63. except OutputDeviceError.UserCanceledError:
  64. self._onRejected()
  65. except Exception as e:
  66. message = Message(
  67. i18n_catalog.i18nc("@info:error", "Unable to write to file: {0}", file_name),
  68. title=i18n_catalog.i18nc("@info:title", "Error"),
  69. message_type=Message.MessageType.ERROR
  70. )
  71. message.show()
  72. Logger.logException("e", "Unable to write to file %s: %s", file_name, e)
  73. self._onRejected()
  74. def _onAccepted(self):
  75. self.save3mf()
  76. def _onRejected(self):
  77. self._onFinished()
  78. def _onSuccess(self):
  79. self._accepted = True
  80. self._onFinished()
  81. def _onFinished(self):
  82. # Make sure we don't send the finished signal twice, whatever happens
  83. if self._finished:
  84. return
  85. self._finished = True
  86. # Reset the model to the workspace writer
  87. mesh_writer = CuraApplication.getInstance().getInstance().getWorkspaceFileHandler().getWriter("3MFWriter")
  88. mesh_writer.setExportModel(None)
  89. self.finished.emit(self._accepted)