Skip to content

Commit 61cfa88

Browse files
committed
Fix opening the Cura window
It looks like there is a possible racecondition caused by the presence of qml/RenameDialog.qml inside a resource searchpath. contributes to #35
1 parent 5982ec6 commit 61cfa88

File tree

4 files changed

+53
-54
lines changed

4 files changed

+53
-54
lines changed

MeshTools.py

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,23 @@
4949

5050
from typing import Optional, List, Dict
5151

52-
Resources.addSearchPath(
53-
os.path.join(
54-
os.path.abspath(os.path.dirname(__file__)),
55-
"resources"
56-
)
57-
) # Plugin translation file import
58-
59-
catalog = i18nCatalog("meshtools")
60-
6152

6253
class MeshTools(Extension, QObject,):
6354
def __init__(self, parent = None) -> None:
6455
QObject.__init__(self, parent)
6556
Extension.__init__(self)
6657

67-
self._application = CuraApplication.getInstance()
58+
Resources.addSearchPath(
59+
os.path.join(
60+
os.path.abspath(os.path.dirname(__file__)),
61+
"resources"
62+
)
63+
) # Plugin translation file import
64+
self._catalog = i18nCatalog("meshtools")
65+
66+
self._qml_folder = "qml_qt6" if not USE_QT5 else "qml_qt5"
6867

69-
self._qml_folder = "qml" if not USE_QT5 else "qml_qt5"
68+
self._application = CuraApplication.getInstance()
7069

7170
self._application.engineCreatedSignal.connect(self._onEngineCreated)
7271
self._application.fileLoaded.connect(self._onFileLoaded)
@@ -88,23 +87,23 @@ def __init__(self, parent = None) -> None:
8887
self._preferences.addPreference("meshtools/randomise_location_on_load", False)
8988
self._preferences.addPreference("meshtools/model_unit_factor", 1)
9089

91-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Reload model"), self.reloadMesh)
92-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Rename model..."), self.renameMesh)
93-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Replace models..."), self.replaceMeshes)
90+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Reload model"), self.reloadMesh)
91+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Rename model..."), self.renameMesh)
92+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Replace models..."), self.replaceMeshes)
9493
self.addMenuItem("", lambda: None)
95-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Check models"), self.checkMeshes)
96-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Analyse models"), self.analyseMeshes)
97-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Fix simple holes"), self.fixSimpleHolesForMeshes)
98-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Fix model normals"), self.fixNormalsForMeshes)
99-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Split model into parts"), self.splitMeshes)
94+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Check models"), self.checkMeshes)
95+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Analyse models"), self.analyseMeshes)
96+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Fix simple holes"), self.fixSimpleHolesForMeshes)
97+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Fix model normals"), self.fixNormalsForMeshes)
98+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Split model into parts"), self.splitMeshes)
10099
self.addMenuItem(" ", lambda: None)
101-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Randomise location"), self.randomiseMeshLocation)
102-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Apply transformations to mesh"), self.bakeMeshTransformation)
103-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Reset origin to center of mesh"), self.resetMeshOrigin)
100+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Randomise location"), self.randomiseMeshLocation)
101+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Apply transformations to mesh"), self.bakeMeshTransformation)
102+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Reset origin to center of mesh"), self.resetMeshOrigin)
104103
self.addMenuItem(" ", lambda: None)
105-
self.addMenuItem(catalog.i18nc("@item:inmenu", "Mesh Tools settings..."), self.showSettingsDialog)
104+
self.addMenuItem(self._catalog.i18nc("@item:inmenu", "Mesh Tools settings..."), self.showSettingsDialog)
106105

107-
self._message = Message(title=catalog.i18nc("@info:title", "Mesh Tools"))
106+
self._message = Message(title=self._catalog.i18nc("@info:title", "Mesh Tools"))
108107
self._additional_menu = None # type: Optional[QObject]
109108

110109
def showSettingsDialog(self) -> None:
@@ -155,7 +154,7 @@ def _onEngineCreated(self) -> None:
155154

156155
if USE_QT5:
157156
context_menu.insertSeparator(0)
158-
context_menu.insertMenu(0, catalog.i18nc("@info:title", "Mesh Tools"))
157+
context_menu.insertMenu(0, self._catalog.i18nc("@info:title", "Mesh Tools"))
159158

160159
# Move additional menu items into context menu
161160
self._additional_menu.moveToContextMenu(context_menu)
@@ -223,23 +222,23 @@ def checkQueuedNodes(self) -> None:
223222

224223
if self._preferences.getValue("meshtools/check_models_on_load") and not tri_node.is_watertight:
225224
if not file_name:
226-
file_name = catalog.i18nc("@text Print job name", "Untitled")
225+
file_name = self._catalog.i18nc("@text Print job name", "Untitled")
227226
base_name = os.path.basename(file_name)
228227

229228
if file_name in self._mesh_not_watertight_messages:
230229
self._mesh_not_watertight_messages[file_name].hide()
231230

232-
message = Message(title=catalog.i18nc("@info:title", "Mesh Tools"))
233-
body = catalog.i18nc("@info:status", "Model %s is not watertight, and may not print properly.") % base_name
231+
message = Message(title=self._catalog.i18nc("@info:title", "Mesh Tools"))
232+
body = self._catalog.i18nc("@info:status", "Model %s is not watertight, and may not print properly.") % base_name
234233

235234
# XRayView may not be available if the plugin has been disabled
236235
active_view = self._controller.getActiveView()
237236
if active_view and "XRayView" in self._controller.getAllViews() and active_view.getPluginId() != "XRayView":
238-
body += " " + catalog.i18nc("@info:status", "Check X-Ray View and repair the model before printing it.")
239-
message.addAction("X-Ray", catalog.i18nc("@action:button", "Show X-Ray View"), "", "")
237+
body += " " + self._catalog.i18nc("@info:status", "Check X-Ray View and repair the model before printing it.")
238+
message.addAction("X-Ray", self._catalog.i18nc("@action:button", "Show X-Ray View"), "", "")
240239
message.actionTriggered.connect(self._showXRayView)
241240
else:
242-
body += " " +catalog.i18nc("@info:status", "Repair the model before printing it.")
241+
body += " " +self._catalog.i18nc("@info:status", "Repair the model before printing it.")
243242

244243
message.setText(body)
245244
message.show()
@@ -277,12 +276,12 @@ def _getSelectedNodes(self, force_single = False) -> List[SceneNode]:
277276
if len(selection) == 1:
278277
return selection[:]
279278

280-
self._message.setText(catalog.i18nc("@info:status", "Please select a single model first"))
279+
self._message.setText(self._catalog.i18nc("@info:status", "Please select a single model first"))
281280
else:
282281
if len(selection) >= 1:
283282
return selection[:]
284283

285-
self._message.setText(catalog.i18nc("@info:status", "Please select one or more models first"))
284+
self._message.setText(self._catalog.i18nc("@info:status", "Please select one or more models first"))
286285

287286
self._message.show()
288287
return []
@@ -300,7 +299,7 @@ def _getAllSelectedNodes(self) -> List[SceneNode]:
300299
if deep_selection:
301300
return deep_selection
302301

303-
self._message.setText(catalog.i18nc("@info:status", "Please select one or more models first"))
302+
self._message.setText(self._catalog.i18nc("@info:status", "Please select one or more models first"))
304303
self._message.show()
305304

306305
return []
@@ -311,16 +310,16 @@ def checkMeshes(self) -> None:
311310
if not nodes_list:
312311
return
313312

314-
message_body = catalog.i18nc("@info:status", "Check summary:")
313+
message_body = self._catalog.i18nc("@info:status", "Check summary:")
315314
for node in nodes_list:
316315
tri_node = self._toTriMesh(node.getMeshData())
317316
message_body = message_body + "\n - %s" % node.getName()
318317
if tri_node.is_watertight:
319-
message_body = message_body + " " + catalog.i18nc("@info:status", "is watertight")
318+
message_body = message_body + " " + self._catalog.i18nc("@info:status", "is watertight")
320319
else:
321-
message_body = message_body + " " + catalog.i18nc("@info:status", "is not watertight and may not print properly")
320+
message_body = message_body + " " + self._catalog.i18nc("@info:status", "is not watertight and may not print properly")
322321
if tri_node.body_count > 1:
323-
message_body = message_body + " " + catalog.i18nc("@info:status", "and consists of {body_count} submeshes").format(body_count = tri_node.body_count)
322+
message_body = message_body + " " + self._catalog.i18nc("@info:status", "and consists of {body_count} submeshes").format(body_count = tri_node.body_count)
324323

325324
self._message.setText(message_body)
326325
self._message.show()
@@ -331,13 +330,13 @@ def analyseMeshes(self) -> None:
331330
if not nodes_list:
332331
return
333332

334-
message_body = catalog.i18nc("@info:status", "Analysis summary:")
333+
message_body = self._catalog.i18nc("@info:status", "Analysis summary:")
335334
for node in nodes_list:
336335
tri_node = self._toTriMesh(node.getMeshDataTransformed())
337336
message_body = message_body + "\n - %s:" % node.getName()
338-
message_body += "\n\t" + catalog.i18nc("@info:status", "%d vertices, %d faces") % (len(tri_node.vertices), len(tri_node.faces))
337+
message_body += "\n\t" + self._catalog.i18nc("@info:status", "%d vertices, %d faces") % (len(tri_node.vertices), len(tri_node.faces))
339338
if tri_node.is_watertight:
340-
message_body += "\n\t" + catalog.i18nc("@info:status", "area: %d mm2, volume: %d mm3") % (tri_node.area, tri_node.volume)
339+
message_body += "\n\t" + self._catalog.i18nc("@info:status", "area: %d mm2, volume: %d mm3") % (tri_node.area, tri_node.volume)
341340

342341
self._message.setText(message_body)
343342
self._message.show()
@@ -353,7 +352,7 @@ def fixSimpleHolesForMeshes(self) -> None:
353352
success = tri_node.fill_holes()
354353
self._replaceSceneNode(node, [tri_node])
355354
if not success:
356-
self._message.setText(catalog.i18nc(
355+
self._message.setText(self._catalog.i18nc(
357356
"@info:status",
358357
"The mesh needs more extensive repair to become watertight"
359358
))
@@ -376,15 +375,15 @@ def splitMeshes(self) -> None:
376375
if not nodes_list:
377376
return
378377

379-
message_body = catalog.i18nc("@info:status", "Split result:")
378+
message_body = self._catalog.i18nc("@info:status", "Split result:")
380379
for node in nodes_list:
381380
message_body = message_body + "\n - %s" % node.getName()
382381
tri_node = self._toTriMesh(node.getMeshData())
383382
if tri_node.body_count > 1:
384383
self._replaceSceneNode(node, tri_node.split(only_watertight=False))
385-
message_body = message_body + " " + catalog.i18nc("@info:status", "was split in %d submeshes") % tri_node.body_count
384+
message_body = message_body + " " + self._catalog.i18nc("@info:status", "was split in %d submeshes") % tri_node.body_count
386385
else:
387-
message_body = message_body + " " + catalog.i18nc("@info:status", "could not be split into submeshes")
386+
message_body = message_body + " " + self._catalog.i18nc("@info:status", "could not be split into submeshes")
388387

389388
self._message.setText(message_body)
390389
self._message.show()
@@ -398,7 +397,7 @@ def replaceMeshes(self) -> None:
398397
for node in self._node_queue:
399398
mesh_data = node.getMeshData()
400399
if not mesh_data:
401-
self._message.setText(catalog.i18nc("@info:status", "Replacing a group is not supported"))
400+
self._message.setText(self._catalog.i18nc("@info:status", "Replacing a group is not supported"))
402401
self._message.show()
403402
self._node_queue = [] #type: List[SceneNode]
404403
return
@@ -419,12 +418,12 @@ def replaceMeshes(self) -> None:
419418

420419
file_name, _ = QFileDialog.getOpenFileName(
421420
parent=None,
422-
caption=catalog.i18nc("@title:window", "Select Replacement Mesh File"),
421+
caption=self._catalog.i18nc("@title:window", "Select Replacement Mesh File"),
423422
directory=directory, options=options, filter=filter_types
424423
)
425424
else:
426425
dialog = QFileDialog()
427-
dialog.setWindowTitle(catalog.i18nc("@title:window", "Select Replacement Mesh File"))
426+
dialog.setWindowTitle(self._catalog.i18nc("@title:window", "Select Replacement Mesh File"))
428427
dialog.setDirectory(directory)
429428
dialog.setNameFilters(self._application.getMeshFileHandler().supportedReadFileTypes)
430429
dialog.setAcceptMode(QFileDialog.AcceptMode.AcceptOpen)
@@ -473,14 +472,14 @@ def reloadMesh(self) -> None:
473472

474473
mesh_data = self._node_queue[0].getMeshData()
475474
if not mesh_data:
476-
self._message.setText(catalog.i18nc("@info:status", "Reloading a group is not supported"))
475+
self._message.setText(self._catalog.i18nc("@info:status", "Reloading a group is not supported"))
477476
self._message.show()
478477
self._node_queue = [] #type: List[SceneNode]
479478
return
480479

481480
file_name = mesh_data.getFileName()
482481
if not file_name:
483-
self._message.setText(catalog.i18nc("@info:status", "No link to the original file was found"))
482+
self._message.setText(self._catalog.i18nc("@info:status", "No link to the original file was found"))
484483
self._message.show()
485484
self._node_queue = [] #type: List[SceneNode]
486485
return
@@ -492,14 +491,14 @@ def reloadMesh(self) -> None:
492491
def _readMeshFinished(self, job) -> None:
493492
job_result = job.getResult()
494493
if len(job_result) == 0:
495-
self._message.setText(catalog.i18nc("@info:status", "Failed to load mesh"))
494+
self._message.setText(self._catalog.i18nc("@info:status", "Failed to load mesh"))
496495
self._message.show()
497496
self._node_queue = [] #type: List[SceneNode]
498497
return
499498

500499
mesh_data = job_result[0].getMeshData()
501500
if not mesh_data:
502-
self._message.setText(catalog.i18nc("@info:status", "Replacing meshes with a group of meshes is not supported"))
501+
self._message.setText(self._catalog.i18nc("@info:status", "Replacing meshes with a group of meshes is not supported"))
503502
self._message.show()
504503
self._node_queue = [] #type: List[SceneNode]
505504
return
@@ -508,7 +507,7 @@ def _readMeshFinished(self, job) -> None:
508507
if file_name:
509508
mesh_name = os.path.basename(file_name)
510509
else:
511-
mesh_name = catalog.i18nc("@text Print job name", "Untitled")
510+
mesh_name = self._catalog.i18nc("@text Print job name", "Untitled")
512511

513512
has_merged_nodes = False
514513

@@ -572,7 +571,7 @@ def bakeMeshTransformation(self) -> None:
572571
file_name = ""
573572
mesh_name = os.path.basename(file_name)
574573
if not mesh_name:
575-
mesh_name = catalog.i18nc("@text Print job name", "Untitled")
574+
mesh_name = self._catalog.i18nc("@text Print job name", "Untitled")
576575

577576
local_transformation = node.getLocalTransformation()
578577
position = local_transformation.getTranslation()
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)