Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/multipr.git] / src / MULTIPRGUI / MULTIPR_GUI.cxx
1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
3
4 /**
5  * \file    MULTIPR_GUI.cxx
6  *
7  * \brief   see MULTIPR_GUI.h
8  *
9  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
10  * 
11  * \date    01/2007
12  */
13   
14 //*****************************************************************************
15 // Includes section
16 //*****************************************************************************
17
18 // MULTIPR Includes
19 #include "MULTIPR_GUI.h"
20 #include "MULTIPR_GUI_Dlg.h"
21 #include "MULTIPR_Utils.hxx"
22
23 // Salome Includes
24 #include <SalomeApp_Application.h>
25 #include <SalomeApp_DataModel.h>
26 #include <SalomeApp_Study.h>
27 #include <SalomeApp_CheckFileDlg.h>
28
29 #include <LightApp_Study.h>
30 #include <LightApp_DataModel.h>
31 #include <LightApp_DataOwner.h>
32 #include <LightApp_SelectionMgr.h>
33
34 #include <CAM_DataModel.h>
35 #include <CAM_Module.h>
36
37 #include <SUIT_MessageBox.h>
38 #include <SUIT_ResourceMgr.h>
39 #include <SUIT_Session.h>
40
41 #include <SALOME_LifeCycleCORBA.hxx>
42 #include <SALOMEDS_Study.hxx>
43
44 #include <SALOME_Event.hxx>
45
46 #include <QtxPopupMgr.h>
47
48 // QT Includes
49 #include <qapplication.h>
50 #include <qinputdialog.h>
51 #include <qlayout.h>
52 #include <qpushbutton.h>
53 #include <qgroupbox.h>
54 #include <qvbox.h>
55 #include <qbuttongroup.h>
56 #include <qlabel.h>
57 #include <qcombobox.h>
58 #include <qvariant.h>
59 #include <qlineedit.h>
60 #include <qspinbox.h>
61 #include <qtooltip.h>
62 #include <qwhatsthis.h>
63 #include <qimage.h>
64 #include <qpixmap.h>
65 #include <qmessagebox.h>
66 #include <qaction.h>
67 #include <qtimer.h>
68 #include <qthread.h>
69
70 #include <stdexcept>
71
72 using namespace std;
73
74
75 //*****************************************************************************
76 // Global variable
77 //*****************************************************************************
78
79 //namespace multipr
80 //{
81 //    // progress callback used by the MULTIPR library
82 //    extern MULTIPR_ProgressCallback*  gProgressCallback;
83 //    extern MULTIPR_EmptyMeshCallback* gEmptyMeshCallback;
84 //}
85 class MULTIPR_GUI_FinishSaveEvent: public SALOME_Event
86 {
87   SalomeApp_Application* myApp;
88   bool myIsError;
89 public:
90   MULTIPR_GUI_FinishSaveEvent (SalomeApp_Application* theApp,
91                                bool theIsError)
92     : myApp(theApp),
93       myIsError(theIsError)
94   {}
95   virtual void Execute()
96   {
97     if (myIsError) {
98       SUIT_MessageBox::error1(myApp->desktop(),
99                               "Save distributed MED file error", 
100                               "Error while writing distributed MED file", 
101                               myApp->tr("MULTIPR_BUT_OK"));
102     }
103     else {
104       myApp->updateObjectBrowser();
105       myApp->updateActions();
106     }
107     QApplication::restoreOverrideCursor();
108   }
109 };
110
111 class MULTIPR_GUI_SaveThread : public QThread
112 {
113 public:
114   MULTIPR_GUI_SaveThread (MULTIPR_GUI* pModule,
115                           MULTIPR_ORB::MULTIPR_Obj_ptr pObj,
116                           QString pPath)
117     : mModule(pModule)
118   {
119     mObj = MULTIPR_ORB::MULTIPR_Obj::_duplicate(pObj);
120     mPath = pPath;
121   }
122   virtual void run();
123
124 private:
125   MULTIPR_GUI* mModule;
126   MULTIPR_ORB::MULTIPR_Obj_ptr mObj;
127   QString mPath;
128 };
129
130 void MULTIPR_GUI_SaveThread::run()
131 {
132   try
133   {
134     mObj->save(mPath);
135   }
136   catch(...)
137   {
138     ProcessVoidEvent(new MULTIPR_GUI_FinishSaveEvent(mModule->getApp(), true));
139     return;
140   }
141
142   ProcessVoidEvent(new MULTIPR_GUI_FinishSaveEvent(mModule->getApp(), false));
143 }
144
145 //*****************************************************************************
146 // Global function
147 //*****************************************************************************
148
149 // singleton
150 MULTIPR_ORB::MULTIPR_Gen_ptr GetMultiprGen (const CAM_Module* theModule)
151 {
152     static MULTIPR_ORB::MULTIPR_Gen_ptr aGen = NULL;
153
154     if (!aGen)
155     {
156         SALOME_LifeCycleCORBA aLCC (SalomeApp_Application::namingService());
157         Engines::Component_var aComponent = aLCC.FindOrLoad_Component("FactoryServer", "MULTIPR");
158         aGen = MULTIPR_ORB::MULTIPR_Gen::_narrow(aComponent);
159         if (!CORBA::is_nil(aGen))
160         {
161           // Set current study
162           SalomeApp_Study* aSAStudy =
163             dynamic_cast<SalomeApp_Study*>(theModule->application()->activeStudy());
164           _PTR(Study) aStudy = aSAStudy->studyDS();
165           SALOMEDS::Study_ptr aStudyDS;
166           if (aStudy)
167             aStudyDS = _CAST(Study,aStudy)->GetStudy();
168           aGen->SetCurrentStudy(aStudyDS);
169         }
170     }
171
172     if (CORBA::is_nil(aGen))
173         throw std::runtime_error("Can't find MULTIPR component");
174
175     return aGen;
176 }
177
178
179 //*****************************************************************************
180 // Class MULTIPR_GUI implementation
181 //*****************************************************************************
182
183 MULTIPR_GUI::MULTIPR_GUI()
184   : SalomeApp_Module("MULTIPR"),
185     //mMULTIPRObj(NULL),
186     mMEDFileName(""),
187     mProgress(NULL)
188 {
189   mTimer = new QTimer (this);
190   connect(mTimer, SIGNAL(timeout()), this, SLOT(timerDone()));
191 }
192
193
194 MULTIPR_GUI::~MULTIPR_GUI()
195 {
196   //if (mMULTIPRObj != NULL)
197   if (!CORBA::is_nil(mMULTIPRObj))
198     {
199         CORBA::release(mMULTIPRObj);
200     }
201 }
202
203
204 MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_GUI::getMULTIPRObj()
205 {
206     return mMULTIPRObj;
207 }
208
209 void MULTIPR_GUI::setMULTIPRObj (MULTIPR_ORB::MULTIPR_Obj_ptr theObj)
210 {
211   mMULTIPRObj = MULTIPR_ORB::MULTIPR_Obj::_duplicate(theObj);
212 }
213
214 SalomeApp_Application* MULTIPR_GUI::getAppli() const
215 {
216     return getApp();
217 }
218
219
220 void MULTIPR_GUI::initialize(CAM_Application* app)
221 {
222     SalomeApp_Module::initialize(app);
223     
224     GetMultiprGen(this);
225     
226     QWidget* aParent = app->desktop();
227     SUIT_ResourceMgr* aResourceMgr = app->resourceMgr();
228     
229     //-------------------------------------------------------------------------
230     // create actions
231     //-------------------------------------------------------------------------    
232     QPixmap aPixmapImportFromMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("MULTIPR_ICON_IMPORT_MED"));
233     
234     createAction( 
235         ACTION_IMPORT_MED, 
236         tr("MULTIPR_TLT_IMPORT_FROM_MED_FILE"), 
237         QIconSet(aPixmapImportFromMEDFile), 
238         tr("MULTIPR_MEN_IMPORT_FROM_MED_FILE"), 
239         tr("MULTIPR_STS_IMPORT_FROM_MED_FILE"), 
240         (CTRL + Key_I),
241         aParent, 
242         false,
243         this, 
244         SLOT(OnImportFromMEDFile()));
245         
246     createAction( 
247         ACTION_SPLIT, 
248         tr("MULTIPR_TLT_SPLIT"), 
249         QIconSet(), 
250         tr("MULTIPR_MEN_SPLIT"), 
251         tr("MULTIPR_STS_SPLIT"), 
252         0,
253         aParent, 
254         false,
255         this, 
256         SLOT(OnPartition2()));
257     
258     createAction( 
259         ACTION_DECIMATE, 
260         tr("MULTIPR_TLT_DECIMATE"), 
261         QIconSet(), 
262         tr("MULTIPR_MEN_DECIMATE"), 
263         tr("MULTIPR_STS_DECIMATE"), 
264         0,
265         aParent, 
266         false,
267         this, 
268         SLOT(OnDecimate()));
269     
270     createAction( 
271         ACTION_REMOVE, 
272         tr("MULTIPR_TLT_REMOVE"), 
273         QIconSet(), 
274         tr("MULTIPR_MEN_REMOVE"), 
275         tr("MULTIPR_STS_REMOVE"), 
276         0,
277         aParent, 
278         false,
279         this, 
280         SLOT(OnRemove()));
281         
282     QPixmap aPixmapSaveMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("MULTIPR_ICON_SAVE_MED"));
283     
284     createAction( 
285         ACTION_SAVE, 
286         tr("MULTIPR_TLT_SAVE"), 
287         QIconSet(aPixmapSaveMEDFile), 
288         tr("MULTIPR_MEN_SAVE"), 
289         tr("MULTIPR_STS_SAVE"), 
290         0,
291         aParent, 
292         false,
293         this, 
294         SLOT(OnSave()));
295     
296     //-------------------------------------------------------------------------
297     // create menus
298     //-------------------------------------------------------------------------
299     int aMenuId;
300     aMenuId = createMenu(tr("MULTIPR_MEN_FILE"), -1, -1);
301     createMenu(separator(), aMenuId, -1, 10);
302     aMenuId = createMenu(tr("MULTIPR_MEN_FILE_MULTIPR"), aMenuId, -1, 10);
303     createMenu(ACTION_IMPORT_MED, aMenuId);
304     
305     aMenuId = createMenu(tr("MULTIPR_MEN_MULTIPR"), -1, -1, 30);
306     createMenu(ACTION_IMPORT_MED, aMenuId, 10);
307     createMenu(ACTION_SAVE, aMenuId, 10);
308     createMenu(ACTION_SPLIT, aMenuId, 10);
309     createMenu(ACTION_DECIMATE, aMenuId, 10);
310     createMenu(ACTION_REMOVE, aMenuId, 10);
311     
312     //-------------------------------------------------------------------------
313     // create toolbars
314     //-------------------------------------------------------------------------
315     int aToolId = createTool(tr("MULTIPR_TOOL_MULTIPR"));
316     createTool(ACTION_IMPORT_MED, aToolId);
317     createTool(ACTION_SAVE, aToolId);
318     
319     //-------------------------------------------------------------------------
320     // create popup menus
321     //-------------------------------------------------------------------------
322     QtxPopupMgr* mgr = popupMgr();
323     mgr->insert( action(ACTION_SPLIT), -1, -1, -1 );
324     mgr->insert( action(ACTION_DECIMATE), -1, -1, -1 );
325     mgr->insert( action(ACTION_REMOVE), -1, -1, -1 );
326     mgr->insert( action(ACTION_SAVE), -1, -1, -1 );
327     
328     QString aRule = "client='ObjectBrowser' and selcount>=1"; // $type in {'VISU::TMESH'}";
329     mgr->setRule(action(ACTION_SPLIT), aRule, true);
330     mgr->setRule(action(ACTION_DECIMATE), aRule, true);
331     mgr->setRule(action(ACTION_REMOVE), aRule, true);
332     mgr->setRule(action(ACTION_SAVE), aRule, true);
333     
334     //-------------------------------------------------------------------------
335     // set progress dialog
336     //-------------------------------------------------------------------------
337     //MULTIPR_GUI_ProgressCallbackDlg* progressDlg =
338     //  new MULTIPR_GUI_ProgressCallbackDlg(application()->desktop());
339     //multipr::gProgressCallback = progressDlg;
340     
341     //MULTIPR_GUI_EmptyMeshCallbackDlg* emptyMeshDlg =
342     //  new MULTIPR_GUI_EmptyMeshCallbackDlg(application()->desktop());
343     //multipr::gEmptyMeshCallback = emptyMeshDlg;
344 }
345
346
347 CAM_DataModel* MULTIPR_GUI::createDataModel()
348 {
349     return new MULTIPR_GUI_DataModel(this);
350 }
351
352
353 QString MULTIPR_GUI::engineIOR() const
354 {
355     CORBA::String_var anIOR = getApp()->orb()->object_to_string(GetMultiprGen(this));
356     return QString(anIOR.in());
357 }
358
359 bool MULTIPR_GUI::activateModule(SUIT_Study* theStudy)
360 {
361     bool bOk = SalomeApp_Module::activateModule(theStudy);
362
363     setMenuShown(true);
364     setToolShown(true);
365
366     action(ACTION_IMPORT_MED)->setAccel(QKeySequence(CTRL + Key_I));
367
368     // Set current study
369     MULTIPR_ORB::MULTIPR_Gen_ptr aGen = GetMultiprGen(this);
370     SalomeApp_Study* aSAStudy = dynamic_cast<SalomeApp_Study*>(theStudy);
371     _PTR(Study) aStudy = aSAStudy->studyDS();
372     SALOMEDS::Study_ptr aStudyDS;
373     if (aStudy)
374       aStudyDS = _CAST(Study,aStudy)->GetStudy();
375     aGen->SetCurrentStudy(aStudyDS);
376
377     // Init mMULTIPRObj
378     _PTR(SComponent) aSComp = aStudy->FindComponent(name());
379     if (aSComp) {
380       _PTR(ChildIterator) it (aStudy->NewChildIterator(aSComp));
381       if (it->More()) {
382         _PTR(SObject) aSObj = it->Value();
383         string anIOR = aSObj->GetIOR();
384         if (!anIOR.empty()) {
385           CORBA::Object_var anObj = getApp()->orb()->string_to_object(anIOR.c_str());
386           mMULTIPRObj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
387         }
388       }
389     }
390
391     return bOk;
392 }
393
394
395 bool MULTIPR_GUI::deactivateModule(SUIT_Study* theStudy)
396 {
397     setMenuShown(false);
398     setToolShown(false);
399
400     // Unset actions accelerator keys
401     action(ACTION_IMPORT_MED)->setAccel(QKeySequence());
402
403     mMULTIPRObj = MULTIPR_ORB::MULTIPR_Obj::_nil();
404
405     return SalomeApp_Module::deactivateModule(theStudy);
406 }
407
408
409 void MULTIPR_GUI::windows(QMap<int, int>& theMap) const
410 {
411     theMap.clear();
412     theMap.insert(SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft);
413     theMap.insert(SalomeApp_Application::WT_PyConsole,     Qt::DockBottom);
414 }
415
416
417 void MULTIPR_GUI::selected(QStringList& entries, const bool multiple)
418 {
419     LightApp_SelectionMgr* mgr = getApp()->selectionMgr();
420     
421     if(!mgr) return;
422     
423     SUIT_DataOwnerPtrList anOwnersList;
424     mgr->selected(anOwnersList);
425     
426     for (int i = 0 ; i < anOwnersList.size() ; i++)
427     {
428         const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>(anOwnersList[i].get());
429         
430         if (!entries.contains(owner->entry()))
431         {
432             entries.append(owner->entry());
433         }
434             
435         if (!multiple)
436             break;
437     }
438 }
439
440
441 void MULTIPR_GUI::OnImportFromMEDFile()
442 {
443     // Get file name
444     QStringList aFilter;
445     aFilter.append(tr("MULTIPR_FLT_MED_FILES"));
446     aFilter.append(tr("MULTIPR_FLT_ALL_FILES"));
447     
448     SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg(
449         this->application()->desktop(), 
450         true, 
451         tr("") );
452         
453     fd->setCaption(tr("MULTIPR_MEN_IMPORT_FROM_MED_FILE"));
454     fd->setFilters(aFilter);
455     if (fd->exec() == QDialog::Rejected)
456     {
457         delete fd;
458         return;
459     }
460     
461     QFileInfo aFileInfo(fd->selectedFile());
462     delete fd;
463     
464     // Check the file name
465     if (!aFileInfo.exists())
466         return;
467
468     mMEDFileName = aFileInfo.filePath();
469
470     QApplication::setOverrideCursor(Qt::waitCursor);
471
472     // Delete previous MULTIPR object.
473     //if (mMULTIPRObj != NULL)
474     if (!CORBA::is_nil(mMULTIPRObj) && !mMULTIPRObj->_non_existent())
475     {
476         mMULTIPRObj->reset();
477     }
478
479     MULTIPR_ORB::MULTIPR_Gen_ptr multiprgen = GetMultiprGen(this);
480
481     try
482     {
483       mMULTIPRObj = multiprgen->getObject(mMEDFileName.latin1());
484     }
485     catch(...)
486     {
487         SUIT_MessageBox::error1( 
488             getApp()->desktop(),
489             "Import MED file error", 
490             "Invalid MED file (not recognized by MULTIPR)", 
491             tr("MULTIPR_BUT_OK") );
492     }
493     QApplication::restoreOverrideCursor();
494     
495     //if (mMULTIPRObj != NULL)
496     if (!CORBA::is_nil(mMULTIPRObj))
497     {
498         SALOMEDS::SObject_ptr aSObject = SALOMEDS::SObject::_nil();
499         SalomeApp_Study* aSAStudy = dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
500         _PTR(Study) aStudyDSClient = aSAStudy->studyDS();
501         SALOMEDS::Study_ptr aStudyDS = _CAST(Study,aStudyDSClient)->GetStudy();
502         multiprgen->PublishInStudy(aStudyDS, aSObject, mMULTIPRObj, "Mesh");
503
504         try
505         {
506             if (mMULTIPRObj->isValidSequentialMEDFile())
507             {
508                 OnPartition1();
509             }
510         }
511         catch (...)
512         {
513         }
514
515         getApp()->updateObjectBrowser();
516         getApp()->updateActions();
517     }
518 }
519
520
521 void MULTIPR_GUI::OnPartition1()
522 {
523     // check if MULTIPRObj exists
524     //if (mMULTIPRObj == NULL)
525     if (CORBA::is_nil(mMULTIPRObj))
526     {
527         return;
528     }
529  
530     // do the partition.   
531     MULTIPR_GUI_Partition1Dlg* dialog = new MULTIPR_GUI_Partition1Dlg(this);
532     dialog->exec();
533     delete dialog;
534
535     // Now we need to save the file.
536     SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg(
537         this->application()->desktop(), 
538         true, 
539         tr("") );
540         
541     fd->setCaption(tr("Save distributed MED file - Destination directory"));
542     fd->setMode(QFileDialog::DirectoryOnly);
543     
544     if (fd->exec() == QDialog::Rejected)
545     {
546         delete fd;
547         mMULTIPRObj->reset();
548         getApp()->updateObjectBrowser();
549         return;
550     }
551     
552     QFileInfo aFileInfo(fd->selectedFile());
553     delete fd;
554         
555     QString path = aFileInfo.filePath();
556     
557     QApplication::setOverrideCursor(Qt::waitCursor);
558     mMULTIPRObj->resetSaveProgress();
559
560     MULTIPR_GUI_SaveThread* a = new MULTIPR_GUI_SaveThread (this, mMULTIPRObj, path);
561     a->start();
562     
563     // save progress
564     //mProgress = new MULTIPR_GUI_ProgressCallbackDlg (getApp()->desktop());
565     //mProgress->start("Save mesh", 100);
566     if (mProgress == NULL)
567         mProgress = new QProgressDialog ("Save mesh", "Cancel", /*totalSteps*/100, getApp()->desktop());
568     //mProgress->setProgress(0);
569     //mProgress->init(100);
570     //mTimer->start(500); // 0.5 seconds timer
571     //QApplication::restoreOverrideCursor();
572     //getApp()->updateObjectBrowser();
573     
574 }
575
576
577 void MULTIPR_GUI::OnPartition2()
578 {
579     // check if MULTIPRObj exists
580     //if (mMULTIPRObj == NULL)
581     if (CORBA::is_nil(mMULTIPRObj))
582     {
583         return;
584     }
585     
586     retrieveSelectedParts();
587     
588     if (mSelectedParts.count() == 0)
589     {
590         SUIT_MessageBox::warn1( 
591             getApp()->desktop(),
592             "Split warning", 
593             "No parts selected", 
594             tr("MULTIPR_BUT_OK") );
595         return;
596     }
597     
598     if (!removeLowerResolution())
599     {
600         return;
601     }
602     
603     MULTIPR_GUI_Partition2Dlg* dialog = new MULTIPR_GUI_Partition2Dlg(this);
604     dialog->exec();
605     delete dialog;
606     getApp()->updateObjectBrowser();
607     getApp()->updateActions();
608 }
609
610
611 void MULTIPR_GUI::OnDecimate()
612 {
613     // check if MULTIPRObj exists
614     //if (mMULTIPRObj == NULL)
615     if (CORBA::is_nil(mMULTIPRObj))
616     {
617         return;
618     }
619     
620     retrieveSelectedParts();
621     
622     if (mSelectedParts.count() == 0)
623     {
624         SUIT_MessageBox::warn1( 
625             getApp()->desktop(),
626             "Decimation warning", 
627             "No parts selected", 
628             tr("MULTIPR_BUT_OK") );
629         return;
630     }
631
632     if (!removeLowerResolution())
633     {
634         return;
635     }
636
637     const QStringList& partsList = this->getSelectedParts();
638     QString allParts = partsList.join("|");
639     MULTIPR_ORB::string_array* listFields = this->getMULTIPRObj()->getFields(allParts.latin1());
640     if (listFields->length() == 0)
641     {
642       SUIT_MessageBox::error1( 
643             this->getAppli()->desktop(),
644             "Decimation error", 
645             "No field for this part.", 
646             tr("OK") );
647       return ;
648     }
649
650     MULTIPR_GUI_DecimateDlg* dialog = new MULTIPR_GUI_DecimateDlg(this);
651     dialog->exec();
652     delete dialog;
653     getApp()->updateObjectBrowser();
654     getApp()->updateActions();
655 }
656
657
658 void MULTIPR_GUI::OnRemove()
659 {
660     // check if MULTIPRObj exists
661     //if (mMULTIPRObj == NULL)
662     if (CORBA::is_nil(mMULTIPRObj))
663     {
664         return;
665     }
666     
667     retrieveSelectedParts();
668     
669     if (mSelectedParts.count() == 0)
670     {
671         SUIT_MessageBox::warn1( 
672             getApp()->desktop(),
673             "Remove warning", 
674             "No parts selected", 
675             tr("MULTIPR_BUT_OK") );
676         return;
677     }
678     
679     if (QMessageBox::question(
680             getApp()->desktop(),
681             tr("Remove selected part(s)"),
682             tr("Do you want to remove selected part(s)?"),
683             tr("&Yes"), tr("&No"),
684             QString::null, 0, 1 ) )
685     {
686         return;
687     }
688
689     QApplication::setOverrideCursor(Qt::waitCursor);
690
691     try
692     {
693       QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end();
694       for (; it != last; it++)
695       {
696         const QString& partName = (*it);
697         cout << "Remove " << partName.latin1() << endl;
698         mMULTIPRObj->removeParts(partName.latin1());
699       }
700     }
701     catch(...)
702     {
703         SUIT_MessageBox::error1( 
704             getApp()->desktop(),
705             "Remove error", 
706             "Error while removing selected part(s)", 
707             tr("MULTIPR_BUT_OK") );
708     }
709
710     QApplication::restoreOverrideCursor();
711
712     getApp()->updateObjectBrowser();
713     getApp()->updateActions();
714 }
715
716
717 void MULTIPR_GUI::OnSave()
718 {
719   // check if MULTIPRObj exists
720   //if (mMULTIPRObj == NULL)
721   if (CORBA::is_nil(mMULTIPRObj))
722   {
723     return;
724   }
725
726   SalomeApp_CheckFileDlg* fd =
727     new SalomeApp_CheckFileDlg(this->application()->desktop(),
728                                true,
729                                tr(""));
730
731   fd->setCaption(tr("Save distributed MED file - Destination directory"));
732   fd->setMode(QFileDialog::DirectoryOnly);
733
734   if (fd->exec() == QDialog::Rejected)
735   {
736     delete fd;
737     return;
738   }
739
740   QFileInfo aFileInfo(fd->selectedFile());
741   delete fd;
742
743   QApplication::setOverrideCursor(Qt::waitCursor);
744
745   QString path = aFileInfo.filePath();
746   mMULTIPRObj->resetSaveProgress();
747
748   MULTIPR_GUI_SaveThread* a = new MULTIPR_GUI_SaveThread (this, mMULTIPRObj, path);
749   a->start();
750
751   // save progress
752   //mProgress = new MULTIPR_GUI_ProgressCallbackDlg (getApp()->desktop());
753   //mProgress->start("Save mesh", 100);
754   if (mProgress == NULL)
755     mProgress = new QProgressDialog ("Save mesh", "Cancel", /*totalSteps*/100, getApp()->desktop());
756   //mProgress->setProgress(0);
757   //mProgress->init(100);
758   mTimer->start(500); // 0.5 seconds timer
759
760   //QApplication::restoreOverrideCursor();
761 }
762
763 void MULTIPR_GUI::timerDone()
764 {
765   int progress = mMULTIPRObj->getSaveProgress();
766   if (mProgress != NULL) {
767     mProgress->setProgress(progress);
768
769     if (progress >= 100) {
770       mTimer->stop();
771     }
772   }
773 }
774
775 void MULTIPR_GUI::retrieveSelectedParts()
776 {
777     mSelectedParts.clear();
778
779     QStringList userSelection;
780     selected(userSelection, true);
781     for (QStringList::const_iterator it = userSelection.begin(), last = userSelection.end(); it != last; it++)
782     {
783         const QString& str = (*it);
784         QStringList words = QStringList::split(":", str);
785         if (words.count() == 2)
786         {
787             if (words[0] == "MULTIPR_PART")
788             {
789                 mSelectedParts.push_back(words[1]);
790             }
791         }
792     }
793 }
794
795
796 bool MULTIPR_GUI::isPartExist(const char* partName)
797 {
798   //if (mMULTIPRObj == NULL) return false;
799     if (CORBA::is_nil(mMULTIPRObj)) return false;
800     
801     MULTIPR_ORB::string_array* listParts = mMULTIPRObj->getParts();
802     for (int i=0 ; i<listParts->length() ; i++)
803     {
804         const char* strItem = (*listParts)[i];
805         if (strcmp(strItem, partName) == 0) 
806         {
807             return true;
808         }
809     }
810     return false;
811 }
812
813
814 bool MULTIPR_GUI::removeLowerResolution()
815 {
816     // for each selected part, check if there are lower resolution
817     // and then propose to remove them before performing new process
818     QStringList partNameLowerResolution;
819     for (QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end();
820          it != last; it++)
821     {
822         const QString& partName = (*it);
823         QString partNameLow = partName + "_LOW";
824         QString partNameMed = partName + "_MED";
825         const char* strPartNameLow = partNameLow.latin1();
826         const char* strPartNameMed = partNameMed.latin1();
827         
828         if (isPartExist(strPartNameLow))
829         {
830             partNameLowerResolution.push_back(partNameLow);
831             cout << "Part to be removed: " << partNameLow << endl;
832         }
833         
834         if (isPartExist(strPartNameMed))
835         {
836             partNameLowerResolution.push_back(partNameMed);
837             cout << "Part to be removed: " << partNameMed << endl;
838         }
839     }
840      
841     if (partNameLowerResolution.count() > 0)
842     {
843         if (QMessageBox::question(
844                 getApp()->desktop(),
845                 tr("Remove previous results"),
846                 tr("Do you want to remove previous results?"),
847                 tr("&Yes"), tr("&No"),
848                 QString::null, 0, 1 ) )
849         {
850             return false;
851         }
852     
853         QApplication::setOverrideCursor(Qt::waitCursor);
854         
855         try
856         {
857             for (QStringList::const_iterator it = partNameLowerResolution.begin(),
858                    last = partNameLowerResolution.end(); it != last; it++)
859             {
860                 const QString& partName = (*it);
861                 cout << "Remove " << partName.latin1() << endl;
862                 mMULTIPRObj->removeParts(partName.latin1());
863             }
864             
865         }
866         catch(...)
867         {
868             SUIT_MessageBox::error1( 
869                 getApp()->desktop(),
870                 "Remove error", 
871                 "Error while removing previous results", 
872                 tr("MULTIPR_BUT_OK") );
873         }
874         
875         QApplication::restoreOverrideCursor();
876         
877         getApp()->updateObjectBrowser();
878         getApp()->updateActions();
879     }
880     
881     return true;
882 }
883
884
885 //*****************************************************************************
886 // Super class Data Object implementation
887 //*****************************************************************************
888
889 MULTIPR_GUI_DataObject::MULTIPR_GUI_DataObject (SUIT_DataObject* parent, const char* name)
890   : LightApp_DataObject(parent),
891     CAM_DataObject(parent)
892 {
893     mName = name;
894 }
895
896
897 MULTIPR_GUI_DataObject::~MULTIPR_GUI_DataObject()
898 {
899     // do nothing!
900 }
901
902
903 QString MULTIPR_GUI_DataObject::entry() const
904 {
905     return QString("MULTIPR_OBJECT");
906 }
907
908
909 QString MULTIPR_GUI_DataObject::name() const
910 {
911   return mName;
912 }
913
914
915 QPixmap MULTIPR_GUI_DataObject::icon() const
916 {
917     //static QPixmap icon = SUIT_Session::session()->resourceMgr()->loadPixmap("MULTIPR", QObject::tr("ICON_IMPORT_MED"), false);
918     return QPixmap();
919     
920 }
921
922
923 QString MULTIPR_GUI_DataObject::toolTip() const
924 {
925     // default behaviour: return an empty string
926     return "";
927 }
928
929
930 //*****************************************************************************
931 // Class Data Object Module implementation
932 //*****************************************************************************
933
934 MULTIPR_GUI_DataObject_Module::MULTIPR_GUI_DataObject_Module (CAM_DataModel* dm,
935                                                               SUIT_DataObject* parent,
936                                                               const char* name)
937   : MULTIPR_GUI_DataObject(parent, name),
938     LightApp_ModuleObject(dm, parent),
939     CAM_DataObject(parent)
940 {
941     // do nothing!
942 }
943
944
945 MULTIPR_GUI_DataObject_Module::~MULTIPR_GUI_DataObject_Module()
946 {
947     // do nothing!
948 }
949
950
951 QString MULTIPR_GUI_DataObject_Module::entry() const
952 {
953     return QString("MULTIPR_MODULE:" + mName);
954 }
955
956
957 QString MULTIPR_GUI_DataObject_Module::name() const
958 {
959   return CAM_RootObject::name();
960 }
961
962
963 QPixmap MULTIPR_GUI_DataObject_Module::icon() const
964 {
965     return QPixmap();
966 }
967
968
969 QString MULTIPR_GUI_DataObject_Module::toolTip() const
970 {
971     return QString("Module MULTIPR");
972 }
973
974
975 //*****************************************************************************
976 // Class Data Object Mesh implementation
977 //*****************************************************************************
978
979 MULTIPR_GUI_DataObject_Mesh::MULTIPR_GUI_DataObject_Mesh (SUIT_DataObject* parent, const char* name)
980   : MULTIPR_GUI_DataObject(parent, name),
981     CAM_DataObject(parent)
982 {
983     // do nothing!
984 }
985
986
987 MULTIPR_GUI_DataObject_Mesh::~MULTIPR_GUI_DataObject_Mesh()
988 {
989     // do nothing!
990 }
991
992
993 QString MULTIPR_GUI_DataObject_Mesh::entry() const
994 {
995     return QString("MULTIPR_MESH:") + mName;
996 }
997
998
999 QPixmap MULTIPR_GUI_DataObject_Mesh::icon() const
1000 {
1001     return QPixmap();
1002 }
1003
1004
1005 QString MULTIPR_GUI_DataObject_Mesh::toolTip() const
1006 {
1007     return QString("Original mesh");
1008 }
1009
1010
1011 //*****************************************************************************
1012 // Class Data Object Part implementation
1013 //*****************************************************************************
1014
1015 MULTIPR_GUI_DataObject_Part::MULTIPR_GUI_DataObject_Part (SUIT_DataObject* parent,
1016                                                           const char* name, const char* info)
1017   : MULTIPR_GUI_DataObject(parent, name),
1018     CAM_DataObject(parent)
1019 {
1020     mMeshName    = "";
1021     mId          = 0;
1022     mPath        = "";
1023     mMEDFileName = "";
1024     
1025     mTooltip = info;
1026     
1027     // parse info to retrieve all the fields
1028     char   lMeshName[256];
1029     int    lId;
1030     char   lPartName[256];
1031     char   lPath[256];
1032     char   lMEDFileName[256];
1033     
1034     int ret = sscanf(info, "%s %d %s %s %s", 
1035                 lMeshName,
1036                 &lId,
1037                 lPartName,
1038                 lPath,
1039                 lMEDFileName);
1040                 
1041     // number of read parameters should be 5
1042     if (ret != 5) return;
1043     
1044     mMeshName    = lMeshName;
1045     mId          = lId;
1046     mPath        = lPath;
1047     mMEDFileName = lMEDFileName;
1048 }
1049
1050
1051 MULTIPR_GUI_DataObject_Part::~MULTIPR_GUI_DataObject_Part()
1052 {
1053     // do nothing!
1054 }
1055
1056
1057 QString MULTIPR_GUI_DataObject_Part::entry() const
1058 {
1059     return QString("MULTIPR_PART:") + mName;
1060 }
1061
1062
1063 QPixmap MULTIPR_GUI_DataObject_Part::icon() const
1064 {
1065     return QPixmap();
1066 }
1067
1068
1069 QString MULTIPR_GUI_DataObject_Part::toolTip() const
1070 {
1071     return mTooltip;
1072 }
1073
1074
1075 //*****************************************************************************
1076 // Class Data Object Resolution implementation
1077 //*****************************************************************************
1078
1079 MULTIPR_GUI_DataObject_Resolution::MULTIPR_GUI_DataObject_Resolution (SUIT_DataObject* parent,
1080                                                                       const char* name, const char* info)
1081   : MULTIPR_GUI_DataObject_Part(parent, name, info),
1082     CAM_DataObject(parent)
1083 {
1084     // do nothing!
1085 }
1086
1087
1088 MULTIPR_GUI_DataObject_Resolution::~MULTIPR_GUI_DataObject_Resolution()
1089 {
1090     // do nothing!
1091 }
1092
1093
1094 QString MULTIPR_GUI_DataObject_Resolution::entry() const
1095 {
1096     return QString("MULTIPR_RESOLUTION:") + mName;
1097 }
1098
1099
1100 QPixmap MULTIPR_GUI_DataObject_Resolution::icon() const
1101 {
1102     return QPixmap();
1103 }
1104
1105
1106 QString MULTIPR_GUI_DataObject_Resolution::toolTip() const
1107 {
1108     return mTooltip;
1109 }
1110
1111
1112 //*****************************************************************************
1113 // Data Model
1114 //*****************************************************************************
1115
1116 MULTIPR_GUI_DataModel::MULTIPR_GUI_DataModel(CAM_Module* module)
1117   //: LightApp_DataModel(module)
1118   : SalomeApp_DataModel(module)
1119 {
1120     mMULTIPR_GUI = dynamic_cast<MULTIPR_GUI*>(module);
1121 }
1122
1123 MULTIPR_GUI_DataModel::~MULTIPR_GUI_DataModel()
1124 {
1125     // do nothing!
1126 }
1127
1128
1129 void MULTIPR_GUI_DataModel::update (LightApp_DataObject*, LightApp_Study* theStudy)
1130 {
1131   LightApp_ModuleObject* modelRoot = dynamic_cast<LightApp_ModuleObject*>( root() );
1132   DataObjectList ch;
1133   QMap<SUIT_DataObject*,int> aMap;
1134   if( modelRoot )
1135   {
1136     ch = modelRoot->children();
1137     for ( DataObjectListIterator it( ch ); it.current(); ++it )
1138       it.current()->setParent( 0 );
1139   }
1140
1141   buildAll(theStudy);
1142
1143   modelRoot = dynamic_cast<LightApp_ModuleObject*>( root() );
1144   if( modelRoot )
1145   {
1146     DataObjectList new_ch = modelRoot->children();
1147     for ( DataObjectListIterator it1( new_ch ); it1.current(); ++it1 )
1148       aMap.insert( it1.current(), 0 );
1149   }
1150
1151   updateWidgets();
1152
1153   for( DataObjectListIterator it( ch ); it.current(); ++it )
1154     if( !aMap.contains( it.current() ) )
1155       delete it.current();
1156 }
1157
1158 void MULTIPR_GUI_DataModel::build()
1159 {
1160 }
1161
1162 void MULTIPR_GUI_DataModel::buildAll (LightApp_Study* theStudy)
1163 {
1164   try
1165   {
1166     SalomeApp_Study* aSAStudy = dynamic_cast<SalomeApp_Study*>(theStudy);
1167     if (!aSAStudy)
1168       aSAStudy = dynamic_cast<SalomeApp_Study*>(getModule()->getApp()->activeStudy());
1169
1170     if (!aSAStudy) return;
1171
1172     MULTIPR_GUI_DataObject_Module* modelRoot = dynamic_cast<MULTIPR_GUI_DataObject_Module*>(root());
1173     if (!modelRoot)  
1174     {  
1175       // root is not set yet
1176       modelRoot = new MULTIPR_GUI_DataObject_Module(this, NULL, "MULTIPR");
1177       setRoot(modelRoot);
1178     }
1179
1180     // find SObject in Study
1181     MULTIPR_ORB::MULTIPR_Obj_ptr obj = MULTIPR_ORB::MULTIPR_Obj::_nil();
1182
1183     _PTR(SComponent) aSComp = aSAStudy->studyDS()->FindComponent(module()->name());
1184     if (aSComp)
1185     {
1186       _PTR(ChildIterator) it (aSAStudy->studyDS()->NewChildIterator(aSComp));
1187       if (it->More())
1188       {
1189         _PTR(SObject) aSObj = it->Value();
1190         string anIOR = aSObj->GetIOR();
1191         if (!anIOR.empty())
1192         {
1193           CORBA::Object_var anObj = mMULTIPR_GUI->getApp()->orb()->string_to_object(anIOR.c_str());
1194           obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
1195
1196           // set Object to MULTIPR_GUI
1197           mMULTIPR_GUI->setMULTIPRObj(obj);
1198         }
1199         //CORBA::Object_var anObj = aSObj->GetObject();
1200         //obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
1201         //if (!CORBA::is_nil(obj))
1202         //{
1203         //  // set Object to MULTIPR_GUI
1204         //  mMULTIPR_GUI->setMULTIPRObj(obj);
1205         //}
1206       }
1207
1208       // remove Data Objects, automatically built for not loaded MULTIPR module
1209       // by SalomeApp_Application::updateObjectBrowser
1210       if (aSAStudy->root())
1211       {
1212         DataObjectList ch_comp;
1213         aSAStudy->root()->children(ch_comp);
1214         DataObjectList::const_iterator anIt_comp = ch_comp.begin(), aLast_comp = ch_comp.end();
1215         for (; anIt_comp != aLast_comp; anIt_comp++)
1216         {
1217           LightApp_DataObject* dobj = dynamic_cast<LightApp_DataObject*>(*anIt_comp);
1218           if (dobj && dobj->name() == aSComp->GetName().c_str())
1219           {
1220             //SalomeApp_DataModelSync sync (aSAStudy->studyDS(), aSAStudy->root());
1221             //sync.deleteItemWithChildren(dobj);
1222             DataObjectList ch_obj;
1223             dobj->children(ch_obj);
1224             DataObjectList::const_iterator anIt_obj = ch_obj.begin(), aLast_obj = ch_obj.end();
1225             for (; anIt_obj != aLast_obj; anIt_obj++)
1226               // delete data object of each SObject
1227               delete (*anIt_obj);
1228
1229             // delete data object of SComponent itself
1230             delete dobj;
1231             break;
1232           }
1233         }
1234       }
1235     }
1236
1237     // build data tree
1238     if (!CORBA::is_nil(obj))
1239     {
1240       // MED file object
1241       std::string lMEDFile = obj->getFilename();
1242       std::string lMEDFileName = multipr::getFilenameWithoutPath(lMEDFile.c_str());
1243       MULTIPR_GUI_DataObject_Mesh* dataObjectMED =
1244         new MULTIPR_GUI_DataObject_Mesh(modelRoot, lMEDFileName.c_str());
1245
1246       // MESH object
1247       MULTIPR_ORB::string_array* listParts = obj->getParts();
1248
1249       if (listParts->length() >= 1)
1250       {
1251         const char* strPartName0 = (*listParts)[0];
1252         char* strPartInfo0 = obj->getPartInfo(strPartName0);
1253
1254         char   lMeshName[256];
1255         int    lId;
1256         char   lPartName[256];
1257         char   lPath[256];
1258         char   lMEDFileName[256];    
1259
1260         // parse infos
1261         int ret = sscanf(strPartInfo0, "%s %d %s %s %s", 
1262                          lMeshName,
1263                          &lId,
1264                          lPartName,
1265                          lPath,
1266                          lMEDFileName);
1267
1268         if (ret != 5) 
1269         {
1270           cout << "MULTIPR: build() tree; error while parsing part info" << endl;
1271           std::runtime_error("MULTIPR: build() tree; error while parsing part info");
1272           return;
1273         }
1274
1275         MULTIPR_GUI_DataObject_Mesh* dataObjectMesh =
1276           new MULTIPR_GUI_DataObject_Mesh(dataObjectMED, lMeshName);
1277
1278         // PART and RESOLUTION objects
1279         MULTIPR_GUI_DataObject_Part* dataObjectPart_prev = NULL;
1280
1281         for (int i = 0 ; i < listParts->length() ; i++)
1282         {
1283           const char* strItem = (*listParts)[i];
1284           char* strPartInfo = obj->getPartInfo(strItem);
1285
1286           // parse infos
1287           int ret = sscanf(strPartInfo, "%s %d %s %s %s", 
1288                            lMeshName,
1289                            &lId,
1290                            lPartName,
1291                            lPath,
1292                            lMEDFileName);
1293
1294           if (ret != 5) return;
1295
1296           if ((strstr(lPartName,"_MED") != NULL) || (strstr(lPartName,"_LOW") != NULL))
1297           {
1298             new MULTIPR_GUI_DataObject_Resolution(dataObjectPart_prev, strItem, strPartInfo);
1299           }
1300           else
1301           {
1302             dataObjectPart_prev = new MULTIPR_GUI_DataObject_Part(dataObjectMesh, strItem, strPartInfo);
1303           }
1304         }
1305       }
1306     }
1307   }
1308   catch (...)
1309   {
1310   }
1311 }
1312
1313
1314 extern "C" 
1315 {
1316     CAM_Module* createModule()
1317     {
1318         return new MULTIPR_GUI();
1319     }
1320 }
1321
1322
1323 // EOF