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