1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
25 from MGCleanerPlugDialog import Ui_MGCleanerPlugDialog
26 from MGCleanerMonViewText import MGCleanerMonViewText
27 from PyQt4.QtGui import *
28 from PyQt4.QtCore import *
31 class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget):
35 QWidget.__init__(self)
37 self.connecterSignaux()
43 self.__selectedMesh=None
45 # complex whith QResources: not used
46 # The icon are supposed to be located in the $SMESH_ROOT_DIR/share/salome/resources/smesh folder,
47 # other solution could be in the same folder than this python module file:
48 # iconfolder=os.path.dirname(os.path.abspath(__file__))
50 self.iconfolder=os.environ["SMESH_ROOT_DIR"]+"/share/salome/resources/smesh"
51 #print "MGCleanerMonPlugDialog iconfolder",iconfolder
53 icon.addFile(os.path.join(self.iconfolder,"select1.png"))
54 self.PB_LoadHyp.setIcon(icon)
55 self.PB_LoadHyp.setToolTip("hypothesis from Salome Object Browser")
56 self.PB_SaveHyp.setIcon(icon)
57 self.PB_SaveHyp.setToolTip("hypothesis to Salome Object Browser")
58 self.PB_MeshSmesh.setIcon(icon)
59 self.PB_MeshSmesh.setToolTip("source mesh from Salome Object Browser")
61 icon.addFile(os.path.join(self.iconfolder,"open.png"))
62 self.PB_ParamsFileExplorer.setIcon(icon)
63 self.PB_Load.setIcon(icon)
64 self.PB_Load.setToolTip("hypothesis from file")
65 self.PB_Save.setIcon(icon)
66 self.PB_Save.setToolTip("hypothesis to file")
67 self.PB_MeshFile.setIcon(icon)
68 self.PB_MeshFile.setToolTip("source mesh from a file in disk")
70 #Ces parametres ne sont pas remis à rien par le clean
71 self.paramsFile= os.path.abspath(os.path.join(os.environ["HOME"],".MGCleaner.dat"))
72 self.LE_ParamsFile.setText(self.paramsFile)
73 self.LE_MeshFile.setText("")
74 self.LE_MeshSmesh.setText("")
76 v1=QDoubleValidator(self)
80 self.SP_MinHoleSize.setValidator(v1)
82 v2=QDoubleValidator(self)
86 self.SP_ToleranceDisplacement.setValidator(v2)
88 v3=QDoubleValidator(self)
92 self.SP_ResolutionLength.setValidator(v3)
94 v4=QDoubleValidator(self)
98 self.SP_OverlapDistance.setValidator(v4)
100 self.resize(800, 500)
103 def connecterSignaux(self) :
104 self.connect(self.PB_Cancel,SIGNAL("clicked()"),self.PBCancelPressed)
105 self.connect(self.PB_Default,SIGNAL("clicked()"),self.clean)
106 self.connect(self.PB_Help,SIGNAL("clicked()"),self.PBHelpPressed)
107 self.connect(self.PB_OK,SIGNAL("clicked()"),self.PBOKPressed)
109 self.connect(self.PB_Load,SIGNAL("clicked()"),self.PBLoadPressed)
110 self.connect(self.PB_Save,SIGNAL("clicked()"),self.PBSavePressed)
111 self.connect(self.PB_LoadHyp,SIGNAL("clicked()"),self.PBLoadHypPressed)
112 self.connect(self.PB_SaveHyp,SIGNAL("clicked()"),self.PBSaveHypPressed)
114 self.connect(self.PB_MeshFile,SIGNAL("clicked()"),self.PBMeshFilePressed)
115 self.connect(self.PB_MeshSmesh,SIGNAL("clicked()"),self.PBMeshSmeshPressed)
116 self.connect(self.LE_MeshSmesh,SIGNAL("returnPressed()"),self.meshSmeshNameChanged)
117 self.connect(self.PB_ParamsFileExplorer,SIGNAL("clicked()"),self.setParamsFileName)
118 self.connect(self.LE_MeshFile,SIGNAL("returnPressed()"),self.meshFileNameChanged)
119 self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged)
121 #QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL("stateChanged(int)"), self.change)
122 self.connect(self.CB_FillHoles,SIGNAL("stateChanged(int)"),self.SP_MinHoleSize.setEnabled)
123 self.connect(self.CB_ComputedToleranceDisplacement,SIGNAL("stateChanged(int)"),self.SP_ToleranceDisplacement.setDisabled)
124 self.connect(self.CB_ComputedResolutionLength,SIGNAL("stateChanged(int)"),self.SP_ResolutionLength.setDisabled)
125 self.connect(self.CB_ComputedOverlapDistance,SIGNAL("stateChanged(int)"),self.SP_OverlapDistance.setDisabled)
127 def PBHelpPressed(self):
129 mydir=os.environ["SMESH_ROOT_DIR"]
131 QMessageBox.warning( self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
133 maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf"
134 command="xdg-open "+maDoc+";"
135 subprocess.call(command, shell=True)
137 def PBOKPressed(self):
138 if not(self.PrepareLigneCommande()):
140 #QMessageBox.warning(self, "Compute", "Command not found")
142 maFenetre=MGCleanerMonViewText(self, self.commande)
144 def enregistreResultat(self):
148 from salome.kernel import studyedit
150 if not os.path.isfile(self.fichierOut):
151 QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found")
153 maStudy=studyedit.getActiveStudy()
154 smesh.SetCurrentStudy(maStudy)
155 (outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut)
156 name=str(self.LE_MeshSmesh.text())
158 initialMeshObject=None
160 a=str(self.fichierIn)
161 name=os.path.basename(os.path.splitext(a)[0])
164 initialMeshObject=maStudy.FindObjectByName(name ,"SMESH")[0]
166 meshname = name+"_MGC_"+str(self.num)
167 smesh.SetName(outputMesh.GetMesh(), meshname)
168 outputMesh.Compute() #no algorithms message for "Mesh_x" has been computed with warnings: - global 1D algorithm is missing
170 self.editor = studyedit.getStudyEditor()
171 moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
172 HypReMeshEntry = self.editor.findOrCreateItem(
173 moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
175 monStudyBuilder=maStudy.NewBuilder()
176 monStudyBuilder.NewCommand()
177 newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
178 self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
179 self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
181 SOMesh=maStudy.FindObjectByName(meshname ,"SMESH")[0]
183 if initialMeshFile!=None:
184 newStudyFileName=monStudyBuilder.NewObject(SOMesh)
185 self.editor.setAttributeValue(newStudyFileName, "AttributeName", "meshFile")
186 self.editor.setAttributeValue(newStudyFileName, "AttributeExternalFileDef", initialMeshFile)
187 self.editor.setAttributeValue(newStudyFileName, "AttributeComment", initialMeshFile)
189 if initialMeshObject!=None:
190 newLink=monStudyBuilder.NewObject(SOMesh)
191 monStudyBuilder.Addreference(newLink, initialMeshObject)
193 newLink=monStudyBuilder.NewObject(SOMesh)
194 monStudyBuilder.Addreference(newLink, newStudyIter)
196 if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
200 def PBSavePressed(self):
201 from datetime import datetime
202 if not(self.PrepareLigneCommande()): return
203 text = "# MGCleaner hypothesis parameters\n"
204 text += "# Params for mesh : " + self.LE_MeshSmesh.text() +"\n"
205 text += datetime.now().strftime("# Date : %d/%m/%y %H:%M:%S\n")
206 text += "# Command : "+self.commande+"\n"
207 text += self.getResumeData(separator="\n")
211 f=open(self.paramsFile,"a")
213 QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
218 QMessageBox.warning(self, "File", "Unable to write "+self.paramsFile)
222 def PBSaveHypPressed(self):
223 """save hypothesis in Object Browser"""
224 #QMessageBox.warning(self, "save Object Browser MGCleaner Hypothesis", "TODO")
229 from salome.kernel import studyedit
231 maStudy=studyedit.getActiveStudy()
232 smesh.SetCurrentStudy(maStudy)
234 self.editor = studyedit.getStudyEditor()
235 moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
236 HypReMeshEntry = self.editor.findOrCreateItem(
237 moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
239 monStudyBuilder=maStudy.NewBuilder()
240 monStudyBuilder.NewCommand()
241 newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
242 self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
243 self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
245 if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
250 import salome_pluginsmanager
251 print "salome_pluginsmanager.plugins",salome_pluginsmanager.plugins
252 print "salome_pluginsmanager.current_plugins_manager",salome_pluginsmanager.current_plugins_manager
255 def SP_toStr(self, widget):
256 #cr, pos=widget.validator().validate(res, 0) #n.b. "1,3" is acceptable !locale!
258 return str(float(widget.text()))
260 widget.setProperty("text", "0.0")
263 def getResumeData(self, separator="\n"):
265 if self.RB_Fix1.isChecked():
266 CheckOrFix="fix1pass"
268 if self.RB_Fix2.isChecked():
269 CheckOrFix="fix2pass"
272 text+="CheckOrFix="+CheckOrFix+separator
273 text+="PreserveTopology="+str(self.CB_PreserveTopology.isChecked())+separator
274 text+="FillHoles="+str(self.CB_FillHoles.isChecked())+separator
275 v=self.SP_toStr(self.SP_MinHoleSize)
276 text+="MinHoleSize="+v+separator
277 text+="ComputedToleranceDisplacement="+str(self.CB_ComputedToleranceDisplacement.isChecked())+separator
278 v=self.SP_toStr(self.SP_ToleranceDisplacement)
279 text+="ToleranceDisplacement="+v+separator
280 text+="ComputedResolutionLength="+str(self.CB_ComputedResolutionLength.isChecked())+separator
281 v=self.SP_toStr(self.SP_ResolutionLength)
282 text+="ResolutionLength="+v+separator
283 text+="FoldingAngle="+str(self.SP_FoldingAngle.value())+separator
284 text+="RemeshPlanes="+str(self.CB_RemeshPlanes.isChecked())+separator
285 text+="ComputedOverlapDistance="+str(self.CB_ComputedOverlapDistance.isChecked())+separator
286 v=self.SP_toStr(self.SP_OverlapDistance)
287 text+="OverlapDistance="+v+separator
288 text+="OverlapAngle="+str(self.SP_OverlapAngle.value())+separator
289 text+="Verbosity="+str(self.SP_Verbosity.value())+separator
292 def loadResumeData(self, hypothesis, separator="\n"):
295 for slig in reversed(text.split(separator)):
297 #print "load ResumeData",lig
298 if lig=="": continue #skip blanck lines
299 if lig[0]=="#": break
301 tit,value=lig.split("=")
302 if tit=="CheckOrFix":
303 self.RB_Fix1.setChecked(False)
304 self.RB_Fix2.setChecked(False)
305 self.RB_Check.setChecked(False)
306 if value=="fix1pass": self.RB_Fix1.setChecked(True)
307 if value=="fix2pass": self.RB_Fix2.setChecked(True)
308 if value=="check": self.RB_Check.setChecked(True)
309 if tit=="PreserveTopology": self.CB_PreserveTopology.setChecked(value=="True")
310 if tit=="FillHoles": self.CB_FillHoles.setChecked(value=="True")
311 if tit=="MinHoleSize": self.SP_MinHoleSize.setProperty("text", value)
312 if tit=="ComputedToleranceDisplacement": self.CB_ComputedToleranceDisplacement.setChecked(value=="True")
313 if tit=="ToleranceDisplacement": self.SP_ToleranceDisplacement.setProperty("text", value)
314 if tit=="ComputedResolutionLength": self.CB_ComputedResolutionLength.setChecked(value=="True")
315 if tit=="ResolutionLength": self.SP_ResolutionLength.setProperty("text", value)
316 if tit=="FoldingAngle": self.SP_FoldingAngle.setProperty("value", float(value))
317 if tit=="RemeshPlanes": self.CB_RemeshPlanes.setChecked(value=="True")
318 if tit=="ComputedOverlapDistance": self.CB_ComputedOverlapDistance.setChecked(value=="True")
319 if tit=="OverlapDistance": self.SP_OverlapDistance.setProperty("text", value)
320 if tit=="OverlapAngle": self.SP_OverlapAngle.setProperty("value", float(value))
321 if tit=="Verbosity": self.SP_Verbosity.setProperty("value", int(float(value)))
323 QMessageBox.warning(self, "load MGCleaner Hypothesis", "Problem on '"+lig+"'")
325 def PBLoadPressed(self):
326 """load last hypothesis saved in tail of file"""
328 f=open(self.paramsFile,"r")
330 QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
335 QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile)
338 self.loadResumeData(text, separator="\n")
340 def PBLoadHypPressed(self):
341 """load hypothesis saved in Object Browser"""
342 #QMessageBox.warning(self, "load Object Browser MGCleaner hypothesis", "TODO")
344 from salome.kernel import studyedit
345 from salome.smesh.smeshstudytools import SMeshStudyTools
346 from salome.gui import helper as guihelper
347 from omniORB import CORBA
349 mySObject, myEntry = guihelper.getSObjectSelected()
350 if CORBA.is_nil(mySObject) or mySObject==None:
351 QMessageBox.critical(self, "Hypothese", "select an Object Browser MGCleaner hypothesis")
354 #for i in dir(mySObject): print "dir mySObject",i
355 #print "GetAllAttributes",mySObject.GetAllAttributes()
356 #print "GetComment",mySObject.GetComment()
357 #print "GetName",mySObject.GetName()
360 #if mySObject.GetFather().GetName()!="MGCleaner Hypotheses":
361 # QMessageBox.critical(self, "Hypothese", "not a child of MGCleaner Hypotheses")
364 text=mySObject.GetComment()
367 if "CheckOrFix=" not in text:
368 QMessageBox.critical(self, "Load Hypothese", "Object Browser selection not a MGCleaner Hypothesis")
370 self.loadResumeData(text, separator=" ; ")
373 def PBCancelPressed(self):
376 def PBMeshFilePressed(self):
377 fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)")
379 infile = fd.selectedFiles()[0]
380 self.LE_MeshFile.setText(infile)
381 self.fichierIn=infile.toLatin1()
383 self.LE_MeshSmesh.setText("")
385 def setParamsFileName(self):
386 fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)")
388 infile = fd.selectedFiles()[0]
389 self.LE_ParamsFile.setText(infile)
390 self.paramsFile=infile.toLatin1()
392 def meshFileNameChanged(self):
393 self.fichierIn=str(self.LE_MeshFile.text())
394 #print "meshFileNameChanged", self.fichierIn
395 if os.path.exists(self.fichierIn):
396 self.__selectedMesh=None
398 self.LE_MeshSmesh.setText("")
400 QMessageBox.warning(self, "Mesh file", "File doesn't exist")
402 def meshSmeshNameChanged(self):
403 """only change by GUI mouse selection, otherwise clear"""
404 #self.MeshIn=str(self.LE_MeshSmesh.text())
405 #print "meshSmeshNameChanged", self.MeshIn
406 self.__selectedMesh = None
408 self.LE_MeshSmesh.setText("")
412 def paramsFileNameChanged(self):
413 self.paramsFile=self.LE_ParamsFile.text()
415 def PBMeshSmeshPressed(self):
418 from salome.kernel import studyedit
419 from salome.smesh.smeshstudytools import SMeshStudyTools
420 from salome.gui import helper as guihelper
421 from omniORB import CORBA
423 mySObject, myEntry = guihelper.getSObjectSelected()
424 if CORBA.is_nil(mySObject) or mySObject==None:
425 QMessageBox.critical(self, "Mesh", "select an input mesh")
427 self.smeshStudyTool = SMeshStudyTools()
429 self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
431 QMessageBox.critical(self, "Mesh", "select an input mesh")
433 if CORBA.is_nil(self.__selectedMesh):
434 QMessageBox.critical(self, "Mesh", "select an input mesh")
436 myName = mySObject.GetName()
437 #print "MeshSmeshNameChanged", myName
439 self.LE_MeshSmesh.setText(myName)
440 self.LE_MeshFile.setText("")
443 def prepareFichier(self):
444 self.fichierIn="/tmp/ForMGCleaner_"+str(self.num)+".mesh"
445 #print "prepareFichier"
447 self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True)
449 def PrepareLigneCommande(self):
451 #use doc examples of mg-cleaner:
452 ls -al /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin
453 source /data/tmplgls/salome/prerequis/install/LICENSE/dlim8.var.sh
454 export PATH=/data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin/Linux_64:$PATH
455 cp -r /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/examples .
457 mg-cleaner.exe --help
458 mg-cleaner.exe --in case7.mesh --out case7-test.mesh --check
459 mg-cleaner.exe case7.mesh case7-fix.mesh --fix
460 mg-cleaner.exe --in Porsche.mesh --out Porsche-test.mesh --check
461 mg-cleaner.exe --in Porsche.mesh --out Porschefix.mesh --fix
462 mg-cleaner.exe --in Porsche.mesh --out PorscheNewfix.mesh --fix --resolution_length 0.03
465 #self.commande="mg-cleaner.exe --in " + self.fichierIn + " --out " + self.fichierOut + " --fix2pass"
467 #print "PrepareLigneCommande '"+self.fichierIn+"' '"+self.MeshIn+"'",self.__selectedMesh
468 if self.fichierIn=="" and self.MeshIn=="":
469 QMessageBox.critical(self, "Mesh", "select an input mesh")
471 if self.__selectedMesh!=None: self.prepareFichier()
472 if not (os.path.isfile(self.fichierIn)):
473 QMessageBox.critical(self, "File", "unable to read GMF Mesh in "+str(self.fichierIn))
476 self.commande="mg-cleaner.exe"
477 verbosity=str(self.SP_Verbosity.value())
478 self.commande+=" --verbose " + verbosity
479 self.commande+=" --in " + self.fichierIn
480 #print "self.fichierIn",self.fichierIn,type(self.fichierIn)
481 deb=os.path.splitext(str(self.fichierIn))
482 self.fichierOut=deb[0] + "_fix.mesh"
483 self.commande+=" --out "+self.fichierOut
484 if self.RB_Fix1.isChecked():
485 self.commande+=" --fix1pass"
487 if self.RB_Fix2.isChecked():
488 self.commande+=" --fix2pass"
490 self.commande+=" --check"
491 if self.CB_PreserveTopology.isChecked():
492 self.commande+=" --topology respect"
494 self.commande+=" --topology ignore"
495 if self.CB_FillHoles.isChecked(): #no fill holes default
496 self.commande+=" --min_hole_size " + self.SP_toStr(self.SP_MinHoleSize)
497 if not self.CB_ComputedToleranceDisplacement.isChecked(): #computed default
498 self.commande+=" --tolerance_displacement " + self.SP_toStr(self.SP_ToleranceDisplacement)
499 if not self.CB_ComputedResolutionLength.isChecked(): #computed default
500 self.commande+=" --resolution_length " + self.SP_toStr(self.SP_ResolutionLength)
501 self.commande+=" --folding_angle " + str(self.SP_FoldingAngle.value())
502 if self.CB_RemeshPlanes.isChecked(): #no remesh default
503 self.commande+=" --remesh_planes"
504 if not self.CB_ComputedOverlapDistance.isChecked(): #computed default
505 self.commande+=" --overlap_distance " + self.SP_toStr(self.SP_OverlapDistance)
506 self.commande+=" --overlap_angle " + str(self.SP_OverlapAngle.value())
510 self.RB_Check.setChecked(False)
511 self.RB_Fix1.setChecked(False)
512 self.RB_Fix2.setChecked(True)
513 self.CB_PreserveTopology.setChecked(False)
514 self.CB_FillHoles.setChecked(False)
515 self.CB_RemeshPlanes.setChecked(False)
517 self.SP_MinHoleSize.setProperty("text", 0)
518 self.SP_ToleranceDisplacement.setProperty("text", 0)
519 self.SP_ResolutionLength.setProperty("text", 0)
520 self.SP_FoldingAngle.setProperty("value", 15)
521 self.SP_OverlapDistance.setProperty("text", 0)
522 self.SP_OverlapAngle.setProperty("value", 15)
523 self.SP_Verbosity.setProperty("value", 3)
525 self.CB_ComputedToleranceDisplacement.setChecked(True)
526 self.CB_ComputedResolutionLength.setChecked(True)
527 self.CB_ComputedOverlapDistance.setChecked(True)
532 This function returns a singleton instance of the plugin dialog.
533 c est obligatoire pour faire un show sans parent...
537 __dialog = MGCleanerMonPlugDialog()
544 # ==============================================================================
546 # ==============================================================================
548 def TEST_standalone():
550 works only if a salome is launched yet with a study loaded
551 to launch standalone python do:
552 /export/home/wambeke/2013/V6_main_MGC_CO6.4_64/APPLI/runSession
555 python /export/home/wambeke/2013/V6_main_MGC_CO6.4_64/INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py
560 from salome.kernel import studyedit
562 maStudy=studyedit.getActiveStudy()
566 # ==============================================================================
567 # Basic use cases and unit test functions
568 # ==============================================================================
570 def TEST_MGCleanerMonPlugDialog():
571 #print "TEST_MGCleanerMonPlugDialog"
573 from PyQt4.QtGui import QApplication
574 from PyQt4.QtCore import QObject, SIGNAL, SLOT
575 app = QApplication(sys.argv)
576 QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
578 dlg=MGCleanerMonPlugDialog()
580 sys.exit(app.exec_())
582 if __name__ == "__main__":
583 TEST_MGCleanerMonPlugDialog()