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