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