Salome HOME
Rename Engines::Component to Engines::EngineComponent
[modules/multipr.git] / src / MULTIPRGUI / MULTIPR_GUI.cxx
index 3ce03305919b1a3c3976fb432b5ede955d14d7d2..67fd1cacf8a31571397921948683618fea3a88ed 100644 (file)
@@ -1,4 +1,21 @@
-// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
 // Partitioning/decimation module for the SALOME v3.2 platform
 
 /**
  * \brief   see MULTIPR_GUI.h
  *
  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
- * 
+ *
  * \date    01/2007
  */
-  
+
 //*****************************************************************************
 // Includes section
 //*****************************************************************************
 // MULTIPR Includes
 #include "MULTIPR_GUI.h"
 #include "MULTIPR_GUI_Dlg.h"
+#include "MULTIPR_Utils.hxx"
 
 // Salome Includes
-#include <SUIT_MessageBox.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Session.h>
 #include <SalomeApp_Application.h>
 #include <SalomeApp_DataModel.h>
 #include <SalomeApp_Study.h>
 #include <SalomeApp_CheckFileDlg.h>
+
 #include <LightApp_Study.h>
 #include <LightApp_DataModel.h>
 #include <LightApp_DataOwner.h>
 #include <LightApp_SelectionMgr.h>
+
 #include <CAM_DataModel.h>
 #include <CAM_Module.h>
 
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+
 #include <SALOME_LifeCycleCORBA.hxx>
+#include <SALOMEDS_Study.hxx>
+
+#include <SALOME_Event.h>
 
 #include <QtxPopupMgr.h>
 
 // QT Includes
-#include <qapplication.h>
-#include <qinputdialog.h>
-#include <qlayout.h>
-#include <qpushbutton.h>
-#include <qgroupbox.h>
-#include <qvbox.h>
-#include <qbuttongroup.h>
-#include <qlabel.h>
-#include <qcombobox.h>
-#include <qvariant.h>
-#include <qlineedit.h>
-#include <qspinbox.h>
-#include <qtooltip.h>
-#include <qwhatsthis.h>
-#include <qimage.h>
-#include <qpixmap.h>
-#include <qmessagebox.h>
-
+#include <QApplication>
+#include <QInputDialog>
+#include <QLayout>
+#include <QPushButton>
+#include <QGroupBox>
+#include <QVBoxLayout>
+#include <QButtonGroup>
+#include <QLabel>
+#include <QComboBox>
+#include <QVariant>
+#include <QLineEdit>
+#include <QSpinBox>
+#include <QToolTip>
+#include <QWhatsThis>
+#include <QImage>
+#include <QPixmap>
+#include <QMessageBox>
+#include <QAction>
+#include <QTimer>
+#include <QThread>
+//#include <QPtrList>
+#include <QListIterator>
+#include <stdexcept>
 
 using namespace std;
 
-
 //*****************************************************************************
 // Global variable
 //*****************************************************************************
 
-namespace multipr
+//namespace multipr
+//{
+//    // progress callback used by the MULTIPR library
+//    extern MULTIPR_ProgressCallback*  gProgressCallback;
+//    extern MULTIPR_EmptyMeshCallback* gEmptyMeshCallback;
+//}
+class MULTIPR_GUI_FinishSaveEvent: public SALOME_Event
+{
+  SalomeApp_Application* myApp;
+  bool myIsError;
+public:
+  MULTIPR_GUI_FinishSaveEvent (SalomeApp_Application* theApp,
+                               bool theIsError)
+    : myApp(theApp),
+      myIsError(theIsError)
+  {}
+  virtual void Execute()
+  {
+    if (myIsError) {
+      SUIT_MessageBox::critical((QWidget*) MULTIPR_GUI::desktop(),
+                            QObject::tr("SAVE_DISTMED_ERROR"),
+//                           QString("Save distributed MED file error"),
+                              QObject::tr("WRIT_DISTMED_ERROR"));
+//                            QString("Error while writing distributed MED file"));
+    }
+    else {
+      myApp->updateObjectBrowser();
+      myApp->updateActions();
+    }
+    QApplication::restoreOverrideCursor();
+  }
+};
+
+class MULTIPR_GUI_SaveThread : public QThread
+{
+public:
+  MULTIPR_GUI_SaveThread (MULTIPR_GUI* pModule,
+                          MULTIPR_ORB::MULTIPR_Obj_ptr pObj,
+                          QString pPath)
+    : mModule(pModule)
+  {
+    mObj = MULTIPR_ORB::MULTIPR_Obj::_duplicate(pObj);
+    mPath = pPath;
+  }
+  virtual void run();
+
+private:
+  MULTIPR_GUI* mModule;
+  MULTIPR_ORB::MULTIPR_Obj_ptr mObj;
+  QString mPath;
+};
+
+void MULTIPR_GUI_SaveThread::run()
+{
+  try
+  {
+    mObj->save(mPath.toLatin1());
+  }
+  catch(...)
+  {
+    ProcessVoidEvent(new MULTIPR_GUI_FinishSaveEvent(mModule->getApp(), true));
+    return;
+  }
+
+  ProcessVoidEvent(new MULTIPR_GUI_FinishSaveEvent(mModule->getApp(), false));
+}
+
+//*****************************************************************************
+// Global function
+//*****************************************************************************
+
+// singleton
+MULTIPR_ORB::MULTIPR_Gen_ptr GetMultiprGen (SalomeApp_Application* app)
 {
-       // progress callback used by the MULTIPR library
-       extern MULTIPR_ProgressCallback* gProgressCallback;
+    static MULTIPR_ORB::MULTIPR_Gen_ptr aGen = NULL;
+
+    if (!aGen)
+    {
+        SALOME_LifeCycleCORBA aLCC (SalomeApp_Application::namingService());
+        Engines::EngineComponent_var comp = app->lcc()->FindOrLoad_Component( "FactoryServer","MULTIPR" );
+        aGen = MULTIPR_ORB::MULTIPR_Gen::_narrow(comp);
+        if (!CORBA::is_nil(aGen))
+        {
+          // Set current study
+          SalomeApp_Study* aSAStudy =dynamic_cast<SalomeApp_Study*>(app->activeStudy());
+          _PTR(Study) aStudy = aSAStudy->studyDS();
+          SALOMEDS::Study_ptr aStudyDS;
+          if (aStudy)
+            aStudyDS = _CAST(Study,aStudy)->GetStudy();
+          aGen->SetCurrentStudy(aStudyDS);
+        }
+    }
+
+    if (CORBA::is_nil(aGen))
+        throw std::runtime_error("Can't find MULTIPR component");
+
+    return aGen;
 }
 
 
@@ -76,547 +197,713 @@ namespace multipr
 // Class MULTIPR_GUI implementation
 //*****************************************************************************
 
-MULTIPR_GUI::MULTIPR_GUI() : SalomeApp_Module("MULTIPR")
+MULTIPR_GUI::MULTIPR_GUI()
+  : SalomeApp_Module("MULTIPR"),
+    LightApp_Module( "MULTIPR" ),
+    //mMULTIPRObj(NULL),
+    mMEDFileName(""),
+    mProgress(NULL)
 {
-       mMEDFileName = "";
-       mMULTIPRObj = NULL;
+  mTimer = new QTimer (this);
+  connect(mTimer, SIGNAL(timeout()), this, SLOT(timerDone()));
 }
 
 
-MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_GUI::getMULTIPRObj()
+MULTIPR_GUI::~MULTIPR_GUI()
 {
-       return mMULTIPRObj;
+  //if (mMULTIPRObj != NULL)
+  if (!CORBA::is_nil(mMULTIPRObj))
+    {
+        CORBA::release(mMULTIPRObj);
+    }
 }
 
 
-SalomeApp_Application* MULTIPR_GUI::getAppli() const
+MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_GUI::getMULTIPRObj()
 {
-       return getApp();
+    return mMULTIPRObj;
 }
 
+void MULTIPR_GUI::setMULTIPRObj (MULTIPR_ORB::MULTIPR_Obj_ptr theObj)
+{
+  mMULTIPRObj = MULTIPR_ORB::MULTIPR_Obj::_duplicate(theObj);
+}
 
-MULTIPR_ORB::MULTIPR_Gen_ptr MULTIPR_GUI::InitMULTIPRGen(SalomeApp_Application* app)
+SalomeApp_Application* MULTIPR_GUI::getAppli() const
 {
-       Engines::Component_var comp = app->lcc()->FindOrLoad_Component("FactoryServer", "MULTIPR");
-       MULTIPR_ORB::MULTIPR_Gen_ptr clr = MULTIPR_ORB::MULTIPR_Gen::_narrow(comp);
-       ASSERT(!CORBA::is_nil(clr));
-       return clr;
+    return getApp();
 }
 
 
 void MULTIPR_GUI::initialize(CAM_Application* app)
 {
-       SalomeApp_Module::initialize(app);
-       
-       InitMULTIPRGen(dynamic_cast<SalomeApp_Application*>(app));
-       
-       QWidget* aParent = app->desktop();
-       SUIT_ResourceMgr* aResourceMgr = app->resourceMgr();
-       
-       //-------------------------------------------------------------------------
-       // create actions
-       //-------------------------------------------------------------------------     
-       QPixmap aPixmapImportFromMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("ICON_IMPORT_MED"));
-       
-       createAction( 
-               ACTION_IMPORT_MED, 
-               tr("TLT_IMPORT_FROM_MED_FILE"), 
-               QIconSet(aPixmapImportFromMEDFile), 
-               tr("MEN_IMPORT_FROM_MED_FILE"), 
-               tr("STS_IMPORT_FROM_MED_FILE"), 
-               (CTRL + Key_I),
-               aParent, 
-               false,
-               this, 
-               SLOT(OnImportFromMEDFile()));
-               
-       createAction( 
-               ACTION_SPLIT, 
-               tr("TLT_SPLIT"), 
-               QIconSet(), 
-               tr("MEN_SPLIT"), 
-               tr("STS_SPLIT"), 
-               0,
-               aParent, 
-               false,
-               this, 
-               SLOT(OnPartition2()));
-       
-       createAction( 
-               ACTION_DECIMATE, 
-               tr("TLT_DECIMATE"), 
-               QIconSet(), 
-               tr("MEN_DECIMATE"), 
-               tr("STS_DECIMATE"), 
-               0,
-               aParent, 
-               false,
-               this, 
-               SLOT(OnDecimate()));
-       
-       createAction( 
-               ACTION_REMOVE, 
-               tr("TLT_REMOVE"), 
-               QIconSet(), 
-               tr("MEN_REMOVE"), 
-               tr("STS_REMOVE"), 
-               0,
-               aParent, 
-               false,
-               this, 
-               SLOT(OnRemove()));
-               
-       QPixmap aPixmapSaveMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("ICON_SAVE_MED"));
-       
-       createAction( 
-               ACTION_SAVE, 
-               tr("TLT_SAVE"), 
-               QIconSet(aPixmapSaveMEDFile), 
-               tr("MEN_SAVE"), 
-               tr("STS_SAVE"), 
-               0,
-               aParent, 
-               false,
-               this, 
-               SLOT(OnSave()));
-       
-       //-------------------------------------------------------------------------
-       // create menus
-       //-------------------------------------------------------------------------
-       int aMenuId;
-       aMenuId = createMenu(tr("MEN_FILE"), -1, -1);
-       createMenu(separator(), aMenuId, -1, 10);
-       aMenuId = createMenu(tr("MEN_FILE_MULTIPR"), aMenuId, -1, 10);
-       createMenu(ACTION_IMPORT_MED, aMenuId);
-       
-       aMenuId = createMenu(tr("MEN_MULTIPR"), -1, -1, 30);
-       createMenu(ACTION_IMPORT_MED, aMenuId, 10);
-       createMenu(ACTION_SAVE, aMenuId, 10);
-       createMenu(ACTION_SPLIT, aMenuId, 10);
-       createMenu(ACTION_DECIMATE, aMenuId, 10);
-       createMenu(ACTION_REMOVE, aMenuId, 10);
-       
-       //-------------------------------------------------------------------------
-       // create toolbars
-       //-------------------------------------------------------------------------
-       int aToolId = createTool(tr("TOOL_MULTIPR"));
-       createTool(ACTION_IMPORT_MED, aToolId);
-       createTool(ACTION_SAVE, aToolId);
-       
-       //-------------------------------------------------------------------------
-       // create popup menus
-       //-------------------------------------------------------------------------
-       QtxPopupMgr* mgr = popupMgr();
-       mgr->insert( action(ACTION_SPLIT), -1, -1, -1 );
-       mgr->insert( action(ACTION_DECIMATE), -1, -1, -1 );
-       mgr->insert( action(ACTION_REMOVE), -1, -1, -1 );
-       mgr->insert( action(ACTION_SAVE), -1, -1, -1 );
-       
-       QString aRule = "client='ObjectBrowser' and selcount>=1"; // $type in {'VISU::TMESH'}";
-       mgr->setRule(action(ACTION_SPLIT), aRule, true);
-       mgr->setRule(action(ACTION_DECIMATE), aRule, true);
-       mgr->setRule(action(ACTION_REMOVE), aRule, true);
-       mgr->setRule(action(ACTION_SAVE), aRule, true);
-       
-       //-------------------------------------------------------------------------
-       // set progress dialog
-       //-------------------------------------------------------------------------
-       MULTIPR_GUI_ProgressCallbackDlg* progressDlg = new MULTIPR_GUI_ProgressCallbackDlg(application()->desktop());
-       multipr::gProgressCallback = progressDlg;
+    SalomeApp_Module::initialize(app);
+
+    GetMultiprGen(dynamic_cast<SalomeApp_Application*>( app ));
+
+    QWidget* aParent = (QWidget*) application()->desktop();
+    SUIT_ResourceMgr* aResourceMgr = app->resourceMgr();
+
+    //-------------------------------------------------------------------------
+    // create actions
+    //-------------------------------------------------------------------------
+    QPixmap aPixmapImportFromMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("MULTIPR_ICON_IMPORT_MED"));
+
+    createAction(
+        ACTION_IMPORT_MED,
+        tr("MULTIPR_TLT_IMPORT_FROM_MED_FILE"),
+        QIcon(aPixmapImportFromMEDFile),
+        tr("MULTIPR_MEN_IMPORT_FROM_MED_FILE"),
+        tr("MULTIPR_STS_IMPORT_FROM_MED_FILE"),
+        (Qt::CTRL + Qt::Key_I),
+        aParent,
+        false,
+        this,
+        SLOT(OnImportFromMEDFile()));
+
+    createAction(
+        ACTION_SPLIT,
+        tr("MULTIPR_TLT_SPLIT"),
+        QIcon(),
+        tr("MULTIPR_MEN_SPLIT"),
+        tr("MULTIPR_STS_SPLIT"),
+        0,
+        aParent,
+        false,
+        this,
+        SLOT(OnPartition2()));
+
+    createAction(
+        ACTION_DECIMATE,
+        tr("MULTIPR_TLT_DECIMATE"),
+        QIcon(),
+        tr("MULTIPR_MEN_DECIMATE"),
+        tr("MULTIPR_STS_DECIMATE"),
+        0,
+        aParent,
+        false,
+        this,
+        SLOT(OnDecimate()));
+
+    createAction(
+        ACTION_REMOVE,
+        tr("MULTIPR_TLT_REMOVE"),
+        QIcon(),
+        tr("MULTIPR_MEN_REMOVE"),
+        tr("MULTIPR_STS_REMOVE"),
+        0,
+        aParent,
+        false,
+        this,
+        SLOT(OnRemove()));
+
+    QPixmap aPixmapSaveMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("MULTIPR_ICON_SAVE_MED"));
+
+    createAction(
+        ACTION_SAVE,
+        tr("MULTIPR_TLT_SAVE"),
+        QIcon(aPixmapSaveMEDFile),
+        tr("MULTIPR_MEN_SAVE"),
+        tr("MULTIPR_STS_SAVE"),
+        0,
+        aParent,
+        false,
+        this,
+        SLOT(OnSave()));
+
+    //-------------------------------------------------------------------------
+    // create menus
+    //-------------------------------------------------------------------------
+    int aMenuId;
+    aMenuId = createMenu(tr("MULTIPR_MEN_FILE"), -1, -1);
+    createMenu(separator(), aMenuId, -1, 10);
+    aMenuId = createMenu(tr("MULTIPR_MEN_FILE_MULTIPR"), aMenuId, -1, 10);
+    createMenu(ACTION_IMPORT_MED, aMenuId);
+
+    aMenuId = createMenu(tr("MULTIPR_MEN_MULTIPR"), -1, -1, 30);
+    createMenu(ACTION_IMPORT_MED, aMenuId, 10);
+    createMenu(ACTION_SAVE, aMenuId, 10);
+    createMenu(ACTION_SPLIT, aMenuId, 10);
+    createMenu(ACTION_DECIMATE, aMenuId, 10);
+    createMenu(ACTION_REMOVE, aMenuId, 10);
+
+    //-------------------------------------------------------------------------
+    // create toolbars
+    //-------------------------------------------------------------------------
+    int aToolId = createTool(tr("MULTIPR_TOOL_MULTIPR"));
+    createTool(ACTION_IMPORT_MED, aToolId);
+    createTool(ACTION_SAVE, aToolId);
+
+    //-------------------------------------------------------------------------
+    // create popup menus
+    //-------------------------------------------------------------------------
+    QtxPopupMgr* mgr = popupMgr();
+    mgr->insert( action(ACTION_SPLIT), -1, -1, -1 );
+    mgr->insert( action(ACTION_DECIMATE), -1, -1, -1 );
+    mgr->insert( action(ACTION_REMOVE), -1, -1, -1 );
+    mgr->insert( action(ACTION_SAVE), -1, -1, -1 );
+
+    QString aRule = "client='ObjectBrowser' and selcount>=1"; // $type in {'VISU::TMESH'}";
+    mgr->setRule(action(ACTION_SPLIT), aRule);
+    mgr->setRule(action(ACTION_DECIMATE), aRule);
+    mgr->setRule(action(ACTION_REMOVE), aRule);
+    mgr->setRule(action(ACTION_SAVE), aRule);
+
+    //-------------------------------------------------------------------------
+    // set progress dialog
+    //-------------------------------------------------------------------------
+    //MULTIPR_GUI_ProgressCallbackDlg* progressDlg =
+    //  new MULTIPR_GUI_ProgressCallbackDlg(application()->desktop());
+    //multipr::gProgressCallback = progressDlg;
+
+    //MULTIPR_GUI_EmptyMeshCallbackDlg* emptyMeshDlg =
+    //  new MULTIPR_GUI_EmptyMeshCallbackDlg(application()->desktop());
+    //multipr::gEmptyMeshCallback = emptyMeshDlg;
 }
 
 
 CAM_DataModel* MULTIPR_GUI::createDataModel()
 {
-       return new MULTIPR_GUI_DataModel(this);
+    return new MULTIPR_GUI_DataModel(this);
 }
 
 
 QString MULTIPR_GUI::engineIOR() const
 {
-       CORBA::String_var anIOR = getApp()->orb()->object_to_string(InitMULTIPRGen(getApp()));
-       return QString(anIOR.in());
+//   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(this);
+    CORBA::String_var anIOR = getApp()->orb()->object_to_string(GetMultiprGen(getApp()));
+    return QString(anIOR.in());
 }
 
-
 bool MULTIPR_GUI::activateModule(SUIT_Study* theStudy)
 {
-       bool bOk = SalomeApp_Module::activateModule(theStudy);
-       
-       setMenuShown(true);
-       setToolShown(true);
-       
-       return bOk;
+    bool bOk = SalomeApp_Module::activateModule(theStudy);
+
+    setMenuShown(true);
+    setToolShown(true);
+
+    action(ACTION_IMPORT_MED)->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_I));
+
+    // Set current study
+    MULTIPR_ORB::MULTIPR_Gen_ptr aGen = GetMultiprGen(dynamic_cast<SalomeApp_Application*>(this));
+    SalomeApp_Study* aSAStudy = dynamic_cast<SalomeApp_Study*>(theStudy);
+    _PTR(Study) aStudy = aSAStudy->studyDS();
+    SALOMEDS::Study_ptr aStudyDS;
+    if (aStudy)
+      aStudyDS = _CAST(Study,aStudy)->GetStudy();
+    aGen->SetCurrentStudy(aStudyDS);
+
+    // Init mMULTIPRObj
+    _PTR(SComponent) aSComp = aStudy->FindComponent(name().toStdString());
+    if (aSComp) {
+      _PTR(ChildIterator) it (aStudy->NewChildIterator(aSComp));
+      if (it->More()) {
+        _PTR(SObject) aSObj = it->Value();
+        string anIOR = aSObj->GetIOR();
+        if (!anIOR.empty()) {
+          CORBA::Object_var anObj = getApp()->orb()->string_to_object(anIOR.c_str());
+          mMULTIPRObj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
+        }
+      }
+    }
+
+    return bOk;
 }
 
 
 bool MULTIPR_GUI::deactivateModule(SUIT_Study* theStudy)
 {
-       setMenuShown(false);
-       setToolShown(false);
-       
-       return SalomeApp_Module::deactivateModule(theStudy);
+    setMenuShown(false);
+    setToolShown(false);
+
+    // Unset actions accelerator keys
+    action(ACTION_IMPORT_MED)->setShortcut(QKeySequence());
+
+    mMULTIPRObj = MULTIPR_ORB::MULTIPR_Obj::_nil();
+
+    return SalomeApp_Module::deactivateModule(theStudy);
 }
 
 
 void MULTIPR_GUI::windows(QMap<int, int>& theMap) const
 {
-       theMap.clear();
-       theMap.insert(SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft);
-       theMap.insert(SalomeApp_Application::WT_PyConsole,     Qt::DockBottom);
+    theMap.clear();
+    theMap.insert(SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea);
+    theMap.insert(SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea);
 }
 
 
 void MULTIPR_GUI::selected(QStringList& entries, const bool multiple)
 {
-       LightApp_SelectionMgr* mgr = getApp()->selectionMgr();
-       
-       if(!mgr) return;
-       
-       SUIT_DataOwnerPtrList anOwnersList;
-       mgr->selected(anOwnersList);
-       
-       for (int i = 0 ; i < anOwnersList.size() ; i++)
-       {
-               const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>(anOwnersList[i].get());
-               
-               if (!entries.contains(owner->entry()))
-               {
-                       entries.append(owner->entry());
-               }
-                       
-               if (!multiple)
-                       break;
-       }
+    LightApp_SelectionMgr* mgr = getApp()->selectionMgr();
+
+    if(!mgr) return;
+
+    SUIT_DataOwnerPtrList anOwnersList;
+    mgr->selected(anOwnersList);
+
+    for (int i = 0 ; i < anOwnersList.size() ; i++)
+    {
+        const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>(anOwnersList[i].get());
+
+        if (!entries.contains(owner->entry()))
+        {
+            entries.append(owner->entry());
+        }
+
+        if (!multiple)
+            break;
+    }
 }
 
 
 void MULTIPR_GUI::OnImportFromMEDFile()
 {
-       // Get file name
-       QStringList aFilter;
-       aFilter.append(tr("FLT_MED_FILES"));
-       aFilter.append(tr("FLT_ALL_FILES"));
-       
-       SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg(
-               this->application()->desktop(), 
-               true, 
-               tr("USE_BUILD_PROGRESS") );
-               
-       fd->setCaption(tr("MEN_IMPORT_FROM_MED_FILE"));
-       fd->setFilters(aFilter);
-       fd->exec();
-       QFileInfo aFileInfo(fd->selectedFile());
-       delete fd;
-       
-       // Check the file name
-       if (!aFileInfo.exists())
-               return;
-               
-       mMEDFileName = aFileInfo.filePath();
-       
-       QApplication::setOverrideCursor(Qt::waitCursor);
-       
-       try
-       {
-               MULTIPR_ORB::MULTIPR_Gen_ptr multiprgen = MULTIPR_GUI::InitMULTIPRGen(getApp());
-               mMULTIPRObj = multiprgen->getObject(mMEDFileName.latin1());
-       }
-       catch(...)
-       {
-               SUIT_MessageBox::error1( 
-                       getApp()->desktop(),
-                       "Import MED file error", 
-                       "Invalid MED file (not recognized by MULTIPR)", 
-                       tr("OK") );
-       }
-       QApplication::restoreOverrideCursor();
-       
-       if (mMULTIPRObj != NULL)
-       {
-               try
-               {
-                       if (mMULTIPRObj->isValidSequentialMEDFile())
-                       {
-                               OnPartition1();
-                       }
-               }
-               catch (...)
-               {
-               }
-               
-               getApp()->updateObjectBrowser();
-       }
+    // Get file name
+    QStringList aFilter;
+    aFilter.append(tr("MULTIPR_FLT_MED_FILES"));
+    aFilter.append(tr("MULTIPR_FLT_ALL_FILES"));
+
+    SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg(
+        (QWidget*) MULTIPR_GUI::desktop(),
+        true,
+        tr("") );
+
+    fd->setWindowTitle(tr("MULTIPR_MEN_IMPORT_FROM_MED_FILE"));
+    fd->setFilters(aFilter);
+    if (fd->exec() == QDialog::Rejected)
+    {
+        delete fd;
+        return;
+    }
+
+    QFileInfo aFileInfo(fd->selectedFile());
+    delete fd;
+
+    // Check the file name
+    if (!aFileInfo.exists())
+        return;
+
+    mMEDFileName = aFileInfo.filePath();
+
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+
+    // Delete previous MULTIPR object.
+    //if (mMULTIPRObj != NULL)
+    if (!CORBA::is_nil(mMULTIPRObj) && !mMULTIPRObj->_non_existent())
+    {
+        mMULTIPRObj->reset();
+    }
+
+    MULTIPR_ORB::MULTIPR_Gen_ptr multiprgen = GetMultiprGen(dynamic_cast<SalomeApp_Application*>( this ));
+
+    try
+    {
+      mMULTIPRObj = multiprgen->getObject(mMEDFileName.toLatin1());
+    }
+    catch(...)
+    {
+        SUIT_MessageBox::critical(
+            (QWidget*) MULTIPR_GUI::desktop(),
+            QObject::tr("IMPORT_MED_ERROR"),
+//            "Import MED file error",
+            QObject::tr("INVALID_MED_FILE"));
+//          "Invalid MED file (not recognized by MULTIPR)");
+    }
+    QApplication::restoreOverrideCursor();
+
+    //if (mMULTIPRObj != NULL)
+    if (!CORBA::is_nil(mMULTIPRObj))
+    {
+        SALOMEDS::SObject_ptr aSObject = SALOMEDS::SObject::_nil();
+        SalomeApp_Study* aSAStudy = dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
+        _PTR(Study) aStudyDSClient = aSAStudy->studyDS();
+        SALOMEDS::Study_ptr aStudyDS = _CAST(Study,aStudyDSClient)->GetStudy();
+        multiprgen->PublishInStudy(aStudyDS, aSObject, mMULTIPRObj, "Mesh");
+
+        try
+        {
+            if (mMULTIPRObj->isValidSequentialMEDFile())
+            {
+                OnPartition1();
+            }
+        }
+        catch (...)
+        {
+        }
+
+        getApp()->updateObjectBrowser();
+        getApp()->updateActions();
+    }
 }
 
 
 void MULTIPR_GUI::OnPartition1()
 {
-       // check if MULTIPRObj exists
-       if (mMULTIPRObj == NULL)
-       {
-               return;
-       }
-       
-       MULTIPR_GUI_Partition1Dlg* dialog = new MULTIPR_GUI_Partition1Dlg(this);
-       dialog->exec();
-       delete dialog;
+    // check if MULTIPRObj exists
+    //if (mMULTIPRObj == NULL)
+    if (CORBA::is_nil(mMULTIPRObj))
+    {
+        return;
+    }
+
+    // do the partition.
+    MULTIPR_GUI_Partition1Dlg* dialog = new MULTIPR_GUI_Partition1Dlg(this);
+    dialog->exec();
+    delete dialog;
+
+    // Now we need to save the file.
+    SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg(
+        (QWidget*) MULTIPR_GUI::desktop(),
+        true,
+        tr("") );
+
+    fd->setWindowTitle(tr("Save distributed MED file - Destination directory"));
+    fd->setFileMode(QFileDialog::DirectoryOnly);
+
+    if (fd->exec() == QDialog::Rejected)
+    {
+        delete fd;
+        mMULTIPRObj->reset();
+        getApp()->updateObjectBrowser();
+        return;
+    }
+
+    QFileInfo aFileInfo(fd->selectedFile());
+    delete fd;
+
+    QString path = aFileInfo.filePath();
+
+    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+    mMULTIPRObj->resetSaveProgress();
+
+    MULTIPR_GUI_SaveThread* a = new MULTIPR_GUI_SaveThread (this, mMULTIPRObj, path);
+    a->start();
+
+    // save progress
+    //mProgress = new MULTIPR_GUI_ProgressCallbackDlg (getApp()->desktop());
+    //mProgress->start("Save mesh", 100);
+    if (mProgress == NULL)
+        mProgress = new QProgressDialog ("Save mesh", "Cancel", 0,/*totalSteps*/100, (QWidget*) MULTIPR_GUI::desktop());
+    //mProgress->setProgress(0);
+    //mProgress->init(100);
+    //mTimer->start(500); // 0.5 seconds timer
+    //QApplication::restoreOverrideCursor();
+    //getApp()->updateObjectBrowser();
+
 }
 
 
 void MULTIPR_GUI::OnPartition2()
 {
-       // check if MULTIPRObj exists
-       if (mMULTIPRObj == NULL)
-       {
-               return;
-       }
-       
-       retrieveSelectedParts();
-       
-       if (mSelectedParts.count() == 0)
-       {
-               SUIT_MessageBox::warn1( 
-                       getApp()->desktop(),
-                       "Split warning", 
-                       "No parts selected", 
-                       tr("OK") );
-               return;
-       }
-       
-       if (!removeLowerResolution())
-       {
-               return;
-       }
-       
-       MULTIPR_GUI_Partition2Dlg* dialog = new MULTIPR_GUI_Partition2Dlg(this);
-       dialog->exec();
-       delete dialog;
-       getApp()->updateObjectBrowser();
+    // check if MULTIPRObj exists
+    //if (mMULTIPRObj == NULL)
+    if (CORBA::is_nil(mMULTIPRObj))
+    {
+        return;
+    }
+
+    retrieveSelectedParts();
+
+    if (mSelectedParts.count() == 0)
+    {
+        SUIT_MessageBox::warning(
+            (QWidget*) MULTIPR_GUI::desktop(),
+            QString("Split warning"),
+            QString("No parts selected"));
+        return;
+    }
+
+    if (!removeLowerResolution())
+    {
+        return;
+    }
+
+    MULTIPR_GUI_Partition2Dlg* dialog = new MULTIPR_GUI_Partition2Dlg(this);
+    dialog->exec();
+    delete dialog;
+    getApp()->updateObjectBrowser();
+    getApp()->updateActions();
 }
 
 
 void MULTIPR_GUI::OnDecimate()
 {
-       // check if MULTIPRObj exists
-       if (mMULTIPRObj == NULL)
-       {
-               return;
-       }
-       
-       retrieveSelectedParts();
-       
-       if (mSelectedParts.count() == 0)
-       {
-               SUIT_MessageBox::warn1( 
-                       getApp()->desktop(),
-                       "Decimation warning", 
-                       "No parts selected", 
-                       tr("OK") );
-               return;
-       }
-       
-       if (!removeLowerResolution())
-       {
-               return;
-       }
-       
-       MULTIPR_GUI_DecimateDlg* dialog = new MULTIPR_GUI_DecimateDlg(this);
-       dialog->exec();
-       delete dialog;
-       getApp()->updateObjectBrowser();
+    // check if MULTIPRObj exists
+    //if (mMULTIPRObj == NULL)
+    if (CORBA::is_nil(mMULTIPRObj))
+    {
+        return;
+    }
+
+    retrieveSelectedParts();
+
+    if (mSelectedParts.count() == 0)
+    {
+        SUIT_MessageBox::warning(
+            (QWidget*) MULTIPR_GUI::desktop(),
+            QString("Decimation warning"),
+            QString("No parts selected"));
+        return;
+    }
+
+    if (!removeLowerResolution())
+    {
+        return;
+    }
+
+    const QStringList& partsList = this->getSelectedParts();
+    QString allParts = partsList.join("|");
+    MULTIPR_ORB::string_array* listFields = this->getMULTIPRObj()->getFields(allParts.toLatin1());
+    if (listFields->length() == 0)
+    {
+      SUIT_MessageBox::critical(
+            (QWidget*) MULTIPR_GUI::desktop(),
+            QObject::tr("DECIM_ERROR"),
+//            "Decimation error",
+            QObject::tr("NO_FIELD_ON_PART"));
+//          "No field for this part.",);
+      return ;
+    }
+
+    MULTIPR_GUI_DecimateDlg* dialog = new MULTIPR_GUI_DecimateDlg(this);
+    dialog->exec();
+    delete dialog;
+    getApp()->updateObjectBrowser();
+    getApp()->updateActions();
 }
 
 
 void MULTIPR_GUI::OnRemove()
 {
-       // check if MULTIPRObj exists
-       if (mMULTIPRObj == NULL)
-       {
-               return;
-       }
-       
-       retrieveSelectedParts();
-       
-       if (mSelectedParts.count() == 0)
-       {
-               SUIT_MessageBox::warn1( 
-                       getApp()->desktop(),
-                       "Remove warning", 
-                       "No parts selected", 
-                       tr("OK") );
-               return;
-       }
-       
-       if (QMessageBox::question(
-            getApp()->desktop(),
-            tr("Remove selected part(s)"),
-            tr("Do you want to remove selected part(s)?"),
-            tr("&Yes"), tr("&No"),
+    // check if MULTIPRObj exists
+    //if (mMULTIPRObj == NULL)
+    if (CORBA::is_nil(mMULTIPRObj))
+    {
+        return;
+    }
+
+    retrieveSelectedParts();
+
+    if (mSelectedParts.count() == 0)
+    {
+        SUIT_MessageBox::warning(
+            (QWidget*) MULTIPR_GUI::desktop(),
+            QString("Remove warning"),
+            QString("No parts selected"));
+        return;
+    }
+
+    if (QMessageBox::question(
+            (QWidget*) MULTIPR_GUI::desktop(),
+            QString("Remove selected part(s)"),
+            QString("Do you want to remove selected part(s)?"),
+            QString("&Yes"), QString("&No"),
             QString::null, 0, 1 ) )
-       {
-               return;
-       }
-
-       QApplication::setOverrideCursor(Qt::waitCursor);
-       
-       try
-       {
-               for (QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end(); it != last; it++)
-               {
-                       const QString& partName = (*it);
-                       cout << "Remove " << partName.latin1() << endl;
-                       mMULTIPRObj->removeParts(partName.latin1());
-               }
-               
-       }
-       catch(...)
-       {
-               SUIT_MessageBox::error1( 
-                       getApp()->desktop(),
-                       "Remove error", 
-                       "Error while removing selected part(s)", 
-                       tr("OK") );
-       }
-       
-       QApplication::restoreOverrideCursor();
-       
-       getApp()->updateObjectBrowser();
+    {
+        return;
+    }
+
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+
+    try
+    {
+      QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end();
+      for (; it != last; it++)
+      {
+        const QString& partName = (*it);
+        cout << "Remove " << (const char*)partName.toLatin1() << endl;
+        mMULTIPRObj->removeParts(partName.toLatin1());
+      }
+    }
+    catch(...)
+    {
+        SUIT_MessageBox::critical(
+            (QWidget*) MULTIPR_GUI::desktop(),
+            QString("Remove error"),
+            QString("Error while removing selected part(s)"));
+    }
+
+    QApplication::restoreOverrideCursor();
+
+    getApp()->updateObjectBrowser();
+    getApp()->updateActions();
 }
 
 
 void MULTIPR_GUI::OnSave()
 {
-       // check if MULTIPRObj exists
-       if (mMULTIPRObj == NULL)
-       {
-               return;
-       }
-
-       QApplication::setOverrideCursor(Qt::waitCursor);
-       
-       try
-       {
-               mMULTIPRObj->save();
-               getApp()->updateObjectBrowser();
-       }
-       catch(...)
-       {
-               SUIT_MessageBox::error1( 
-                       getApp()->desktop(),
-                       "Save distributed MED file error", 
-                       "Error while writing distributed MED file", 
-                       tr("OK") );
-       }
-       
-       QApplication::restoreOverrideCursor();
+  // check if MULTIPRObj exists
+  //if (mMULTIPRObj == NULL)
+  if (CORBA::is_nil(mMULTIPRObj))
+  {
+    return;
+  }
+
+    SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( (QWidget*) MULTIPR_GUI::desktop(), true,tr(""));
+
+  fd->setWindowTitle(tr("Save distributed MED file - Destination directory"));
+  fd->setFileMode(QFileDialog::DirectoryOnly);
+
+  if (fd->exec() == QDialog::Rejected)
+  {
+    delete fd;
+    return;
+  }
+
+  QFileInfo aFileInfo(fd->selectedFile());
+  delete fd;
+
+  QApplication::setOverrideCursor(Qt::WaitCursor);
+
+  QString path = aFileInfo.filePath();
+  mMULTIPRObj->resetSaveProgress();
+
+  MULTIPR_GUI_SaveThread* a = new MULTIPR_GUI_SaveThread (this, mMULTIPRObj, path);
+  a->start();
+
+  // save progress
+  //mProgress = new MULTIPR_GUI_ProgressCallbackDlg (getApp()->desktop());
+  //mProgress->start("Save mesh", 100);
+  if (mProgress == NULL)
+    mProgress = new QProgressDialog ("Save mesh", "Cancel", 0,/*totalSteps*/100, (QWidget*) MULTIPR_GUI::desktop());
+  //mProgress->setProgress(0);
+  //mProgress->init(100);
+  mTimer->start(500); // 0.5 seconds timer
+
+  //QApplication::restoreOverrideCursor();
 }
 
+void MULTIPR_GUI::timerDone()
+{
+  int progress = mMULTIPRObj->getSaveProgress();
+  if (mProgress != NULL) {
+    mProgress->setValue(progress);
 
+    if (progress >= 100) {
+      mTimer->stop();
+    }
+  }
+}
 
 void MULTIPR_GUI::retrieveSelectedParts()
 {
-       mSelectedParts.clear();
-
-       QStringList userSelection;      
-       selected(userSelection, true);
-       for (QStringList::const_iterator it = userSelection.begin(), last = userSelection.end(); it != last; it++)
-       {
-               const QString& str = (*it);
-               QStringList words = QStringList::split(":", str);
-               if (words.count() == 2)
-               {
-                       if (words[0] == "MULTIPR_PART")
-                       {
-                               mSelectedParts.push_back(words[1]);
-                       }
-               }
+    mSelectedParts.clear();
+
+    QStringList userSelection;
+    selected(userSelection, true);
+    for (QStringList::const_iterator it = userSelection.begin(), last = userSelection.end(); it != last; it++)
+    {
+        const QString& str = (*it);
+        QStringList words = str.split(":");
+        if (words.count() == 2)
+        {
+            if (words[0] == "MULTIPR_PART")
+            {
+                mSelectedParts.push_back(words[1]);
+            }
+        }
     }
 }
 
 
 bool MULTIPR_GUI::isPartExist(const char* partName)
 {
-       if (mMULTIPRObj == NULL) return false;
-       
-       MULTIPR_ORB::string_array* listParts = mMULTIPRObj->getParts();
-       for (int i=0 ; i<listParts->length() ; i++)
-       {
-               const char* strItem = (*listParts)[i];
-               if (strcmp(strItem, partName) == 0) 
-               {
-                       return true;
-               }
-       }
-       return false;
+  //if (mMULTIPRObj == NULL) return false;
+    if (CORBA::is_nil(mMULTIPRObj)) return false;
+
+    MULTIPR_ORB::string_array* listParts = mMULTIPRObj->getParts();
+    for (int i=0 ; i<listParts->length() ; i++)
+    {
+        const char* strItem = (*listParts)[i];
+        if (strcmp(strItem, partName) == 0)
+        {
+            return true;
+        }
+    }
+    return false;
 }
 
 
 bool MULTIPR_GUI::removeLowerResolution()
 {
-       // for each selected part, check if there are lower resolution
-       // and then propose to remove them before performing new process
-       QStringList partNameLowerResolution;
-       for (QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end(); it != last; it++)
-       {
-               const QString& partName = (*it);
-               QString partNameLow = partName + "_LOW";
-               QString partNameMed = partName + "_MED";
-               const char* strPartNameLow = partNameLow.latin1();
-               const char* strPartNameMed = partNameMed.latin1();
-               
-               if (isPartExist(strPartNameLow))
-               {
-                       partNameLowerResolution.push_back(partNameLow);
-                       cout << "Part to be removed: " << partNameLow << endl;
-               }
-               
-               if (isPartExist(strPartNameMed))
-               {
-                       partNameLowerResolution.push_back(partNameMed);
-                       cout << "Part to be removed: " << partNameMed << endl;
-               }
-       }
-        
-       if (partNameLowerResolution.count() > 0)
-       {
-               if (QMessageBox::question(
-                               getApp()->desktop(),
-                               tr("Remove previous results"),
-                               tr("Do you want to remove previous results?"),
-                               tr("&Yes"), tr("&No"),
-                               QString::null, 0, 1 ) )
-               {
-                       return false;
-               }
-       
-               QApplication::setOverrideCursor(Qt::waitCursor);
-               
-               try
-               {
-                       for (QStringList::const_iterator it = partNameLowerResolution.begin(), last = partNameLowerResolution.end(); it != last; it++)
-                       {
-                               const QString& partName = (*it);
-                               cout << "Remove " << partName.latin1() << endl;
-                               mMULTIPRObj->removeParts(partName.latin1());
-                       }
-                       
-               }
-               catch(...)
-               {
-                       SUIT_MessageBox::error1( 
-                               getApp()->desktop(),
-                               "Remove error", 
-                               "Error while removing previous results", 
-                               tr("OK") );
-               }
-               
-               QApplication::restoreOverrideCursor();
-               
-               getApp()->updateObjectBrowser();
-       }
-       
-       return true;
+    // for each selected part, check if there are lower resolution
+    // and then propose to remove them before performing new process
+    QStringList partNameLowerResolution;
+    for (QStringList::const_iterator it = mSelectedParts.begin(), last = mSelectedParts.end();
+         it != last; it++)
+    {
+        const QString& partName = (*it);
+        QString partNameLow = partName + "_LOW";
+        QString partNameMed = partName + "_MED";
+        const char* strPartNameLow = partNameLow.toLatin1();
+        const char* strPartNameMed = partNameMed.toLatin1();
+
+        if (isPartExist(strPartNameLow))
+        {
+            partNameLowerResolution.push_back(partNameLow);
+            cout << "Part to be removed: " << strPartNameLow << endl;
+        }
+
+        if (isPartExist(strPartNameMed))
+        {
+            partNameLowerResolution.push_back(partNameMed);
+            cout << "Part to be removed: " << strPartNameMed << endl;
+        }
+    }
+
+    if (partNameLowerResolution.count() > 0)
+    {
+        if (QMessageBox::question(
+                (QWidget*) MULTIPR_GUI::desktop(),
+                QObject::tr("DEL_PREV_RESULTS"),
+//                tr("Remove previous results"),
+                QObject::tr("DEL_PREV_RESULTS_QUEST"),
+//                tr("Do you want to remove previous results?"),
+                tr("&Yes"), tr("&No"),
+                QString::null, 0, 1 ) )
+        {
+            return false;
+        }
+
+        QApplication::setOverrideCursor(Qt::WaitCursor);
+
+        try
+        {
+            for (QStringList::const_iterator it = partNameLowerResolution.begin(),
+                   last = partNameLowerResolution.end(); it != last; it++)
+            {
+                const QString& partName = (*it);
+                cout << "Remove " << (const char*)partName.toLatin1() << endl;
+                mMULTIPRObj->removeParts(partName.toLatin1());
+            }
+        }
+        catch(...)
+        {
+            SUIT_MessageBox::critical(
+                (QWidget*) MULTIPR_GUI::desktop(),
+                QObject::tr("DEL_ERROR"),
+//                "Remove error",
+                QObject::tr("ERROR_DEL_PREV_RESULT"));
+//                "Error while removing previous results",
+        }
+
+        QApplication::restoreOverrideCursor();
+
+        getApp()->updateObjectBrowser();
+        getApp()->updateActions();
+    }
+
+    return true;
+}
+
+SUIT_Desktop*  MULTIPR_GUI::desktop()
+{
+  SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+  if( app )
+    return app->desktop();
+  else
+    return 0;
 }
 
 
@@ -624,23 +911,23 @@ bool MULTIPR_GUI::removeLowerResolution()
 // Super class Data Object implementation
 //*****************************************************************************
 
-MULTIPR_GUI_DataObject::MULTIPR_GUI_DataObject(SUIT_DataObject* parent, const char* name) : 
-       LightApp_DataObject(parent),
-       CAM_DataObject(parent)
+MULTIPR_GUI_DataObject::MULTIPR_GUI_DataObject (SUIT_DataObject* parent, const char* name)
+  : LightApp_DataObject(parent),
+    CAM_DataObject(parent)
 {
-       mName = name;
+    mName = name;
 }
 
 
 MULTIPR_GUI_DataObject::~MULTIPR_GUI_DataObject()
 {
-       // do nothing!
+    // do nothing!
 }
 
 
 QString MULTIPR_GUI_DataObject::entry() const
 {
-       return QString("MULTIPR_OBJECT");
+    return QString("MULTIPR_OBJECT");
 }
 
 
@@ -652,16 +939,16 @@ QString MULTIPR_GUI_DataObject::name() const
 
 QPixmap MULTIPR_GUI_DataObject::icon() const
 {
-       //static QPixmap icon = SUIT_Session::session()->resourceMgr()->loadPixmap("MULTIPR", QObject::tr("ICON_IMPORT_MED"), false);
-       return QPixmap();
-       
+    //static QPixmap icon = SUIT_Session::session()->resourceMgr()->loadPixmap("MULTIPR", QObject::tr("ICON_IMPORT_MED"), false);
+    return QPixmap();
+
 }
 
 
 QString MULTIPR_GUI_DataObject::toolTip() const
 {
-       // default behaviour: return an empty string
-       return "";
+    // default behaviour: return an empty string
+    return "";
 }
 
 
@@ -669,42 +956,48 @@ QString MULTIPR_GUI_DataObject::toolTip() const
 // Class Data Object Module implementation
 //*****************************************************************************
 
-MULTIPR_GUI_DataObject_Module::MULTIPR_GUI_DataObject_Module(CAM_DataModel* dm, SUIT_DataObject* parent, const char* name) : 
-       MULTIPR_GUI_DataObject(parent, name),
-       LightApp_ModuleObject(dm, parent),
-       CAM_DataObject(parent)
+
+MULTIPR_GUI_DataObject_Module::MULTIPR_GUI_DataObject_Module (CAM_DataModel* dm,
+                                                              SUIT_DataObject* parent,
+                                                              const char* name)
+  : MULTIPR_GUI_DataObject(parent, name),
+//    LightApp_DataObject(dm, parent),
+    CAM_DataObject(parent)
 {
-       // do nothing!
+    // do nothing!
+    mDm = dm;
+    mParent = parent;
 }
 
 
 MULTIPR_GUI_DataObject_Module::~MULTIPR_GUI_DataObject_Module()
 {
-       // do nothing!
+    // do nothing!
 }
 
 
 QString MULTIPR_GUI_DataObject_Module::entry() const
 {
-       return QString("MULTIPR_MODULE:" + mName);
+    return QString("MULTIPR_MODULE:" + mName);
 }
 
 
 QString MULTIPR_GUI_DataObject_Module::name() const
 {
-  return CAM_RootObject::name();
+  CAM_ModuleObject cam(mDm,mParent);
+  return cam.name();
 }
 
 
 QPixmap MULTIPR_GUI_DataObject_Module::icon() const
 {
-       return QPixmap();
+    return QPixmap();
 }
 
 
 QString MULTIPR_GUI_DataObject_Module::toolTip() const
 {
-       return QString("Module MULTIPR");
+    return QString("Module MULTIPR");
 }
 
 
@@ -712,35 +1005,35 @@ QString MULTIPR_GUI_DataObject_Module::toolTip() const
 // Class Data Object Mesh implementation
 //*****************************************************************************
 
-MULTIPR_GUI_DataObject_Mesh::MULTIPR_GUI_DataObject_Mesh(SUIT_DataObject* parent, const char* name) : 
-       MULTIPR_GUI_DataObject(parent, name),
-       CAM_DataObject(parent)
+MULTIPR_GUI_DataObject_Mesh::MULTIPR_GUI_DataObject_Mesh (SUIT_DataObject* parent, const char* name)
+  : MULTIPR_GUI_DataObject(parent, name),
+    CAM_DataObject(parent)
 {
-       // do nothing!
+    // do nothing!
 }
 
 
 MULTIPR_GUI_DataObject_Mesh::~MULTIPR_GUI_DataObject_Mesh()
 {
-       // do nothing!
+    // do nothing!
 }
 
 
 QString MULTIPR_GUI_DataObject_Mesh::entry() const
 {
-       return QString("MULTIPR_MESH:") + mName;
+    return QString("MULTIPR_MESH:") + mName;
 }
 
 
 QPixmap MULTIPR_GUI_DataObject_Mesh::icon() const
 {
-       return QPixmap();
+    return QPixmap();
 }
 
 
 QString MULTIPR_GUI_DataObject_Mesh::toolTip() const
 {
-       return QString("Original mesh");
+    return QString("Original mesh");
 }
 
 
@@ -748,62 +1041,63 @@ QString MULTIPR_GUI_DataObject_Mesh::toolTip() const
 // Class Data Object Part implementation
 //*****************************************************************************
 
-MULTIPR_GUI_DataObject_Part::MULTIPR_GUI_DataObject_Part(SUIT_DataObject* parent, const char* name, const char* info) : 
-       MULTIPR_GUI_DataObject(parent, name),
-       CAM_DataObject(parent)
-{
-       mMeshName    = "";
-       mId          = 0;
-       mPath        = "";
-       mMEDFileName = "";
-       
-       mTooltip = info;
-       
-       // parse info to retrieve all the fields
-       char   lMeshName[256];
-       int    lId;
-       char   lPartName[256];
-       char   lPath[256];
-       char   lMEDFileName[256];
-       
-       int ret = sscanf(info, "%s %d %s %s %s", 
-                               lMeshName,
-                               &lId,
-                               lPartName,
-                               lPath,
-                               lMEDFileName);
-                               
-       // number of read parameters should be 5
-       if (ret != 5) return;
-       
-       mMeshName    = lMeshName;
-       mId          = lId;
-       mPath        = lPath;
-       mMEDFileName = lMEDFileName;
+MULTIPR_GUI_DataObject_Part::MULTIPR_GUI_DataObject_Part (SUIT_DataObject* parent,
+                                                          const char* name, const char* info)
+  : MULTIPR_GUI_DataObject(parent, name),
+    CAM_DataObject(parent)
+{
+    mMeshName    = "";
+    mId          = 0;
+    mPath        = "";
+    mMEDFileName = "";
+
+    mTooltip = info;
+
+    // parse info to retrieve all the fields
+    char   lMeshName[256];
+    int    lId;
+    char   lPartName[256];
+    char   lPath[256];
+    char   lMEDFileName[256];
+
+    int ret = sscanf(info, "%s %d %s %s %s",
+                lMeshName,
+                &lId,
+                lPartName,
+                lPath,
+                lMEDFileName);
+
+    // number of read parameters should be 5
+    if (ret != 5) return;
+
+    mMeshName    = lMeshName;
+    mId          = lId;
+    mPath        = lPath;
+    mMEDFileName = lMEDFileName;
 }
 
 
 MULTIPR_GUI_DataObject_Part::~MULTIPR_GUI_DataObject_Part()
 {
-       // do nothing!
+    // do nothing!
 }
 
 
 QString MULTIPR_GUI_DataObject_Part::entry() const
 {
-       return QString("MULTIPR_PART:") + mName;
+    return QString("MULTIPR_PART:") + mName;
 }
 
 
 QPixmap MULTIPR_GUI_DataObject_Part::icon() const
 {
-       return QPixmap();
+    return QPixmap();
 }
 
 
 QString MULTIPR_GUI_DataObject_Part::toolTip() const
 {
-       return mTooltip;
+    return mTooltip;
 }
 
 
@@ -811,35 +1105,36 @@ QString MULTIPR_GUI_DataObject_Part::toolTip() const
 // Class Data Object Resolution implementation
 //*****************************************************************************
 
-MULTIPR_GUI_DataObject_Resolution::MULTIPR_GUI_DataObject_Resolution(SUIT_DataObject* parent, const char* name, const char* info) : 
-       MULTIPR_GUI_DataObject_Part(parent, name, info),
-       CAM_DataObject(parent)
+MULTIPR_GUI_DataObject_Resolution::MULTIPR_GUI_DataObject_Resolution (SUIT_DataObject* parent,
+                                                                      const char* name, const char* info)
+  : MULTIPR_GUI_DataObject_Part(parent, name, info),
+    CAM_DataObject(parent)
 {
-       // do nothing!
+    // do nothing!
 }
 
 
 MULTIPR_GUI_DataObject_Resolution::~MULTIPR_GUI_DataObject_Resolution()
 {
-       // do nothing!
+    // do nothing!
 }
 
 
 QString MULTIPR_GUI_DataObject_Resolution::entry() const
 {
-       return QString("MULTIPR_RESOLUTION:") + mName;
+    return QString("MULTIPR_RESOLUTION:") + mName;
 }
 
 
 QPixmap MULTIPR_GUI_DataObject_Resolution::icon() const
 {
-       return QPixmap();
+    return QPixmap();
 }
 
 
 QString MULTIPR_GUI_DataObject_Resolution::toolTip() const
 {
-       return mTooltip;
+    return mTooltip;
 }
 
 
@@ -847,104 +1142,212 @@ QString MULTIPR_GUI_DataObject_Resolution::toolTip() const
 // Data Model
 //*****************************************************************************
 
-MULTIPR_GUI_DataModel::MULTIPR_GUI_DataModel(CAM_Module* module) : 
-       LightApp_DataModel(module)
+MULTIPR_GUI_DataModel::MULTIPR_GUI_DataModel(CAM_Module* module)
+// : LightApp_DataModel(module)
+  : SalomeApp_DataModel(module)
 {
-       mMULTIPR_GUI = dynamic_cast<MULTIPR_GUI*>(module);
+    mMULTIPR_GUI = dynamic_cast<MULTIPR_GUI*>(module);
 }
 
-
 MULTIPR_GUI_DataModel::~MULTIPR_GUI_DataModel()
 {
-       // do nothing!
+    // do nothing!
 }
 
+void MULTIPR_GUI_DataModel::update (LightApp_DataObject*, LightApp_Study* theStudy)
+{
+  LightApp_ModuleObject* modelRoot = dynamic_cast<LightApp_ModuleObject*>( root() );
+  DataObjectList ch;
+  //QListIterator<SUIT_DataObject> it1,it2;
+  QMap<SUIT_DataObject*,int> aMap;
+  if( modelRoot )
+  {
+    ch = modelRoot->children();
+    DataObjectList::const_iterator it = ch.begin(), it_last = ch.end();
+    for (; it != it_last; it++)
+        (*it)->setParent( 0);
+  }
+
+  buildAll(theStudy);
+
+  modelRoot = dynamic_cast<LightApp_ModuleObject*>( root() );
+  if( modelRoot )
+  {
+    DataObjectList new_ch = modelRoot->children();
+    DataObjectList::const_iterator it1 = new_ch.begin(), it1_last = new_ch.end();
+    for (; it1 != it1_last; it1++)
+      aMap.insert((*it1),0);
+  }
+
+  updateWidgets();
+  DataObjectList::const_iterator it_del = ch.begin(), it_del_last = ch.end();
+  for (; it_del != it_del_last; it_del++)
+    if( !aMap.contains( (*it_del) ) )
+      delete (*it_del);
+}
 
 void MULTIPR_GUI_DataModel::build()
 {
-       try
-       {
-               MULTIPR_GUI_DataObject_Module* modelRoot = dynamic_cast<MULTIPR_GUI_DataObject_Module*>(root());
-               
-               if (!modelRoot)  
-               {  
-                       // root is not set yet
-                       modelRoot = new MULTIPR_GUI_DataObject_Module(this, NULL, "MULTIPR");
-                       setRoot(modelRoot);
-               }
-               
-               MULTIPR_ORB::MULTIPR_Obj_ptr obj = mMULTIPR_GUI->getMULTIPRObj();
-               
-               if (obj != NULL)
-               {
-                       MULTIPR_ORB::string_array* listParts = obj->getParts();
-                       
-                       if (listParts->length() >= 1)
-                       {
-                               const char* strPartName0 = (*listParts)[0];
-                               char* strPartInfo0 = obj->getPartInfo(strPartName0);
-                               
-                               char   lMeshName[256];
-                               int    lId;
-                               char   lPartName[256];
-                               char   lPath[256];
-                               char   lMEDFileName[256];       
-                               
-                               // parse infos
-                               int ret = sscanf(strPartInfo0, "%s %d %s %s %s", 
-                                       lMeshName,
-                                       &lId,
-                                       lPartName,
-                                       lPath,
-                                       lMEDFileName);
-                                       
-                               if (ret != 5) return;
-                               
-                               MULTIPR_GUI_DataObject_Mesh* dataObjectMesh = new MULTIPR_GUI_DataObject_Mesh(modelRoot, lMeshName);
-                               
-                               MULTIPR_GUI_DataObject_Part* dataObjectPart_prev = NULL;
-                               
-                               for (int i = 0 ; i < listParts->length() ; i++)
-                               {
-                                       const char* strItem = (*listParts)[i];
-                                       char* strPartInfo = obj->getPartInfo(strItem);
-                                       
-                                       // parse infos
-                                       int ret = sscanf(strPartInfo, "%s %d %s %s %s", 
-                                               lMeshName,
-                                               &lId,
-                                               lPartName,
-                                               lPath,
-                                               lMEDFileName);
-                                       
-                                       if (ret != 5) return;
-                               
-                                       //cout << "Part : " << lPartName << endl;
-                                       if ((strstr(lPartName,"_MED") != NULL) || (strstr(lPartName,"_LOW") != NULL))
-                                       {
-                                               //cout << "Found MED/LOW" << endl;
-                                               new MULTIPR_GUI_DataObject_Resolution(dataObjectPart_prev, strItem, strPartInfo);
-                                       }
-                                       else
-                                       {
-                                               dataObjectPart_prev = new MULTIPR_GUI_DataObject_Part(dataObjectMesh, strItem, strPartInfo);
-                                       }
-                               }
-                       }
-               }
-       }
-       catch (...)
-       {
-       }
-}
-
-
-extern "C" 
-{
-       CAM_Module* createModule()
-       {
-               return new MULTIPR_GUI();
-       }
+}
+
+void MULTIPR_GUI_DataModel::buildAll (LightApp_Study* theStudy)
+{
+  try
+  {
+    SalomeApp_Study* aSAStudy = dynamic_cast<SalomeApp_Study*>(theStudy);
+    if (!aSAStudy)
+      aSAStudy = dynamic_cast<SalomeApp_Study*>(getModule()->getApp()->activeStudy());
+
+    if (!aSAStudy) return;
+
+    MULTIPR_GUI_DataObject_Module* modelRoot = dynamic_cast<MULTIPR_GUI_DataObject_Module*>(root());
+    if (!modelRoot)
+    {
+      // root is not set yet
+      modelRoot = new MULTIPR_GUI_DataObject_Module(this, NULL, "MULTIPR");
+      setRoot(modelRoot);
+    }
+
+    // find SObject in Study
+    MULTIPR_ORB::MULTIPR_Obj_ptr obj = MULTIPR_ORB::MULTIPR_Obj::_nil();
+
+    _PTR(SComponent) aSComp = aSAStudy->studyDS()->FindComponent(module()->name().toStdString());
+    if (aSComp)
+    {
+      _PTR(ChildIterator) it (aSAStudy->studyDS()->NewChildIterator(aSComp));
+      if (it->More())
+      {
+        _PTR(SObject) aSObj = it->Value();
+        string anIOR = aSObj->GetIOR();
+        if (!anIOR.empty())
+        {
+          CORBA::Object_var anObj = mMULTIPR_GUI->getApp()->orb()->string_to_object(anIOR.c_str());
+          obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
+
+          // set Object to MULTIPR_GUI
+          mMULTIPR_GUI->setMULTIPRObj(obj);
+        }
+        //CORBA::Object_var anObj = aSObj->GetObject();
+        //obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
+        //if (!CORBA::is_nil(obj))
+        //{
+        //  // set Object to MULTIPR_GUI
+        //  mMULTIPR_GUI->setMULTIPRObj(obj);
+        //}
+      }
+
+      // remove Data Objects, automatically built for not loaded MULTIPR module
+      // by SalomeApp_Application::updateObjectBrowser
+      if (aSAStudy->root())
+      {
+        DataObjectList ch_comp;
+        aSAStudy->root()->children(ch_comp);
+        DataObjectList::const_iterator anIt_comp = ch_comp.begin(), aLast_comp = ch_comp.end();
+        for (; anIt_comp != aLast_comp; anIt_comp++)
+        {
+          LightApp_DataObject* dobj = dynamic_cast<LightApp_DataObject*>(*anIt_comp);
+          if (dobj && dobj->name() == aSComp->GetName().c_str())
+          {
+            //SalomeApp_DataModelSync sync (aSAStudy->studyDS(), aSAStudy->root());
+            //sync.deleteItemWithChildren(dobj);
+            DataObjectList ch_obj;
+            dobj->children(ch_obj);
+            DataObjectList::const_iterator anIt_obj = ch_obj.begin(), aLast_obj = ch_obj.end();
+            for (; anIt_obj != aLast_obj; anIt_obj++)
+              // delete data object of each SObject
+              delete (*anIt_obj);
+
+            // delete data object of SComponent itself
+            delete dobj;
+            break;
+          }
+        }
+      }
+    }
+
+    // build data tree
+    if (!CORBA::is_nil(obj))
+    {
+      // MED file object
+      std::string lMEDFile = obj->getFilename();
+      std::string lMEDFileName = multipr::getFilenameWithoutPath(lMEDFile.c_str());
+      MULTIPR_GUI_DataObject_Mesh* dataObjectMED =
+        new MULTIPR_GUI_DataObject_Mesh(modelRoot, lMEDFileName.c_str());
+
+      // MESH object
+      MULTIPR_ORB::string_array* listParts = obj->getParts();
+
+      if (listParts->length() >= 1)
+      {
+        const char* strPartName0 = (*listParts)[0];
+        char* strPartInfo0 = obj->getPartInfo(strPartName0);
+
+        char   lMeshName[256];
+        int    lId;
+        char   lPartName[256];
+        char   lPath[256];
+        char   lMEDFileName[256];
+
+        // parse infos
+        int ret = sscanf(strPartInfo0, "%s %d %s %s %s",
+                         lMeshName,
+                         &lId,
+                         lPartName,
+                         lPath,
+                         lMEDFileName);
+
+        if (ret != 5)
+        {
+          cout << "MULTIPR: build() tree; error while parsing part info" << endl;
+          std::runtime_error("MULTIPR: build() tree; error while parsing part info");
+          return;
+        }
+
+        MULTIPR_GUI_DataObject_Mesh* dataObjectMesh =
+          new MULTIPR_GUI_DataObject_Mesh(dataObjectMED, lMeshName);
+
+        // PART and RESOLUTION objects
+        MULTIPR_GUI_DataObject_Part* dataObjectPart_prev = NULL;
+
+        for (int i = 0 ; i < listParts->length() ; i++)
+        {
+          const char* strItem = (*listParts)[i];
+          char* strPartInfo = obj->getPartInfo(strItem);
+
+          // parse infos
+          int ret = sscanf(strPartInfo, "%s %d %s %s %s",
+                           lMeshName,
+                           &lId,
+                           lPartName,
+                           lPath,
+                           lMEDFileName);
+
+          if (ret != 5) return;
+
+          if ((strstr(lPartName,"_MED") != NULL) || (strstr(lPartName,"_LOW") != NULL))
+          {
+            new MULTIPR_GUI_DataObject_Resolution(dataObjectPart_prev, strItem, strPartInfo);
+          }
+          else
+          {
+            dataObjectPart_prev = new MULTIPR_GUI_DataObject_Part(dataObjectMesh, strItem, strPartInfo);
+          }
+        }
+      }
+    }
+  }
+  catch (...)
+  {
+  }
+}
+
+
+extern "C"
+{
+    CAM_Module* createModule()
+    {
+        return new MULTIPR_GUI();
+    }
 }