Salome HOME
Porting to Qt4 and autotools
[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             QObject::tr("SPLIT_WARN"), 
596 //            "Split warning", 
597             QObject::tr("NO_PART_SELECTED")); 
598 //            "No parts selected");
599         return;
600     }
601     
602     if (!removeLowerResolution())
603     {
604         return;
605     }
606     
607     MULTIPR_GUI_Partition2Dlg* dialog = new MULTIPR_GUI_Partition2Dlg(this);
608     dialog->exec();
609     delete dialog;
610     getApp()->updateObjectBrowser();
611     getApp()->updateActions();
612 }
613
614
615 void MULTIPR_GUI::OnDecimate()
616 {
617     // check if MULTIPRObj exists
618     //if (mMULTIPRObj == NULL)
619     if (CORBA::is_nil(mMULTIPRObj))
620     {
621         return;
622     }
623     
624     retrieveSelectedParts();
625     
626     if (mSelectedParts.count() == 0)
627     {
628         SUIT_MessageBox::warning( 
629             (QWidget*) MULTIPR_GUI::desktop(),
630             QObject::tr("DECIMATION_WARN"), 
631 //           "Decimation warning", 
632             QObject::tr("NO_PART_SELECTED")); 
633 //            "No parts selected"); 
634         return;
635     }
636
637     if (!removeLowerResolution())
638     {
639         return;
640     }
641
642     const QStringList& partsList = this->getSelectedParts();
643     QString allParts = partsList.join("|");
644     MULTIPR_ORB::string_array* listFields = this->getMULTIPRObj()->getFields(allParts.toLatin1());
645     if (listFields->length() == 0)
646     {
647       SUIT_MessageBox::critical( 
648             (QWidget*) MULTIPR_GUI::desktop(),
649             QObject::tr("DECIM_ERROR"), 
650 //            "Decimation error", 
651             QObject::tr("NO_FIELD_ON_PART"));
652 //          "No field for this part.",);
653       return ;
654     }
655
656     MULTIPR_GUI_DecimateDlg* dialog = new MULTIPR_GUI_DecimateDlg(this);
657     dialog->exec();
658     delete dialog;
659     getApp()->updateObjectBrowser();
660     getApp()->updateActions();
661 }
662
663
664 void MULTIPR_GUI::OnRemove()
665 {
666     // check if MULTIPRObj exists
667     //if (mMULTIPRObj == NULL)
668     if (CORBA::is_nil(mMULTIPRObj))
669     {
670         return;
671     }
672     
673     retrieveSelectedParts();
674     
675     if (mSelectedParts.count() == 0)
676     {
677         SUIT_MessageBox::warning( 
678             (QWidget*) MULTIPR_GUI::desktop(),
679             QObject::tr("DEL_WARN"), 
680 //            "Remove warning", 
681             QObject::tr("NO_PART_SELECTED"));
682 //           "No parts selected"); 
683         return;
684     }
685     
686     if (QMessageBox::question(
687             (QWidget*) MULTIPR_GUI::desktop(),
688             QObject::tr("DEL_SELECTED_PARTS"),
689 //            QObject::tr("Remove selected part(s)"),
690             QObject::tr("DEL_SELECTED_PARTS_QUEST"),
691 //           QObject::tr("Do you want to remove selected part(s)?"),
692             QObject::tr("&Yes"), tr("&No"),
693             QString::null, 0, 1 ) )
694     {
695         return;
696     }
697
698     QApplication::setOverrideCursor(Qt::WaitCursor);
699
700     try
701     {
702       QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end();
703       for (; it != last; it++)
704       {
705         const QString& partName = (*it);
706         cout << "Remove " << (const char*)partName.toLatin1() << endl;
707         mMULTIPRObj->removeParts(partName.toLatin1());
708       }
709     }
710     catch(...)
711     {
712         SUIT_MessageBox::critical( 
713             (QWidget*) MULTIPR_GUI::desktop(),
714             QObject::tr("DEL_ERROR"), 
715 //            "Remove error", 
716             QObject::tr("ERROR_DEL_PART"));
717 //            "Error while removing selected part(s)"); 
718     }
719
720     QApplication::restoreOverrideCursor();
721
722     getApp()->updateObjectBrowser();
723     getApp()->updateActions();
724 }
725
726
727 void MULTIPR_GUI::OnSave()
728 {
729   // check if MULTIPRObj exists
730   //if (mMULTIPRObj == NULL)
731   if (CORBA::is_nil(mMULTIPRObj))
732   {
733     return;
734   }
735
736     SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( (QWidget*) MULTIPR_GUI::desktop(), true,tr(""));
737
738   fd->setWindowTitle(tr("Save distributed MED file - Destination directory"));
739   fd->setFileMode(QFileDialog::DirectoryOnly);
740
741   if (fd->exec() == QDialog::Rejected)
742   {
743     delete fd;
744     return;
745   }
746
747   QFileInfo aFileInfo(fd->selectedFile());
748   delete fd;
749
750   QApplication::setOverrideCursor(Qt::WaitCursor);
751
752   QString path = aFileInfo.filePath();
753   mMULTIPRObj->resetSaveProgress();
754
755   MULTIPR_GUI_SaveThread* a = new MULTIPR_GUI_SaveThread (this, mMULTIPRObj, path);
756   a->start();
757
758   // save progress
759   //mProgress = new MULTIPR_GUI_ProgressCallbackDlg (getApp()->desktop());
760   //mProgress->start("Save mesh", 100);
761   if (mProgress == NULL)
762     mProgress = new QProgressDialog ("Save mesh", "Cancel", 0,/*totalSteps*/100, (QWidget*) MULTIPR_GUI::desktop());
763   //mProgress->setProgress(0);
764   //mProgress->init(100);
765   mTimer->start(500); // 0.5 seconds timer
766
767   //QApplication::restoreOverrideCursor();
768 }
769
770 void MULTIPR_GUI::timerDone()
771 {
772   int progress = mMULTIPRObj->getSaveProgress();
773   if (mProgress != NULL) {
774     mProgress->setValue(progress);
775
776     if (progress >= 100) {
777       mTimer->stop();
778     }
779   }
780 }
781
782 void MULTIPR_GUI::retrieveSelectedParts()
783 {
784     mSelectedParts.clear();
785
786     QStringList userSelection;
787     selected(userSelection, true);
788     for (QStringList::const_iterator it = userSelection.begin(), last = userSelection.end(); it != last; it++)
789     {
790         const QString& str = (*it);
791         QStringList words = str.split(":");
792         if (words.count() == 2)
793         {
794             if (words[0] == "MULTIPR_PART")
795             {
796                 mSelectedParts.push_back(words[1]);
797             }
798         }
799     }
800 }
801
802
803 bool MULTIPR_GUI::isPartExist(const char* partName)
804 {
805   //if (mMULTIPRObj == NULL) return false;
806     if (CORBA::is_nil(mMULTIPRObj)) return false;
807     
808     MULTIPR_ORB::string_array* listParts = mMULTIPRObj->getParts();
809     for (int i=0 ; i<listParts->length() ; i++)
810     {
811         const char* strItem = (*listParts)[i];
812         if (strcmp(strItem, partName) == 0) 
813         {
814             return true;
815         }
816     }
817     return false;
818 }
819
820
821 bool MULTIPR_GUI::removeLowerResolution()
822 {
823     // for each selected part, check if there are lower resolution
824     // and then propose to remove them before performing new process
825     QStringList partNameLowerResolution;
826     for (QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end();
827          it != last; it++)
828     {
829         const QString& partName = (*it);
830         QString partNameLow = partName + "_LOW";
831         QString partNameMed = partName + "_MED";
832         const char* strPartNameLow = partNameLow.toLatin1();
833         const char* strPartNameMed = partNameMed.toLatin1();
834         
835         if (isPartExist(strPartNameLow))
836         {
837             partNameLowerResolution.push_back(partNameLow);
838             cout << "Part to be removed: " << strPartNameLow << endl;
839         }
840         
841         if (isPartExist(strPartNameMed))
842         {
843             partNameLowerResolution.push_back(partNameMed);
844             cout << "Part to be removed: " << strPartNameMed << endl;
845         }
846     }
847      
848     if (partNameLowerResolution.count() > 0)
849     {
850         if (QMessageBox::question(
851                 (QWidget*) MULTIPR_GUI::desktop(),
852                 QObject::tr("DEL_PREV_RESULTS"),
853 //                tr("Remove previous results"),
854                 QObject::tr("DEL_PREV_RESULTS_QUEST"),
855 //                tr("Do you want to remove previous results?"),
856                 tr("&Yes"), tr("&No"),
857                 QString::null, 0, 1 ) )
858         {
859             return false;
860         }
861     
862         QApplication::setOverrideCursor(Qt::WaitCursor);
863         
864         try
865         {
866             for (QStringList::const_iterator it = partNameLowerResolution.begin(),
867                    last = partNameLowerResolution.end(); it != last; it++)
868             {
869                 const QString& partName = (*it);
870                 cout << "Remove " << (const char*)partName.toLatin1() << endl;
871                 mMULTIPRObj->removeParts(partName.toLatin1());
872             }
873             
874         }
875         catch(...)
876         {
877             SUIT_MessageBox::critical( 
878                 (QWidget*) MULTIPR_GUI::desktop(),
879                 QObject::tr("DEL_ERROR"),
880 //                "Remove error", 
881                 QObject::tr("ERROR_DEL_PREV_RESULT")); 
882 //                "Error while removing previous results", 
883         }
884         
885         QApplication::restoreOverrideCursor();
886         
887         getApp()->updateObjectBrowser();
888         getApp()->updateActions();
889     }
890     
891     return true;
892 }
893
894 SUIT_Desktop*  MULTIPR_GUI::desktop()
895 {
896   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
897   if( app )
898     return app->desktop();
899   else
900     return 0;
901 }
902
903
904 //*****************************************************************************
905 // Super class Data Object implementation
906 //*****************************************************************************
907
908 MULTIPR_GUI_DataObject::MULTIPR_GUI_DataObject (SUIT_DataObject* parent, const char* name)
909   : LightApp_DataObject(parent),
910     CAM_DataObject(parent)
911 {
912     mName = name;
913 }
914
915
916 MULTIPR_GUI_DataObject::~MULTIPR_GUI_DataObject()
917 {
918     // do nothing!
919 }
920
921
922 QString MULTIPR_GUI_DataObject::entry() const
923 {
924     return QString("MULTIPR_OBJECT");
925 }
926
927
928 QString MULTIPR_GUI_DataObject::name() const
929 {
930   return mName;
931 }
932
933
934 QPixmap MULTIPR_GUI_DataObject::icon() const
935 {
936     //static QPixmap icon = SUIT_Session::session()->resourceMgr()->loadPixmap("MULTIPR", QObject::tr("ICON_IMPORT_MED"), false);
937     return QPixmap();
938     
939 }
940
941
942 QString MULTIPR_GUI_DataObject::toolTip() const
943 {
944     // default behaviour: return an empty string
945     return "";
946 }
947
948
949 //*****************************************************************************
950 // Class Data Object Module implementation
951 //*****************************************************************************
952
953
954 MULTIPR_GUI_DataObject_Module::MULTIPR_GUI_DataObject_Module (CAM_DataModel* dm,
955                                                               SUIT_DataObject* parent,
956                                                               const char* name)
957   : MULTIPR_GUI_DataObject(parent, name),
958 //    LightApp_DataObject(dm, parent),
959     CAM_DataObject(parent)
960 {
961     // do nothing!
962     mDm = dm;
963     mParent = parent;
964 }
965
966
967 MULTIPR_GUI_DataObject_Module::~MULTIPR_GUI_DataObject_Module()
968 {
969     // do nothing!
970 }
971
972
973 QString MULTIPR_GUI_DataObject_Module::entry() const
974 {
975     return QString("MULTIPR_MODULE:" + mName);
976 }
977
978
979 QString MULTIPR_GUI_DataObject_Module::name() const
980 {
981   CAM_ModuleObject cam(mDm,mParent);
982   return cam.name();
983 }
984
985
986 QPixmap MULTIPR_GUI_DataObject_Module::icon() const
987 {
988     return QPixmap();
989 }
990
991
992 QString MULTIPR_GUI_DataObject_Module::toolTip() const
993 {
994     return QString("Module MULTIPR");
995 }
996
997
998 //*****************************************************************************
999 // Class Data Object Mesh implementation
1000 //*****************************************************************************
1001
1002 MULTIPR_GUI_DataObject_Mesh::MULTIPR_GUI_DataObject_Mesh (SUIT_DataObject* parent, const char* name)
1003   : MULTIPR_GUI_DataObject(parent, name),
1004     CAM_DataObject(parent)
1005 {
1006     // do nothing!
1007 }
1008
1009
1010 MULTIPR_GUI_DataObject_Mesh::~MULTIPR_GUI_DataObject_Mesh()
1011 {
1012     // do nothing!
1013 }
1014
1015
1016 QString MULTIPR_GUI_DataObject_Mesh::entry() const
1017 {
1018     return QString("MULTIPR_MESH:") + mName;
1019 }
1020
1021
1022 QPixmap MULTIPR_GUI_DataObject_Mesh::icon() const
1023 {
1024     return QPixmap();
1025 }
1026
1027
1028 QString MULTIPR_GUI_DataObject_Mesh::toolTip() const
1029 {
1030     return QString("Original mesh");
1031 }
1032
1033
1034 //*****************************************************************************
1035 // Class Data Object Part implementation
1036 //*****************************************************************************
1037
1038 MULTIPR_GUI_DataObject_Part::MULTIPR_GUI_DataObject_Part (SUIT_DataObject* parent,
1039                                                           const char* name, const char* info)
1040   : MULTIPR_GUI_DataObject(parent, name),
1041     CAM_DataObject(parent)
1042 {
1043     mMeshName    = "";
1044     mId          = 0;
1045     mPath        = "";
1046     mMEDFileName = "";
1047     
1048     mTooltip = info;
1049     
1050     // parse info to retrieve all the fields
1051     char   lMeshName[256];
1052     int    lId;
1053     char   lPartName[256];
1054     char   lPath[256];
1055     char   lMEDFileName[256];
1056     
1057     int ret = sscanf(info, "%s %d %s %s %s", 
1058                 lMeshName,
1059                 &lId,
1060                 lPartName,
1061                 lPath,
1062                 lMEDFileName);
1063                 
1064     // number of read parameters should be 5
1065     if (ret != 5) return;
1066     
1067     mMeshName    = lMeshName;
1068     mId          = lId;
1069     mPath        = lPath;
1070     mMEDFileName = lMEDFileName;
1071 }
1072
1073
1074 MULTIPR_GUI_DataObject_Part::~MULTIPR_GUI_DataObject_Part()
1075 {
1076     // do nothing!
1077 }
1078
1079
1080 QString MULTIPR_GUI_DataObject_Part::entry() const
1081 {
1082     return QString("MULTIPR_PART:") + mName;
1083 }
1084
1085
1086 QPixmap MULTIPR_GUI_DataObject_Part::icon() const
1087 {
1088     return QPixmap();
1089 }
1090
1091
1092 QString MULTIPR_GUI_DataObject_Part::toolTip() const
1093 {
1094     return mTooltip;
1095 }
1096
1097
1098 //*****************************************************************************
1099 // Class Data Object Resolution implementation
1100 //*****************************************************************************
1101
1102 MULTIPR_GUI_DataObject_Resolution::MULTIPR_GUI_DataObject_Resolution (SUIT_DataObject* parent,
1103                                                                       const char* name, const char* info)
1104   : MULTIPR_GUI_DataObject_Part(parent, name, info),
1105     CAM_DataObject(parent)
1106 {
1107     // do nothing!
1108 }
1109
1110
1111 MULTIPR_GUI_DataObject_Resolution::~MULTIPR_GUI_DataObject_Resolution()
1112 {
1113     // do nothing!
1114 }
1115
1116
1117 QString MULTIPR_GUI_DataObject_Resolution::entry() const
1118 {
1119     return QString("MULTIPR_RESOLUTION:") + mName;
1120 }
1121
1122
1123 QPixmap MULTIPR_GUI_DataObject_Resolution::icon() const
1124 {
1125     return QPixmap();
1126 }
1127
1128
1129 QString MULTIPR_GUI_DataObject_Resolution::toolTip() const
1130 {
1131     return mTooltip;
1132 }
1133
1134
1135 //*****************************************************************************
1136 // Data Model
1137 //*****************************************************************************
1138
1139 MULTIPR_GUI_DataModel::MULTIPR_GUI_DataModel(CAM_Module* module)
1140 // : LightApp_DataModel(module)
1141   : SalomeApp_DataModel(module)
1142 {
1143     mMULTIPR_GUI = dynamic_cast<MULTIPR_GUI*>(module);
1144 }
1145
1146 MULTIPR_GUI_DataModel::~MULTIPR_GUI_DataModel()
1147 {
1148     // do nothing!
1149 }
1150
1151 void MULTIPR_GUI_DataModel::update (LightApp_DataObject*, LightApp_Study* theStudy)
1152 {
1153   LightApp_ModuleObject* modelRoot = dynamic_cast<LightApp_ModuleObject*>( root() );
1154   DataObjectList ch;
1155   //QListIterator<SUIT_DataObject> it1,it2;
1156   QMap<SUIT_DataObject*,int> aMap;
1157   if( modelRoot )
1158   {
1159     ch = modelRoot->children();
1160     DataObjectList::const_iterator it = ch.begin(), it_last = ch.end();
1161     for (; it != it_last; it++)
1162         (*it)->setParent( 0);
1163   }
1164
1165   buildAll(theStudy);
1166
1167   modelRoot = dynamic_cast<LightApp_ModuleObject*>( root() );
1168   if( modelRoot )
1169   {
1170     DataObjectList new_ch = modelRoot->children();
1171     DataObjectList::const_iterator it1 = new_ch.begin(), it1_last = new_ch.end();
1172     for (; it1 != it1_last; it1++)
1173       aMap.insert((*it1),0);
1174   }
1175
1176   updateWidgets();
1177   DataObjectList::const_iterator it_del = ch.begin(), it_del_last = ch.end();
1178   for (; it_del != it_del_last; it_del++)
1179     if( !aMap.contains( (*it_del) ) )
1180       delete (*it_del);
1181 }
1182
1183 void MULTIPR_GUI_DataModel::build()
1184 {
1185 }
1186
1187 void MULTIPR_GUI_DataModel::buildAll (LightApp_Study* theStudy)
1188 {
1189   try
1190   {
1191     SalomeApp_Study* aSAStudy = dynamic_cast<SalomeApp_Study*>(theStudy);
1192     if (!aSAStudy)
1193       aSAStudy = dynamic_cast<SalomeApp_Study*>(getModule()->getApp()->activeStudy());
1194
1195     if (!aSAStudy) return;
1196
1197     MULTIPR_GUI_DataObject_Module* modelRoot = dynamic_cast<MULTIPR_GUI_DataObject_Module*>(root());
1198     if (!modelRoot)  
1199     {  
1200       // root is not set yet
1201       modelRoot = new MULTIPR_GUI_DataObject_Module(this, NULL, "MULTIPR");
1202       setRoot(modelRoot);
1203     }
1204
1205     // find SObject in Study
1206     MULTIPR_ORB::MULTIPR_Obj_ptr obj = MULTIPR_ORB::MULTIPR_Obj::_nil();
1207
1208     _PTR(SComponent) aSComp = aSAStudy->studyDS()->FindComponent(module()->name().toStdString());
1209     if (aSComp)
1210     {
1211       _PTR(ChildIterator) it (aSAStudy->studyDS()->NewChildIterator(aSComp));
1212       if (it->More())
1213       {
1214         _PTR(SObject) aSObj = it->Value();
1215         string anIOR = aSObj->GetIOR();
1216         if (!anIOR.empty())
1217         {
1218           CORBA::Object_var anObj = mMULTIPR_GUI->getApp()->orb()->string_to_object(anIOR.c_str());
1219           obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
1220
1221           // set Object to MULTIPR_GUI
1222           mMULTIPR_GUI->setMULTIPRObj(obj);
1223         }
1224         //CORBA::Object_var anObj = aSObj->GetObject();
1225         //obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
1226         //if (!CORBA::is_nil(obj))
1227         //{
1228         //  // set Object to MULTIPR_GUI
1229         //  mMULTIPR_GUI->setMULTIPRObj(obj);
1230         //}
1231       }
1232
1233       // remove Data Objects, automatically built for not loaded MULTIPR module
1234       // by SalomeApp_Application::updateObjectBrowser
1235       if (aSAStudy->root())
1236       {
1237         DataObjectList ch_comp;
1238         aSAStudy->root()->children(ch_comp);
1239         DataObjectList::const_iterator anIt_comp = ch_comp.begin(), aLast_comp = ch_comp.end();
1240         for (; anIt_comp != aLast_comp; anIt_comp++)
1241         {
1242           LightApp_DataObject* dobj = dynamic_cast<LightApp_DataObject*>(*anIt_comp);
1243           if (dobj && dobj->name() == aSComp->GetName().c_str())
1244           {
1245             //SalomeApp_DataModelSync sync (aSAStudy->studyDS(), aSAStudy->root());
1246             //sync.deleteItemWithChildren(dobj);
1247             DataObjectList ch_obj;
1248             dobj->children(ch_obj);
1249             DataObjectList::const_iterator anIt_obj = ch_obj.begin(), aLast_obj = ch_obj.end();
1250             for (; anIt_obj != aLast_obj; anIt_obj++)
1251               // delete data object of each SObject
1252               delete (*anIt_obj);
1253
1254             // delete data object of SComponent itself
1255             delete dobj;
1256             break;
1257           }
1258         }
1259       }
1260     }
1261
1262     // build data tree
1263     if (!CORBA::is_nil(obj))
1264     {
1265       // MED file object
1266       std::string lMEDFile = obj->getFilename();
1267       std::string lMEDFileName = multipr::getFilenameWithoutPath(lMEDFile.c_str());
1268       MULTIPR_GUI_DataObject_Mesh* dataObjectMED =
1269         new MULTIPR_GUI_DataObject_Mesh(modelRoot, lMEDFileName.c_str());
1270
1271       // MESH object
1272       MULTIPR_ORB::string_array* listParts = obj->getParts();
1273
1274       if (listParts->length() >= 1)
1275       {
1276         const char* strPartName0 = (*listParts)[0];
1277         char* strPartInfo0 = obj->getPartInfo(strPartName0);
1278
1279         char   lMeshName[256];
1280         int    lId;
1281         char   lPartName[256];
1282         char   lPath[256];
1283         char   lMEDFileName[256];    
1284
1285         // parse infos
1286         int ret = sscanf(strPartInfo0, "%s %d %s %s %s", 
1287                          lMeshName,
1288                          &lId,
1289                          lPartName,
1290                          lPath,
1291                          lMEDFileName);
1292
1293         if (ret != 5) 
1294         {
1295           cout << "MULTIPR: build() tree; error while parsing part info" << endl;
1296           std::runtime_error("MULTIPR: build() tree; error while parsing part info");
1297           return;
1298         }
1299
1300         MULTIPR_GUI_DataObject_Mesh* dataObjectMesh =
1301           new MULTIPR_GUI_DataObject_Mesh(dataObjectMED, lMeshName);
1302
1303         // PART and RESOLUTION objects
1304         MULTIPR_GUI_DataObject_Part* dataObjectPart_prev = NULL;
1305
1306         for (int i = 0 ; i < listParts->length() ; i++)
1307         {
1308           const char* strItem = (*listParts)[i];
1309           char* strPartInfo = obj->getPartInfo(strItem);
1310
1311           // parse infos
1312           int ret = sscanf(strPartInfo, "%s %d %s %s %s", 
1313                            lMeshName,
1314                            &lId,
1315                            lPartName,
1316                            lPath,
1317                            lMEDFileName);
1318
1319           if (ret != 5) return;
1320
1321           if ((strstr(lPartName,"_MED") != NULL) || (strstr(lPartName,"_LOW") != NULL))
1322           {
1323             new MULTIPR_GUI_DataObject_Resolution(dataObjectPart_prev, strItem, strPartInfo);
1324           }
1325           else
1326           {
1327             dataObjectPart_prev = new MULTIPR_GUI_DataObject_Part(dataObjectMesh, strItem, strPartInfo);
1328           }
1329         }
1330       }
1331     }
1332   }
1333   catch (...)
1334   {
1335   }
1336 }
1337
1338
1339 extern "C" 
1340 {
1341     CAM_Module* createModule()
1342     {
1343         return new MULTIPR_GUI();
1344     }
1345 }
1346
1347
1348 // EOF