]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
ADD: packages GuiHelpers (general gui services for "end developpers") and TreeData...
authorboulant <boulant>
Wed, 2 Nov 2011 12:31:14 +0000 (12:31 +0000)
committerboulant <boulant>
Wed, 2 Nov 2011 12:31:14 +0000 (12:31 +0000)
29 files changed:
configure.ac
src/GuiHelpers/Makefile.am [new file with mode: 0644]
src/GuiHelpers/QtHelper.hxx [new file with mode: 0644]
src/GuiHelpers/SALOME_AppStudyEditor.cxx [new file with mode: 0644]
src/GuiHelpers/SALOME_AppStudyEditor.hxx [new file with mode: 0644]
src/GuiHelpers/SALOME_GuiServices.cxx [new file with mode: 0644]
src/GuiHelpers/SALOME_GuiServices.hxx [new file with mode: 0644]
src/GuiHelpers/StandardApp_Module.cxx [new file with mode: 0644]
src/GuiHelpers/StandardApp_Module.hxx [new file with mode: 0644]
src/Makefile.am
src/TreeData/DataModel.cxx [new file with mode: 0644]
src/TreeData/DataModel.hxx [new file with mode: 0644]
src/TreeData/DataObject.cxx [new file with mode: 0644]
src/TreeData/DataObject.hxx [new file with mode: 0644]
src/TreeData/DataProcessor.cxx [new file with mode: 0644]
src/TreeData/DataProcessor.hxx [new file with mode: 0644]
src/TreeData/DockWidgets.cxx [new file with mode: 0644]
src/TreeData/DockWidgets.hxx [new file with mode: 0644]
src/TreeData/Makefile.am [new file with mode: 0644]
src/TreeData/TreeGuiManager.cxx [new file with mode: 0644]
src/TreeData/TreeGuiManager.hxx [new file with mode: 0644]
src/TreeData/TreeItem.cxx [new file with mode: 0644]
src/TreeData/TreeItem.hxx [new file with mode: 0644]
src/TreeData/TreeModel.cxx [new file with mode: 0644]
src/TreeData/TreeModel.hxx [new file with mode: 0644]
src/TreeData/TreeObserver.cxx [new file with mode: 0644]
src/TreeData/TreeObserver.hxx [new file with mode: 0644]
src/TreeData/TreeView.cxx [new file with mode: 0644]
src/TreeData/TreeView.hxx [new file with mode: 0644]

index af9bf5351fb4f82764d6b8d518c5968bfc92db98..c2ad5d5e1ddafdbe704d17236da9da080dd5aac4 100644 (file)
@@ -660,6 +660,8 @@ AC_OUTPUT([ \
   src/Session/Makefile \
   src/SalomeApp/Makefile \
   src/SalomeApp/Test/Makefile \
+  src/GuiHelpers/Makefile \
+  src/TreeData/Makefile \
   src/SALOME_SWIG/Makefile \
   src/SALOME_SWIG/supervisionexample.py \
   src/SALOME_SWIG/supervisiongeomexample.py \
diff --git a/src/GuiHelpers/Makefile.am b/src/GuiHelpers/Makefile.am
new file mode 100644 (file)
index 0000000..931d1a4
--- /dev/null
@@ -0,0 +1,81 @@
+#  Copyright (C) 2011  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+#  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
+#
+# -* Makefile *- 
+#
+# Author : Guillaume Boulant (EDF/R&D) 
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# header files 
+salomeinclude_HEADERS =        \
+       QtHelper.hxx           \
+       SALOME_GuiServices.hxx       \
+       SALOME_AppStudyEditor.hxx     \
+       StandardApp_Module.hxx
+
+# Libraries targets
+lib_LTLIBRARIES = libSalomeGuiHelpers.la
+
+dist_libSalomeGuiHelpers_la_SOURCES = \
+       SALOME_GuiServices.cxx         \
+       SALOME_AppStudyEditor.cxx       \
+       StandardApp_Module.cxx
+
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+CAS_CXXFLAGS=@CAS_CPPFLAGS@ @CAS_CXXFLAGS@
+BOOST_CPPFLAGS=@BOOST_CPPFLAGS@
+BOOST_LIBS=@BOOST_LIBS@
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+
+libSalomeGuiHelpers_la_CPPFLAGS =   \
+       $(QT_CXXFLAGS)              \
+       $(CAS_CXXFLAGS)             \
+       $(BOOST_CPPFLAGS)           \
+       $(CORBA_CXXFLAGS)           \
+       $(KERNEL_CXXFLAGS)          \
+       -I$(srcdir)/../SalomeApp    \
+       -I$(srcdir)/../LightApp     \
+       -I$(srcdir)/../SUIT         \
+       -I$(srcdir)/../Qtx          \
+       -I$(srcdir)/../CAM          \
+       -I$(srcdir)/../STD          \
+       -I$(srcdir)/../OBJECT
+
+libSalomeGuiHelpers_la_LDFLAGS  = \
+       $(KERNEL_LDFLAGS) -lSalomeKernelHelpers
+       $(builddir)/../SalomeApp/libSalomeApp.la
+
+#
+# =======================================================
+# Specific definitions for Qt MOC files
+#
+
+# moc-files generation
+%_moc.cxx: %.hxx
+       $(MOC) $< -o $@
+
+# MOC pre-processing
+MOC_FILES = \
+       StandardApp_Module_moc.cxx
+
+nodist_libSalomeGuiHelpers_la_SOURCES = $(MOC_FILES)
+
+EXTRA_DIST=$(MOC_FILES:%_moc.cxx=%.hxx)
diff --git a/src/GuiHelpers/QtHelper.hxx b/src/GuiHelpers/QtHelper.hxx
new file mode 100644 (file)
index 0000000..748c38b
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef _QT_HELPER_HXX_
+#define _QT_HELPER_HXX_
+
+//
+// =============================================================
+// Macro and template functions for type conversions.
+// =============================================================
+//
+#include "Basics_Utils.hxx" // To get ToString macro
+#include <QString>
+
+// This can be used to convert QString into char *.
+#define QCHARSTAR(qstring) qstring.toLatin1().data()
+// This converts a string into a QString
+#define S2QS(string) QString(string.c_str())
+// This converts a QString into a string
+#define QS2S(qstring) ToString(QCHARSTAR(qstring))
+#define QSTRING(any) S2QS(ToString(any))
+
+//
+// =============================================================
+// General helper macros for manipulating widgets values
+// =============================================================
+//
+#define GETTEXT(widget) ToString(QCHARSTAR(widget->text().trimmed()))
+#define SETTEXT(widget,str) widget->setText(str.c_str())
+
+//
+// =============================================================
+// Qt Logger macros
+// =============================================================
+//
+
+// We can use the macros defined by SALOMELocalTrace/utilities.h
+// as proposed in the file KERNEL_helper.hxx. But we can use instead
+// the Qt debug function:
+#include <QDebug>
+#define QDEBUG qWarning()
+//#define QDEBUG qDebug()
+#define QLOG(data) QDEBUG << "[XSALOME] " << data
+#ifdef LOG
+#undef LOG
+#endif
+#define LOG QLOG
+
+#endif // __QT_HELPER_H_
diff --git a/src/GuiHelpers/SALOME_AppStudyEditor.cxx b/src/GuiHelpers/SALOME_AppStudyEditor.cxx
new file mode 100644 (file)
index 0000000..0dbcc2a
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "SALOME_AppStudyEditor.hxx"
+
+#include <SalomeApp_Study.h>
+#include <SALOME_ListIO.hxx>
+#include <LightApp_SelectionMgr.h>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+SALOME_AppStudyEditor::SALOME_AppStudyEditor(SalomeApp_Application * salomeApp)
+  : SALOME_StudyEditor()
+{
+  _salomeApp = salomeApp;
+  updateActiveStudy();
+}
+
+/**
+ * This updates the editor with the current active study. If the
+ * active study id is identical to the study id currently associated
+ * to this object, then no update is performed.
+ */
+int SALOME_AppStudyEditor::updateActiveStudy() {
+  int activeStudyId = SALOME_AppStudyEditor::getActiveStudyId(_salomeApp);
+  if ( activeStudyId != this->getStudyId() ) {
+    this->setStudyById(activeStudyId);
+  }
+  return activeStudyId;
+}
+
+// GUI context only
+int SALOME_AppStudyEditor::getActiveStudyId(SalomeApp_Application * salomeApp) {
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*> (salomeApp->activeStudy());
+  _PTR(Study) aCStudy = appStudy->studyDS();
+  int studyId = aCStudy->StudyId();
+  return studyId;
+}
+
+SALOMEDS::SObject_ptr SALOME_AppStudyEditor::IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject) {
+  if (!iobject.IsNull()) {
+    if (iobject->hasEntry()) {
+      SALOMEDS::SObject_var sobject = _study->FindObjectID(iobject->getEntry());
+      return sobject._retn();
+    }
+  }
+  return SALOMEDS::SObject::_nil();
+}
+
+/**
+ * This function creates a list of all the "study objects" (SObject)
+ * that map with the selection in the object browser (the "interactive
+ * objects", IObjects). Please note that the objects belongs to the
+ * active study.
+ */
+SALOME_StudyEditor::SObjectList * SALOME_AppStudyEditor::getSelectedObjects() {
+
+  // _GBO_: please note that the use of this function can be
+  // underoptimal in the case where the number of selected objects is
+  // high, because we create a vector list of SObjects while the list
+  // of IObject can be processed directly. In the case where a high
+  // number of objects is selected (~1000), it's certainly better to
+  // use directly the SALOME_ListIO and iterators on it.
+
+  LightApp_SelectionMgr* aSelectionMgr = _salomeApp->selectionMgr();
+  SALOME_ListIO selectedIObjects;
+  aSelectionMgr->selectedObjects(selectedIObjects);
+  /* 
+   * This returns a list containing the selected objects of the objects
+   * browser. Please note that the objects of the browser ARE NOT the
+   * objects of the study. What is returned by this function is a list
+   * of "interactive objects" (IObject) which are objects of the
+   * graphical context. Each of this IObject is characterized by an
+   * entry string that corresponds to the entry string of an associated
+   * "study object" (SObject) in the active study. The mapping can be
+   * done using the function IObjectToSObject.
+   */
+
+  SObjectList * listOfSObject = new SObjectList();
+  SALOME_ListIteratorOfListIO It (selectedIObjects);
+  for (; It.More(); It.Next()) {
+    SALOMEDS::SObject_ptr sobject = this->IObjectToSObject(It.Value());
+    if (!sobject->_is_nil()) {
+      listOfSObject->push_back(sobject);
+    }
+  }
+
+  return listOfSObject;
+}
diff --git a/src/GuiHelpers/SALOME_AppStudyEditor.hxx b/src/GuiHelpers/SALOME_AppStudyEditor.hxx
new file mode 100644 (file)
index 0000000..bc12255
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef __APP_STUDY_EDITOR_HXX__
+#define __APP_STUDY_EDITOR_HXX__
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include <SalomeApp_Application.h>
+#include <SALOME_InteractiveObject.hxx>
+
+#include "SALOME_StudyEditor.hxx"
+
+class SALOME_AppStudyEditor: public SALOME_StudyEditor {
+public:
+  SALOME_AppStudyEditor(SalomeApp_Application * salomeApp);
+  int updateActiveStudy();
+  
+  SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject);
+  SALOME_StudyEditor::SObjectList * getSelectedObjects();
+
+  static int getActiveStudyId(SalomeApp_Application * salomeApp);
+
+private:
+  SalomeApp_Application * _salomeApp;
+
+};
+
+#endif // __APP_STUDY_EDITOR_HXX__
diff --git a/src/GuiHelpers/SALOME_GuiServices.cxx b/src/GuiHelpers/SALOME_GuiServices.cxx
new file mode 100644 (file)
index 0000000..0f31463
--- /dev/null
@@ -0,0 +1,134 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "SALOME_GuiServices.hxx"
+#include <SUIT_Session.h>
+
+namespace GUI {
+  /*!
+   * Get the SALOME application, i.e. the main GUI framework of
+   * SALOME. This function returns a pointer to the singleton instance
+   * of the SalomeApp_Application.
+   * 
+   * The SALOME application can be used to get reference to
+   * the SALOME KERNEL services such that the naming service, the
+   * lifeCycleCORBA, ... Theses services can be retrieved using static
+   * functions (not required to get the singleton instance):
+   *
+   *   SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
+   *
+   * Please note that this usage can be done only from within the
+   * SALOME session server process, i.e. the process that embed the
+   * SALOME application.
+   */
+  SalomeApp_Application * getSalomeApplication() {
+    static SalomeApp_Application * app;
+    if ( app == NULL ) {
+      app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+    }
+    return app;
+  }
+
+  /*!
+   * Get the selection manager of the SALOME application. The
+   * selection manager can be used to get the selected items in the
+   * objects browser that is a GUI display of the active study.
+   * The function returns a pointer to the selectionMgr attribute of
+   * the SalomeApp_Application singleton instance.
+   */
+  LightApp_SelectionMgr * getSelectionManager() {
+    SalomeApp_Application* anApp = GUI::getSalomeApplication();
+    if ( anApp == NULL ) return NULL;
+    return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
+  }
+
+
+  SUIT_ResourceMgr * getResourcesManager() {
+    return SUIT_Session::session()->resourceMgr();
+  }
+  // Note that the resource manager can be also retrieved from the
+  // SALOME application using the resourceMgr() method:
+  // 
+
+  /**
+   * This returns the current active study id if an active study is
+   * defined in the SALOME session, returns -1 otherwise. Note that
+   * the active study doesn't make sense outside of the GUI SALOME
+   * process, i.e. the SALOME_SessionServer embedding the
+   * SalomeApp_Application.
+   */
+  int getActiveStudyId() {
+    SALOME::Session_var aSession = KERNEL::getSalomeSession();
+    if ( CORBA::is_nil(aSession) ) {
+      INFOS("ERR: can't request for active study because the session is NULL");
+      return -1;
+    }
+    return aSession->GetActiveStudyId();
+  }
+
+  /**
+   * This returns the current active study if an active study is
+   * defined in the SALOME session, returns null otherwise.
+   */
+  SALOMEDS::Study_ptr getActiveStudy() {
+    return KERNEL::getStudyById(getActiveStudyId());
+  }
+
+
+  // __GBO__ Question: what is the difference between a
+  // SALOMEDS::Study and a SalomeApp_Study?
+  SalomeApp_Study* getSalomeAppActiveStudy() {
+    SUIT_Application* app = getSalomeApplication();
+    if( app )
+      return dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+    else
+      return NULL;
+  }
+
+
+  SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject) {
+    if (!iobject.IsNull()) {
+      if (iobject->hasEntry()) {
+        SalomeApp_Study* appStudy = getSalomeAppActiveStudy();
+        if ( appStudy != NULL ) {
+          //
+          // IMPORTANT NOTE:
+          //
+          // Note that the SalomeApp_Study give acces to shared
+          // pointer (i.e. _PTR(<BaseClassName>)) that points to proxy
+          // objects (i.e. SALOMEDSClien_<BaseClassName>) that embeds
+          // the CORBA servants (i.e. SALOMEDS::<BaseClassName>_ptr).
+          // Then to retrieve the corba servant, a method is to
+          // retrieve the SALOMEDS::Study servant first and the to
+          // request this servant to get the SObject given its entry.
+          //
+          _PTR(Study) studyClient = appStudy->studyDS();
+          SALOMEDS::Study_var study = KERNEL::getStudyManager()->GetStudyByID(studyClient->StudyId());
+          SALOMEDS::SObject_ptr sobject = study->FindObjectID(iobject->getEntry());
+          return sobject;
+        }
+      }
+    }
+    return SALOMEDS::SObject::_nil();
+  }
+
+}
+
diff --git a/src/GuiHelpers/SALOME_GuiServices.hxx b/src/GuiHelpers/SALOME_GuiServices.hxx
new file mode 100644 (file)
index 0000000..6188ad0
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef __GUI_SERVICES_H__
+#define __GUI_SERVICES_H__
+
+#include <SalomeApp_Application.h>
+#include <SalomeApp_Study.h>
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_ResourceMgr.h>
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOMEDS)
+#include <SALOME_InteractiveObject.hxx>
+#include <SALOME_KernelServices.hxx>
+
+namespace GUI {
+
+  // SALOME GUI main services
+  SalomeApp_Application * getSalomeApplication();
+  LightApp_SelectionMgr * getSelectionManager();
+  SUIT_ResourceMgr      * getResourcesManager();
+
+  // Helper functions to deal with the study in a GUI context.
+  //
+  // First of all, in a GUI context, there is one of the opened
+  // studies that is considered as active. Please note that the active
+  // study is a GUI concept and it can be obtained only in the
+  // SALOME_SessionServer process, i.e. the process that embeds the
+  // SalomeApp_Application. The concept of active study doesn't make
+  // sense outside of the GUI context.
+  //
+  // The active study is associated with an GUI Objects Browser that
+  // displays a graphical representation of the study. The items that
+  // can be selected in the Objects Browser are name Interactive
+  // Objects (instance of class SALOME_InteractiveObject). To work
+  // with data, we have to retrieve from this Interactive Object (IO)
+  // the underlying Study Object (instance of class SALOMEDS::SObject)
+  // and from this last the data object that can be anything (that
+  // depends of the SALOME module technical choices). In general, on
+  // of the attribute of a SObject is a CORBA servant that handles the
+  // data to work with
+  SALOMEDS::Study_ptr getActiveStudy();
+  int                 getActiveStudyId();
+
+  // Another way to get the active study (to be converted in
+  // SALOMEDS::Study):
+  SalomeApp_Study   * getSalomeAppActiveStudy();
+
+  SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject);
+
+  template<class TInterface> typename TInterface::_var_type
+  IObjectToInterface(const Handle(SALOME_InteractiveObject)& iobject) {
+    SALOMEDS::SObject_ptr sobject = IObjectToSObject(iobject);
+    return KERNEL::SObjectToInterface<TInterface>(sobject);
+  }
+  // _MEM_: note that template functions have to be declared AND
+  // implemented in the header because they are not compiled in this
+  // library but in every client library that includes this header
+  // file. The effective compilation depends on the particular class
+  // used for TInterface.
+
+
+}
+
+#endif // GUI_SERVICES
diff --git a/src/GuiHelpers/StandardApp_Module.cxx b/src/GuiHelpers/StandardApp_Module.cxx
new file mode 100644 (file)
index 0000000..1bc997f
--- /dev/null
@@ -0,0 +1,338 @@
+// Copyright (C) 2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Guillaume Boulant (EDF) 
+
+#include "StandardApp_Module.hxx"
+
+#include <SUIT_Desktop.h>
+#include <SUIT_Study.h>
+#include <SalomeApp_Application.h>
+#include <SALOME_LifeCycleCORBA.hxx>
+#include "QtxPopupMgr.h"
+
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
+
+// QT Includes
+#include <QIcon>
+#include <QAction>
+
+#include <Basics_Utils.hxx>
+#include "QtHelper.hxx"
+
+// Constructor
+StandardApp_Module::StandardApp_Module() :
+  SalomeApp_Module( "" ),
+  LightApp_Module( "" )
+{
+  // Note that it's no use to specify here the moduleName because it's
+  // automatically determined by the name of the GUI library
+  // (lib<moduleName>.so) just before initialize step. If you want
+  // nevertheless to setup the module name you should specified this
+  // name in the initialize function below using the CAM_module
+  // function setModuleName(QString&). You are warn then that the
+  // loading of resource files may be incorect and should be manually
+  // managed. In conclusion, if you don't need a special
+  // configuration, please conform to the standard convention: if
+  // <moduleName> is the name of the module as declared in the GUI
+  // configuration file (SalomeApp.xml), then you just have to provide
+  // a library whose name is lib<moduleName>.so and which contains a
+  // factory "extern C" function 'CAM_Module* createModule()'
+}
+
+int StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE = 910;
+int StandardApp_Module::ACTIONID_UNDEFINED = -1;
+
+// Module's initialization
+void StandardApp_Module::initialize( CAM_Application* app )
+{
+  //
+  // ----------------------------------------------------------------
+  // Standard initialization
+  // ----------------------------------------------------------------
+  //
+  SalomeApp_Module::initialize( app );
+  _resourceMgr = app->resourceMgr();
+  // Please note that the moduleName() function is inherited from
+  // CAM_module classe, and that its value is determined automatically
+  // from the name specified in the SalomeApp.xml associated to this
+  // module and which corresponds to the name of the GUI library
+  // (lib<moduleName>.so). For XSALOME, see
+  // share/salome/resources/xsalome/SalomeApp.xml in the install
+  // directory.
+  _defaultMenuId = this->createMenu( QCHARSTAR(moduleName()), -1, -1, 30 );
+  _defaultToolbarId = this->createTool ( QCHARSTAR(moduleName()) );
+  _actionId_internalCount = StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE;
+
+  //
+  // ----------------------------------------------------------------
+  // The following initializes the GUI widget and associated actions
+  // ----------------------------------------------------------------
+  // These functions may be redefined in specialized version of this class
+  this->createModuleWidgets();
+  this->createModuleActions();
+}
+
+QIcon StandardApp_Module::createIcon(const QString& iconName) {
+  // The icon file is supposed to be available througth the resource
+  // manager, i.e. in the folder containing the XSALOME resources (see
+  // specification in the module file SalomeApp.xml).
+  QPixmap aPixmap = _resourceMgr->loadPixmap( QCHARSTAR(moduleName()), iconName );
+  return QIcon( aPixmap );
+}
+
+int StandardApp_Module::newActionId() {
+  _actionId_internalCount++;
+  return _actionId_internalCount;
+}
+
+/*!
+ * This function creates an action and connects it to a button in the
+ * toolbar and to an item in the menu associated to this module.  This
+ * function applies a common and standard procedure with a maximum of
+ * default values. If no identifier is specified, then a static
+ * internal counter is used to associate an identifier to the created
+ * action. In any case, the action identifier is returned.
+ *
+ * Note that the action (object of type QAction) can be retrieved
+ * using the method "QAction * action(int identifier)" of the super
+ * class.
+ */
+int StandardApp_Module::createStandardAction(const QString& label,
+                                            QObject * slotobject,
+                                            const char* slotmember,
+                                            const QString& iconName,
+                                            const QString& tooltip,
+                                            const int identifier)
+{
+
+  // If the tooltip is not defined, we choose instead the label text.
+  QString effToolTip(tooltip);
+  if ( effToolTip.isEmpty() )
+    effToolTip = label;
+
+  QIcon actionIcon = this->createIcon(iconName);
+
+  // If the identifier is not specified, then we use an internal
+  // counter.
+  int effIdentifier = identifier;
+  if ( effIdentifier == StandardApp_Module::ACTIONID_UNDEFINED ) {
+    effIdentifier=newActionId();
+  }
+
+  // Creating the action
+  QAction * action= this->createAction( effIdentifier, label, actionIcon, 
+                                        label, effToolTip, 0, getApp()->desktop(),
+                                        false, slotobject, slotmember);
+
+  return effIdentifier;
+}
+
+/**
+ * Integrate the action in the default toolbar
+ */
+void StandardApp_Module::addActionInToolbar(int actionId) {
+  this->createTool( actionId, _defaultToolbarId );
+}
+
+/**
+ * Integrate the action in the default menu
+ */
+void StandardApp_Module::addActionInMenubar(int actionId) {
+  this->createMenu( actionId, _defaultMenuId, 10 );
+}
+
+/**
+ * Add the specified action as an item in the popup menu, with the
+ * specified visible rule. The default is "visible for object browser".
+ */
+void StandardApp_Module::addActionInPopupMenu(int actionId,const QString& rule) {
+  // _GBO_ for a fine customization of the rule (for example with a
+  // test on the type of the selected object), see the LIGTH module:
+  // implement "LightApp_Selection*    createSelection() const;"
+  int parentId = -1;
+  QtxPopupMgr* mgr = this->popupMgr();
+  mgr->insert ( this->action( actionId ), parentId, 0 );
+  mgr->setRule( this->action( actionId ), rule, QtxPopupMgr::VisibleRule );
+}
+
+/*!
+ * This function can be used to create additionnal widget for this
+ * module GUI (e.g. docked widget). It can be redefined in a
+ * specialized version of this class.
+ */
+void StandardApp_Module::createModuleWidgets() {
+  // Nothing to do in this default gui
+}
+
+/*!
+ * This function can be used to defined the list of actions for this
+ * module GUI.  It can be redefined in a specialized version of this
+ * class.
+ * Depending on wether you use the method "createStandardAction" or
+ * not, the actions will be automatically plugged in the toolbar and
+ * the menu associated to the module.
+ */
+void StandardApp_Module::createModuleActions() {
+  int actionId = this->createStandardAction("Test", this, SLOT(OnTest()),
+                                           "f1.png", "Run the default test function");
+  this->addActionInToolbar(actionId);
+}
+
+// Get compatible dockable windows.
+void StandardApp_Module::windows( QMap<int, int>& theMap ) const
+{
+  theMap.clear();
+  theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+  theMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
+}
+
+// Module's engine IOR
+QString StandardApp_Module::engineIOR() const
+{
+  CORBA::String_var anIOR = getApp()->orb()->object_to_string(getEngine());
+  return QString( anIOR.in() );
+}
+
+/*!
+ * This specifies the filename for the icon to be used for the study
+ * component associated to the module. Note that this icon could be
+ * different than the module icon which is defined by the
+ * SalomeApp.xml file dedicated to this module (see the shared
+ * resources folder dedicated to the module) and which is used for the
+ * toolbar of the SALOME application.
+ */
+QString StandardApp_Module::studyIconName()
+{
+  // By default, we return the module icone name
+  return iconName(); // inherited from CAM_Module
+}
+
+/*!
+ * This can be used to switch the layout of main application
+ * dockwidgets to one of the predefined configuration (see enum
+ * DockLayoutType). When a layout is set, the previous layout is
+ * memorized and can be restored using the unsetDockLayout function (1
+ * step undo). It is typically to be used in the functions
+ * activateModule to setup the layout and deactivateModule to unset
+ * the layout, i.e. restore to the previous state.
+ */
+void StandardApp_Module::setDockLayout(DockLayoutType layoutType) {
+  SUIT_Desktop* desk = getApp()->desktop();
+  _areaAtBottomLeftCorner = desk->corner(Qt::BottomLeftCorner);
+  _areaAtBottomRightCorner = desk->corner(Qt::BottomRightCorner);
+  
+  if ( layoutType == DOCKLAYOUT_LEFT_VLARGE ) {
+    desk->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+    desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+  } else {
+    desk->setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
+    desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);    
+  }
+}
+
+/*!
+ * This function restores the layout state that was previously in
+ * place before the last setDockLayout call.
+ */
+void StandardApp_Module::unsetDockLayout() {
+  SUIT_Desktop* desk = getApp()->desktop();
+  desk->setCorner(Qt::BottomLeftCorner, _areaAtBottomLeftCorner);
+  desk->setCorner(Qt::BottomRightCorner, _areaAtBottomRightCorner);
+}
+
+// Module's activation
+bool StandardApp_Module::activateModule( SUIT_Study* theStudy )
+{
+  bool bOk = SalomeApp_Module::activateModule( theStudy );
+
+  setMenuShown( true );
+  setToolShown( true );
+
+  if ( this->createStudyComponentAtActivation() ) {
+    this->createStudyComponent(theStudy);
+  }
+
+  return bOk;
+}
+
+/*!
+ * This function should be implemented in a specialized class and must
+ * return true if you want to automatically create a study component
+ * for this module at activation step (when you first load the module
+ * for a given study). The default function return true.
+ */
+bool StandardApp_Module::createStudyComponentAtActivation() {
+  return true;
+}
+
+/*!
+ * This creates a root entry in the active study for this module, i.e
+ * a SComponent with the name of the module and the icon specified for
+ * the module. This component is associated to the engine (return by
+ * getEngine()) if the engine is a SALOMEDS::Driver.
+ */
+void StandardApp_Module::createStudyComponent(SUIT_Study* theStudy) {
+
+  SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
+  CORBA::Object_var aSMObject = aNamingService->Resolve("/myStudyManager");
+  SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(aSMObject);
+  SALOMEDS::Study_var aDSStudy = aStudyManager->GetStudyByID(theStudy->id());
+
+  SALOMEDS::SComponent_var aFather = aDSStudy->FindComponent(QCHARSTAR(moduleName()));
+  if (aFather->_is_nil())
+    {
+      SALOMEDS::StudyBuilder_var aStudyBuilder = aDSStudy->NewBuilder();
+      aFather = aStudyBuilder->NewComponent(QCHARSTAR(moduleName()));
+      SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
+      SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
+      aName->SetValue(QCHARSTAR(moduleName()));
+      aName->Destroy();
+      anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
+      SALOMEDS::AttributePixMap_var aPixMap = SALOMEDS::AttributePixMap::_narrow(anAttr);
+      aPixMap->SetPixMap(QCHARSTAR(studyIconName()));
+
+      // WARN: The engine should be associated to the SComponent IF
+      // AND ONLY IF it is a SALOMEDS::Driver. Otherwise, there is no
+      // need to do that, and it could even lead to exception
+      // raising (eh, you work on SALOME isn't it?)
+      SALOMEDS::Driver_var driver = SALOMEDS::Driver::_narrow(this->getEngine());
+      if ( ! driver->_is_nil() ) {
+       STDLOG("Associate the SComponent to the engine");
+       aStudyBuilder->DefineComponentInstance(aFather, this->getEngine());
+      }
+    }
+
+}
+
+// Module's deactivation
+bool StandardApp_Module::deactivateModule( SUIT_Study* theStudy )
+{
+  setMenuShown( false );
+  setToolShown( false );
+
+  return SalomeApp_Module::deactivateModule( theStudy );
+}
+
+void StandardApp_Module::OnTest()
+{
+  // Just for test
+  STDLOG("OnTest: engine IOR = "<<QCHARSTAR(engineIOR()));
+}
+
diff --git a/src/GuiHelpers/StandardApp_Module.hxx b/src/GuiHelpers/StandardApp_Module.hxx
new file mode 100644 (file)
index 0000000..e29fa55
--- /dev/null
@@ -0,0 +1,145 @@
+// Copyright (C) 2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Guillaume Boulant (EDF) 
+
+#ifndef _STANDARDAPP_MODULE_HXX_
+#define _STANDARDAPP_MODULE_HXX_
+
+#include <SUIT_ResourceMgr.h>
+#include <SalomeApp_Module.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Component)
+
+#include <QString>
+
+/*!
+ * This class is provided as the base class for the standard gui part
+ * of a SALOME module. To define a gui part, you just have to
+ * implement the virtual functions:
+ * - getEngine() to specify the engine component associated to this module
+ * - createModuleActions(...) to specify the action functions
+ * - createModuleWidgets(...) to specify special additionnal widgets
+ *
+ * The gui part of a SALOME module is an extension of the SALOME
+ * client Application for this module. Technically speaking, it
+ * consists in a plugin that provides a derived class of CAM_Module
+ * (provided by the GUI module).
+ *
+ * A standard gui is the standard design for most of SALOME module
+ * (object browser on the left, viewer on the rigth, python console on
+ * the bottom, and toolbox in the toolbar with standard definition of
+ * the tool function). This standard design suggests also to specify
+ * the engine associated to the module by implementing the virtual
+ * pure function getEngine(). The engine of a module is the SALOME
+ * component that is associated to the study component for this
+ * module, and generally which is responsible for the persistency
+ * functions or data management for the module.
+ *
+ * See a use case example in the test module Xsalome provided by the
+ * test package (tst/module/gui/Xsalome.hxx and
+ * tst/module/gui/factory.cxx in the XSALOME library).
+ */
+class StandardApp_Module: public SalomeApp_Module
+{
+  Q_OBJECT
+
+public:
+
+  // ================================================================
+  // This part defines the standard interface of the SalomeApp_Module
+  // ================================================================
+
+  StandardApp_Module();
+  void    initialize( CAM_Application* );
+  QString engineIOR() const;
+  virtual void  windows( QMap<int, int>& theMap ) const;
+
+public slots:
+  bool    deactivateModule( SUIT_Study* );
+  bool    activateModule( SUIT_Study* );
+
+  // ================================================================
+  // This part defines the specific interface of this class
+  // ================================================================
+
+public:
+  /* Creates an action with standard default values */
+  int createStandardAction(const QString& label,
+                          QObject * slotobject,
+                           const char* slotmember,
+                           const QString& iconName=QString(),
+                           const QString& tooltip=QString(),
+                           const int identifier=ACTIONID_UNDEFINED);
+
+  void addActionInToolbar(int actionId);
+  void addActionInMenubar(int actionId);
+  void addActionInPopupMenu(int actionId,const QString& rule="client='ObjectBrowser'");
+
+protected:
+  /* Implement this to create additionnal widget (e.g. docked widget) */
+  virtual void createModuleWidgets();
+  /* Implement this to define the actions for this gui */
+  virtual void createModuleActions();
+
+  /* Use this to create a root entry in the study for this module */
+  void createStudyComponent(SUIT_Study*);
+  /* Implement this to say if study component entry should be created
+     at activation step */
+  virtual bool createStudyComponentAtActivation();
+
+  /* The engine is the SALOME component associated to the study */
+  virtual Engines::EngineComponent_ptr getEngine() const = 0;
+  // Note that the function getEngine() is virtual pure and must be
+  // implemented in the specific inherited classes. Note also that the
+  // const flag is required because getEngine is used by functions
+  // with const flags (see for ex: engineIOR()).
+  virtual QString studyIconName();
+
+  QIcon createIcon(const QString& iconName);
+  int newActionId();
+
+  enum DockLayoutType {
+    DOCKLAYOUT_BOTTOM_HLARGE, // Bottom is Horizontal Large
+    DOCKLAYOUT_LEFT_VLARGE,   // Left is Vertical Large
+  };
+  virtual void setDockLayout(DockLayoutType layoutType);
+  virtual void unsetDockLayout();
+  
+  SUIT_ResourceMgr* _resourceMgr;
+  int _defaultMenuId;
+  int _defaultToolbarId;
+
+  static int ACTIONID_DEFAULT_INIT_VALUE;
+  static int ACTIONID_UNDEFINED;
+
+private:
+  int _actionId_internalCount;
+  Qt::DockWidgetArea _areaAtBottomLeftCorner;
+  Qt::DockWidgetArea _areaAtBottomRightCorner;
+
+  // =========================================================
+  // This part defines slots for test purposes
+  // =========================================================
+
+protected slots:
+  void OnTest();
+};
+
+#endif
index d68377865191e8490da34797e5c40fa86d65a264..de80e714ffa66454cc37cc34242e333a9d2d4aa7 100755 (executable)
@@ -106,7 +106,7 @@ SUBDIRS_LIGHT = LightApp ResExporter
 # Full (CORBA) SALOME packages
 ##
 if GUI_ENABLE_CORBA
-  SUBDIRS_CORBA = TOOLSGUI Session SalomeApp 
+  SUBDIRS_CORBA = TOOLSGUI Session SalomeApp GuiHelpers TreeData
 endif
 
 ##
diff --git a/src/TreeData/DataModel.cxx b/src/TreeData/DataModel.cxx
new file mode 100644 (file)
index 0000000..615cd86
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DataModel.hxx"
+
+DataModel::DataModel() {
+
+}
+
+DataModel::~DataModel() {
+  _mapDataObjects.clear();
+}
+
+bool DataModel::addDataObject(DataObject * dataObject) {
+  _mapDataObjects[dataObject->getNameId()] = dataObject;
+  return true;
+}
+bool DataModel::removeDataObject(string nameId) {
+  _mapDataObjects.erase(nameId);
+  return true;
+}
+bool DataModel::removeDataObject(DataObject * dataObject) {
+  if ( dataObject == NULL ) return false;
+  return removeDataObject(dataObject->getNameId());
+}
+
+DataObject * DataModel::getDataObject(string id) {
+  return _mapDataObjects[id];
+}
+
+
+
+map<string, DataObject *>::iterator DataModel::begin() {
+  return _mapDataObjects.begin();
+}
+
+map<string, DataObject *>::iterator DataModel::end() {
+  return _mapDataObjects.end();
+}
diff --git a/src/TreeData/DataModel.hxx b/src/TreeData/DataModel.hxx
new file mode 100644 (file)
index 0000000..4321451
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef DATAMODEL_H
+#define DATAMODEL_H
+
+#include <map>
+#include "DataObject.hxx"
+
+class DataModel {
+
+public:
+  DataModel();
+  ~DataModel();
+
+  /*!
+   * This function can be used to create a specific instance of
+   * DataObject. Note that this function is a pure virtual method and
+   * then no default behavior is done. In particular, the newly
+   * created object is not automatically added to the data model. This
+   * behavior should be implemented in a dedicated version of this
+   * class.
+   */
+  virtual DataObject * newDataObject() = 0;
+
+  /*! Function to add data object to the model */
+  bool addDataObject(DataObject * dataObject);
+  /*! Functions to remove data object from the model */
+  bool removeDataObject(string nameId);
+  bool removeDataObject(DataObject * dataObject);
+  /*! Function to retrieve a data object in the model */
+  DataObject * getDataObject(string nameId);
+
+  map<string, DataObject *>::iterator begin();
+  map<string, DataObject *>::iterator end();
+
+private:
+  map<string, DataObject *> _mapDataObjects;
+  
+
+};
+
+#endif // DATAMODEL_H
diff --git a/src/TreeData/DataObject.cxx b/src/TreeData/DataObject.cxx
new file mode 100644 (file)
index 0000000..ac65147
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DataObject.hxx"
+#include <Basics_Utils.hxx>
+
+// Static assignement
+int DataObject::_lastId=0;
+const string DataObject::_BASENAME = string("object_");
+const string DataObject::pathsep = string("/");
+
+DataObject::DataObject() {
+  _nameId = _BASENAME+ToString(_lastId);
+  _lastId++;
+  // The default label is set to the nameId, but it can be modified
+  // using setLabel whereas the nameId can't be modified.
+  _label  = _nameId;
+}
+
+DataObject::~DataObject() {
+  _properties.clear();
+}
+
+void DataObject::setLabel(string label) {
+  _label = label;
+}
+string DataObject::getLabel() {
+  return _label;
+}
+
+string DataObject::getPathName() {
+  string pathName;
+  pathName = this->getPath() + pathsep + this->getLabel();
+  return pathName;
+}
+
+
+string DataObject::getNameId() {
+  return _nameId;
+}
+
+void DataObject::setProperty(string key, string value) {
+  _properties[key] = value;
+}
+string DataObject::getProperty(string key) {
+  return _properties[key];
+}
+
+string DataObject::toString() {
+  string serialize="\n";
+  serialize+="nameId = "+getNameId()+"\n";
+  serialize+="label  = "+getLabel()+"\n";
+  serialize+="path   = "+getPath();
+  return serialize;
+}
diff --git a/src/TreeData/DataObject.hxx b/src/TreeData/DataObject.hxx
new file mode 100644 (file)
index 0000000..f67d676
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef DATAOBJECT_H
+#define DATAOBJECT_H
+
+#include <map>
+#include <string>
+using namespace std;
+
+class DataObject {
+
+public:
+  DataObject();
+  ~DataObject();
+
+  void setLabel(string label);
+  string getLabel();
+  void setProperty(string key, string value);
+  string getProperty(string key);
+
+  /*!
+   * This function specifies the localization of the object in the
+   * hierarchical organization that can be defined by the DataModel it
+   * belongs to.
+   */
+  virtual string getPath() = 0;
+  string getPathName();
+  string getNameId();
+
+  static const string pathsep;
+
+  /*! This function can be used for debug */
+  string toString();
+
+private:
+  /*! The name this object can be displayed with */
+  string _label;
+  /*! The identifier of this object. An identifier is invariant all the session long */
+  string _nameId;
+  /*! The dictionnary of properties that characterize this object */
+  map<string, string> _properties;
+
+  static int _lastId;
+  static const string _BASENAME;
+};
+
+#endif // DATAOBJECT_H
diff --git a/src/TreeData/DataProcessor.cxx b/src/TreeData/DataProcessor.cxx
new file mode 100644 (file)
index 0000000..f356765
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include "DataProcessor.hxx"
+#include <Basics_Utils.hxx>
+#include "QtHelper.hxx"
+
+DataProcessor::DataProcessor(DataModel * dataModel) {
+  _dataModel = dataModel;
+}
+
+/*!
+ * This function retrieves in the data model all the DataObject
+ * associated to the item nameIds contained in the specified list. The
+ * input list is what the TreeView sends via the notification signal.
+ */
+DataObjectVector * DataProcessor::extract(QStringList itemNameIdList) {
+  if ( _dataModel == NULL ) {
+    STDLOG("No data model associated to this processor");
+    return NULL;
+  }
+
+  DataObjectVector * dataObjectList = new DataObjectVector();
+
+  // We can request the dataModel to obtain the dataObject associated
+  // to each of the item (iteNameId is a TreeView id, Qt stuff only).
+  QStringList::const_iterator it;
+  for (it = itemNameIdList.constBegin(); it != itemNameIdList.constEnd(); ++it) {
+    QString itemNameId = *it;
+    DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+    
+    if ( dataObject != NULL ) {
+      dataObjectList->push_back(dataObject);
+    } else {
+      LOG("No data object associated to the item "<<itemNameId);
+    } 
+  }
+  return dataObjectList;
+}
+
+
+void DataProcessor::process(QStringList itemNameIdList) {
+  if ( _dataModel == NULL ) {
+    STDLOG("No data model");
+    return;
+  }
+
+  this->preprocess(itemNameIdList);
+
+  // We can request the dataModel to obtain the dataObject associated
+  // to each of the item (iteNameId is a TreeView id, Qt stuff only).
+  QStringList::const_iterator it;
+  for (it = itemNameIdList.constBegin(); it != itemNameIdList.constEnd(); ++it) {
+    QString itemNameId = *it;
+    DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+    
+    if ( dataObject != NULL ) {
+      this->processDataObject(dataObject);
+    } else {
+      STDLOG("No data object associated to the item "<<QS2S(itemNameId));
+    } 
+  }
+
+  this->postprocess(itemNameIdList);
+}
+
+
diff --git a/src/TreeData/DataProcessor.hxx b/src/TreeData/DataProcessor.hxx
new file mode 100644 (file)
index 0000000..76b0d11
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _DATAPROCESSOR_H_
+#define _DATAPROCESSOR_H_
+
+#include "DataModel.hxx"
+#include "DataObject.hxx"
+#include <QStringList>
+#include <QString>
+
+#include <vector>
+typedef std::vector<DataObject *> DataObjectVector;
+
+//
+// =================================================================
+// This class can be used to automize processing on data objects.
+// The inputs of public functions are list of selected items in the
+// tree view. The function automize the extraction of associated
+// DataObject and can automize the processing of these object if the
+// virtual function processDataObject is implemented.
+// =================================================================
+//
+
+class DataProcessor {
+
+public:
+  DataProcessor(DataModel * dataModel);
+
+  DataObjectVector * extract(QStringList itemNameIdList);
+  void               process(QStringList itemNameIdList);
+
+  
+protected:
+  virtual void preprocess(QStringList itemNameIdList) {
+      // Implement something to be executed at the begining of the process function
+  };
+  virtual void postprocess(QStringList itemNameIdList) {
+      // Implement something to be executed at the end of the process function
+  };
+  // Implement what must be done with each DataObject during the process function
+  virtual void processDataObject(DataObject * dataObject) = 0;
+
+private:
+  DataModel * _dataModel;
+};
+
+#endif
diff --git a/src/TreeData/DockWidgets.cxx b/src/TreeData/DockWidgets.cxx
new file mode 100644 (file)
index 0000000..ead3b5c
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "DockWidgets.hxx"
+
+// Qt includes
+#include <QMainWindow>
+
+// SALOME includes
+#include <SUIT_Desktop.h>
+#include <SUIT_DataBrowser.h>
+#include <QtxTreeView.h>
+
+/*!
+ * This create a gui container to hold widgets dedicated to the XCAD
+ * data model. By default, the dock widgets are not visible. Use the
+ * show() method to control the visibility (usefull when activating
+ * and desactivating the module to show/hide the dock widgets).
+ *
+ * This class does not make any hypothesis on what will be embedded in
+ * the dock widgets (only that it is QTreeView). The QTreeView is
+ * defined elsewhere and is generaly rendering a tree model containing
+ * tree items.
+ */
+DockWidgets::DockWidgets(SalomeApp_Application* salomeApp,
+                        bool tabify,
+                        const char * title) {
+  _salomeApp = salomeApp;
+
+  QMainWindow *parent = _salomeApp->desktop();
+  _dwDataPanel = new QDockWidget(parent);
+  _dwDataPanel->setVisible(false);
+  _dwDataPanel->setWindowTitle(title);
+  parent->addDockWidget(Qt::LeftDockWidgetArea, _dwDataPanel);
+  //
+  // At this step, the _dwDataPanel is located side by side with the object
+  // browser (or one over the other).
+  //
+  // It is possible to tabify the different dock widgets in one single
+  // tabbed widget. See the above example:
+  this->tabify(tabify);
+}
+
+void DockWidgets::tabify(bool tabify) {
+  if ( tabify ) {    
+    // We first get the object browser tree view, and then the
+    // associated DockWidget. Note that the tree view is a SALOME
+    // specific extention of the originate QTreeView and called
+    // QtxTreeView.
+    SUIT_DataBrowser* objectBrowser = _salomeApp->objectBrowser();
+    QtxTreeView* treeView = objectBrowser->treeView();
+    QWidget* pw = treeView->parentWidget();
+    QDockWidget* dwObjectBrowser = 0;
+    while ( pw && !dwObjectBrowser ) {
+      dwObjectBrowser = ::qobject_cast<QDockWidget*>( pw );
+      pw = pw->parentWidget();
+    };
+    QMainWindow *parent = _salomeApp->desktop();
+    parent->tabifyDockWidget(_dwDataPanel, dwObjectBrowser);
+    parent->setTabOrder(_dwDataPanel, dwObjectBrowser);
+    parent->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
+  }
+  else {
+    // TO BE IMPLEMENTED
+  }
+}
+
+/*!
+ * This function controls the visibility of the dock widgets.
+ */
+void DockWidgets::show(bool isVisible) {
+  _dwDataPanel->setVisible(isVisible);
+}
+
+/*!
+ * This function initializes the central part of the dock widget with
+ * a tree view that can hold a hierarchical data model.
+ */
+void DockWidgets::setDataView(QTreeView * dataView) {
+  _tvDataView = dataView;
+  _tvDataView->setParent(_dwDataPanel);
+  _tvDataView->setMinimumHeight(200);
+  _dwDataPanel->setWidget(_tvDataView);
+}
+
+void DockWidgets::setPropertiesView(QTreeView * propertiesView) {
+  // Not implemented yet
+}
diff --git a/src/TreeData/DockWidgets.hxx b/src/TreeData/DockWidgets.hxx
new file mode 100644 (file)
index 0000000..26487c4
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _DOCKWIDGETS_H_
+#define _DOCKWIDGETS_H_
+
+// Qt includes
+#include <QDockWidget>
+#include <QTreeView>
+
+// SALOME includes
+#include <SalomeApp_Application.h>
+
+class DockWidgets {
+ public:
+  DockWidgets(SalomeApp_Application* salomeApp,
+             bool tabify=false,
+             const char * title="Data Model");
+
+  void tabify(bool tabify);
+  void show(bool isVisible);
+  void setDataView(QTreeView * dataView);
+  void setPropertiesView(QTreeView * propertyView);
+
+ private:
+  SalomeApp_Application* _salomeApp;
+  QDockWidget * _dwDataPanel;
+  QTreeView * _tvDataView;
+};
+
+#endif // _DOCKWIDGETS_H_
diff --git a/src/TreeData/Makefile.am b/src/TreeData/Makefile.am
new file mode 100644 (file)
index 0000000..025b2c8
--- /dev/null
@@ -0,0 +1,106 @@
+#  Copyright (C) 2010  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+#  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
+#
+# -* Makefile *- 
+#
+# Author : Guillaume Boulant (EDF) 
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# moc-files generation
+%_moc.cxx: %.hxx
+       $(MOC) $< -o $@
+
+mostlyclean-local:
+       rm -f @builddir@/*_moc.cxx
+       rm -f @builddir@/*.qm
+
+# Libraries targets
+lib_LTLIBRARIES = libSalomeTreeData.la
+
+#
+# Generic source files
+#
+salomeinclude_HEADERS = \
+       DockWidgets.hxx \
+       TreeModel.hxx \
+       TreeItem.hxx \
+       TreeView.hxx \
+       TreeObserver.hxx \
+       DataModel.hxx \
+       DataObject.hxx \
+       DataProcessor.hxx \
+       TreeGuiManager.hxx
+
+dist_libSalomeTreeData_la_SOURCES = \
+       DockWidgets.cxx \
+       TreeModel.cxx \
+       TreeItem.cxx \
+       TreeView.cxx \
+       TreeObserver.cxx \
+       DataModel.cxx \
+       DataObject.cxx \
+       DataProcessor.cxx \
+       TreeGuiManager.cxx
+
+# MOC pre-processing
+MOC_FILES = \
+       TreeModel_moc.cxx \
+       TreeView_moc.cxx \
+       TreeObserver_moc.cxx
+
+nodist_libSalomeTreeData_la_SOURCES = $(MOC_FILES)
+
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+CAS_CXXFLAGS=@CAS_CPPFLAGS@ @CAS_CXXFLAGS@
+
+BOOST_CPPFLAGS=@BOOST_CPPFLAGS@
+BOOST_LIBS=@BOOST_LIBS@
+
+libSalomeTreeData_la_CPPFLAGS = \
+       $(QT_CXXFLAGS) \
+       $(CAS_CXXFLAGS) \
+       $(BOOST_CPPFLAGS) \
+       $(CORBA_CXXFLAGS) \
+       $(KERNEL_CXXFLAGS) \
+       -I$(srcdir)/../SalomeApp \
+       -I$(srcdir)/../LightApp  \
+       -I$(srcdir)/../CAM  \
+       -I$(srcdir)/../STD \
+       -I$(srcdir)/../ObjBrowser \
+       -I$(srcdir)/../SUIT \
+       -I$(srcdir)/../Qtx \
+       -I$(srcdir)/../GuiHelpers
+
+
+
+
+libSalomeTreeData_la_LDFLAGS  = \
+       $(CORBA_LIBS) $(QT_LIBS)\
+       $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeKernelHelpers \
+       $(top_builddir)/src/SalomeApp/libSalomeApp.la \
+       $(top_builddir)/src/LightApp/libLightApp.la \
+       $(top_builddir)/src/SUIT/libsuit.la \
+       $(top_builddir)/src/Qtx/libqtx.la \
+       $(top_builddir)/src/CAM/libCAM.la \
+       $(top_builddir)/src/STD/libstd.la \
+       $(top_builddir)/src/ObjBrowser/libObjBrowser.la
diff --git a/src/TreeData/TreeGuiManager.cxx b/src/TreeData/TreeGuiManager.cxx
new file mode 100644 (file)
index 0000000..297692b
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "TreeGuiManager.hxx"
+
+// SALOME includes
+#include <QStringList>
+
+// XCAD includes
+#include "TreeView.hxx"
+#include "QtHelper.hxx"
+
+// TODO:
+// IMP: The constructor should have a dockwidget as argument.
+// The creation of the void dockwidget (without the data tree
+// embedded) should be done previously by the StandardApp_Module.
+// The constructor would fill the dockwidget with a data tree view
+
+/*!
+ * The construction of the gui manager setups a graphic framework that
+ * consists in a set of dock widgets implanted in the SALOME GUI and
+ * embedding a tree view rendering a data model (collection of data
+ * objects) in a hierarchic graphical organisation.
+ *
+ * The data model is a straith list of data objects while the view is
+ * a tree representation of this collection where folders corresponds
+ * to specific properties of the objects.
+ *
+ * This represention is for the needs of navigation in a huge amount
+ * of data and to ease the selection and processing of items.
+ */
+TreeGuiManager::TreeGuiManager(SalomeApp_Application * salomeApp, const char * title)
+  : TreeObserver()
+{
+  _salomeApp = salomeApp;
+  
+  bool tabify = false;
+  _dockWidgets = new DockWidgets(_salomeApp, tabify, title);
+
+  // Create a TreeView to be associated to a TreeModel dedicated to
+  // the Xcad data:
+  _dataTreeView = new TreeView();
+  QStringList headers;
+  headers << tr("Name") << tr("Value");
+  _dataTreeModel = new TreeModel(headers);
+  _dataTreeView->setModel(_dataTreeModel);
+
+  // Then plug the TreeView in the dock widget:
+  _dockWidgets->setDataView(_dataTreeView);
+
+  // We specify here the dataview to be observed
+  this->observe(_dataTreeView);
+}
+
+/*!
+ * This returns the SALOME application (SalomeApp_Application
+ * instance) associated to this TreeGuiManager.
+ */
+SalomeApp_Application * TreeGuiManager::getSalomeApplication() {
+  return _salomeApp;
+}
+
+
+/*!
+ * This function set a layout of the different dock widgets in one
+ * single tabbed widget.
+ */
+void TreeGuiManager::tabifyDockWidgets(bool tabify) {
+  _dockWidgets->tabify(tabify);
+}
+
+/*!
+ * This function switch on/off the dock widgets managed by this
+ * gui manager.
+ */
+void TreeGuiManager::showDockWidgets(bool isVisible) {
+  _dockWidgets->show(isVisible);
+}
+
+/*!
+ * This returns the data tree model defined in this
+ * TreeGuiManager. The data tree model is a tree representation of the
+ * data model associated to this TreeGuiManager.
+ */
+TreeModel * TreeGuiManager::getDataTreeModel() {
+  return _dataTreeModel;
+}
+
+/*!
+ * This returns the data tree view defined in this
+ * TreeGuiManager. The data tree view can be request to customize the
+ * popup menu associated to the tree representation.
+ */
+TreeView * TreeGuiManager::getDataTreeView() {
+  return _dataTreeView;
+}
+
+
+/*!
+ * This function specifies the data model to be used by the
+ * TreeGuiManager.
+ */
+void TreeGuiManager::setDataModel(DataModel * dataModel) {
+  _dataModel = dataModel;
+}
+
+DataModel * TreeGuiManager::getDataModel() {
+  return _dataModel;
+}
+
+/*!
+ * This function processes the edit signals received from the
+ * TreeView. This is a default implementation that only prints the
+ * reception of the signal and some information about the dataObject
+ * associated to the item whose id is specified. In practice, the data
+ * model could be requested here to retrieve the data object to be
+ * edited from the nameId.
+ * TO BE IMPLEMENTED IN A DOMAIN SPECIFIC VERSION OF THIS CLASS
+ */
+
+void TreeGuiManager::processItemList(QStringList itemNameIdList,
+                                    int actionId)
+{
+  // WARN: THIS IS A DEFAULT IMPLEMENTATION GIVEN FOR DEMONSTRATION
+  // OF WHAT TO DO WITH THE PARAMETERS
+
+  QString itemNameId = itemNameIdList[0];
+  LOG("TreeGuiManager: signal received : process item "<<itemNameId);
+  DataObject * dataObject = _dataModel->getDataObject(QS2S(itemNameId));
+  if ( dataObject != NULL ) {
+    LOG("TreeGuiManager: dataObject = "<<dataObject->toString().c_str());
+  } else {
+    LOG("TreeGuiManager: no data object associated to this item");
+  }
+}
diff --git a/src/TreeData/TreeGuiManager.hxx b/src/TreeData/TreeGuiManager.hxx
new file mode 100644 (file)
index 0000000..c27e750
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _TREEGUIMANAGER_H_
+#define _TREEGUIMANAGER_H_
+
+// SALOME includes
+#include <SalomeApp_Application.h>
+
+// TREEDATA includes
+#include "DockWidgets.hxx"
+#include "TreeModel.hxx"
+#include "DataModel.hxx"
+#include "TreeView.hxx"
+#include "TreeObserver.hxx"
+
+class TreeGuiManager : public TreeObserver {
+  
+public:
+  TreeGuiManager(SalomeApp_Application * salomeApp, const char * title="Data Model");
+  void tabifyDockWidgets(bool tabify);
+  void showDockWidgets(bool isVisible);
+  SalomeApp_Application * getSalomeApplication();
+  
+  TreeModel * getDataTreeModel();
+  TreeView * getDataTreeView();
+  
+  void setDataModel(DataModel * dataModel);
+  DataModel * getDataModel();
+  
+private:
+  SalomeApp_Application * _salomeApp;
+  
+  DockWidgets * _dockWidgets;
+  TreeView * _dataTreeView;
+  
+  TreeModel * _dataTreeModel;
+  DataModel * _dataModel;
+  
+public slots:
+  virtual void processItemList(QStringList itemNameIdList, int actionId);
+};
+
+#endif /* _TREEGUIMANAGER_H_ */
diff --git a/src/TreeData/TreeItem.cxx b/src/TreeData/TreeItem.cxx
new file mode 100644 (file)
index 0000000..9af3dca
--- /dev/null
@@ -0,0 +1,242 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include <QStringList>
+#include "TreeItem.hxx"
+
+TreeItem::TreeItem(const QString &nameId,
+                   const QVector<QVariant> &columnValues,
+                   TreeItem *parent)
+{
+  this->initialize(nameId, columnValues, parent);
+}
+
+/*!
+ * This initializes the tree item. Called by the constructors.
+ */
+void TreeItem::initialize(const QString &nameId,
+                          const QVector<QVariant> &columnValues,
+                          TreeItem *parent) {
+  _itemNameId = nameId;
+  _itemData   = columnValues;
+  _parentItem = parent;
+
+  // An item is associated to the model of its parent. It can't be
+  //done automatically in the case where the item has no parent. Then
+  //the function associatedToModel has to be called explicitely from
+  //within the user code (for exemple at construction of the model,
+  //when creating the root item).
+  if ( parent != NULL ) {
+    this->associateToModel(parent->associatedModel());
+  }  
+}
+
+TreeItem::~TreeItem()
+{
+  qDeleteAll(_childItems);
+  qDeleteAll(_childItemsMapById);
+  qDeleteAll(_childItemsMapByLabel);
+}
+
+/*!
+ * This must be used to specified which model this item belongs to. It
+ * is required because the item sometimes requests its model for
+ * global informations about the data tree. In standard usage, this
+ * function is automatically set when the item is instantiated by
+ * requested the parent item. Then only the root item needs a manual
+ * setting.
+ */
+void TreeItem::associateToModel(TreeModel * model) {
+  _associatedModel = model;
+}
+
+TreeModel * TreeItem::associatedModel() {
+  return _associatedModel;
+}
+
+/*!
+ * This provide an identifier for this item
+ */
+QString TreeItem::nameId() {
+  return _itemNameId;
+}
+
+/*!
+ * This creates an item from the specified dataObject and put it in
+ * the decendency of this item at the specified relativePath. The
+ * created item could not be a direct child of this item in the case
+ * where the relative path is not null. Note that no reference on the
+ * dataObject is kept in this instance. Only the identifier is used to
+ * set the item identifier, and the properties may be used to set the
+ * values of the item (stored in columns).
+ */
+void TreeItem::appendChild(DataObject * dataObject,
+                           const QStringList &relativePath) {
+  // Definition of the nameId
+  QString nameId = QString(dataObject->getNameId().c_str());
+
+  // Definition of columns data values
+  QVector<QVariant> columnValues;
+  columnValues << QString(dataObject->getLabel().c_str());
+  columnValues << "No value"; // We could use the dataObject properties
+
+  // Append the item at the specified location with the specified values:
+  this->appendChild(nameId, columnValues, relativePath);
+}
+
+void TreeItem::appendChild(const QString &nameId,
+                           const QVector<QVariant> &columnValues,
+                           const QStringList &relativePath) {
+
+  if ( relativePath.isEmpty() ) {
+    // It is a direct child => just create and append to this.
+    TreeItem * child = new TreeItem(nameId, columnValues, this);
+    this->appendChild(child);
+    return;
+  }
+
+  // The child is embedded in a sub-folder (to be created if doesn't
+  // exist).
+  // We first check if the sub-folder already exist:
+  TreeItem * folder = this->childByLabel(relativePath[0]);
+  if ( folder == NULL ) {
+    // The folder does not exist. It must be created before going any
+    // further. By convention we choose the folder name as
+    // identifier.
+    QString folderNameId = relativePath[0];
+    QVector<QVariant> folderColumnValues;
+    folderColumnValues << relativePath[0] << "No value";
+    folder = new TreeItem(folderNameId, folderColumnValues, this);
+    this->appendChild(folder);
+  }
+    
+  // We create the relative path of the next iteration (delete the
+  // first folder path).
+  QStringList nextRelativePath;
+  for (int i = 1; i < relativePath.size(); ++i)
+    nextRelativePath << relativePath[i];
+    
+  folder->appendChild(nameId, columnValues, nextRelativePath);
+}
+
+/*!
+ * This appends the specified child to this item. This item is the
+ * direct parent of the specified child.
+ */
+void TreeItem::appendChild(TreeItem *item)
+{
+  TreeModel * model = this->associatedModel();
+
+  int position = this->childCount();
+  model->beginInsertRows(this->modelIndex(), position, position);
+  _childItems.append(item);
+  _childItemsMapById[item->nameId()] = item;
+  _childItemsMapByLabel[item->data(0).toString()] = item;
+  model->endInsertRows();
+}
+
+/*!
+ * The child() function returns the child that corresponds to the
+ * specified row number in the item's list of child items.
+ */
+TreeItem *TreeItem::child(int row)
+{
+  return _childItems.value(row);
+}
+
+TreeItem *TreeItem::childById(const QString &nameId)
+{
+  QMap <QString, TreeItem*>::iterator it;
+  it = _childItemsMapById.find ( nameId );
+
+  if ( it != _childItemsMapById.end() ) {
+    return it.value();
+  }
+  return NULL;
+}
+
+TreeItem *TreeItem::childByLabel(const QString &label)
+{
+  QMap <QString, TreeItem*>::iterator it;
+  it = _childItemsMapByLabel.find ( label );
+
+  if ( it != _childItemsMapByLabel.end() ) {
+    return it.value();
+  }
+  return NULL;
+}
+
+
+
+int TreeItem::childCount() const
+{
+  return _childItems.count();
+}
+
+/*!
+ * The rowIndex() function reports the item's location within its
+ * parent's list of items.
+ */
+int TreeItem::rowIndex() const
+{
+  if (_parentItem)
+    return _parentItem->_childItems.indexOf(const_cast<TreeItem*>(this));
+
+  return 0;
+}
+
+int TreeItem::columnCount() const
+{
+  return _itemData.count();
+}
+
+QVariant TreeItem::data(int column) const
+{
+  return _itemData.value(column);
+}
+
+TreeItem *TreeItem::parent()
+{
+  return _parentItem;
+}
+
+bool TreeItem::setData(int column, const QVariant &value)
+{
+  if (column < 0 || column >= _itemData.size())
+    return false;
+
+  _itemData[column] = value;
+  return true;
+}
+
+QModelIndex TreeItem::modelIndex(int column)
+{
+  TreeModel * model = this->associatedModel();
+  if (_parentItem && (_parentItem != model->getRootItem()))
+    return model->index(rowIndex(),
+                        column,
+                        _parentItem->modelIndex());
+  else
+    return model->index(rowIndex(),
+                        column,
+                        QModelIndex());
+}
diff --git a/src/TreeData/TreeItem.hxx b/src/TreeData/TreeItem.hxx
new file mode 100644 (file)
index 0000000..fd34188
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef TREEITEM_H
+#define TREEITEM_H
+
+#include <QList>
+#include <QVariant>
+#include <QVector>
+#include <QModelIndex>
+
+#include "DataObject.hxx"
+#include "TreeModel.hxx"
+
+class TreeItem
+{
+ public:
+  TreeItem(const QString &nameId, const QVector<QVariant> &columnValues, TreeItem *parent = 0);
+  ~TreeItem();
+
+  QString nameId();
+  void associateToModel(TreeModel * model);
+  TreeModel * associatedModel();
+  QModelIndex modelIndex(int column=0);
+  TreeItem *parent();
+
+  void appendChild(TreeItem * child);
+  void appendChild(DataObject * dataObject,
+                   const QStringList &relativePath=QStringList());
+  void appendChild(const QString &nameId,
+                   const QVector<QVariant> &columnValues,
+                   const QStringList &relativePath=QStringList());
+
+  
+  
+  TreeItem *child(int row);
+  TreeItem *childById(const QString &nameId);
+  TreeItem *childByLabel(const QString &label);
+  int childCount() const;
+  int columnCount() const;
+  int rowIndex() const;
+  QVariant data(int column) const;
+  bool setData(int column, const QVariant &value);
+
+
+ private:
+  void initialize(const QString &nameId,
+                  const QVector<QVariant> &columnValues,
+                  TreeItem *parent);
+
+  QList<TreeItem*> _childItems;
+  QMap <QString, TreeItem *> _childItemsMapById;
+  QMap <QString, TreeItem *> _childItemsMapByLabel;
+
+  QString _itemNameId;
+  QVector<QVariant> _itemData;
+  TreeItem  * _parentItem;
+  TreeModel * _associatedModel;
+
+};
+
+#endif
diff --git a/src/TreeData/TreeModel.cxx b/src/TreeData/TreeModel.cxx
new file mode 100644 (file)
index 0000000..3e8f451
--- /dev/null
@@ -0,0 +1,210 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#include <QtGui>
+
+#include "TreeItem.hxx"
+#include "TreeModel.hxx"
+
+TreeModel::TreeModel(const QStringList &headers, QObject *parent)
+  : QAbstractItemModel(parent)
+{
+  QVector<QVariant> rootData;
+  foreach (QString header, headers)
+    rootData << header;
+
+  // _MEM_ We have to specify a string identifier for each item so
+  // that it could be easily retrieved by its parent. In the case of
+  // the root item, the value of the identifier doesn't matter => we
+  // choose an arbitrary value
+  //QString rootNameId = "rootItem";
+  _rootItem = new TreeItem("rootItem", rootData);
+  _rootItem->associateToModel(this);
+}
+
+TreeModel::~TreeModel()
+{
+  delete _rootItem;
+}
+
+TreeItem * TreeModel::getRootItem() {
+  return _rootItem;
+}
+
+//
+// =================================================================
+// This part of the implementation is the standard interface required
+// for providing an operational TreeModel. These methods are used by
+// the TreeView for display purpose. We just have to implement how we
+// want the items to be displayed in the view.
+// =================================================================
+//
+int TreeModel::columnCount(const QModelIndex & /* parent */) const
+{
+  return _rootItem->columnCount();
+}
+
+/*!
+ * This function is used by the tree model to inform the tree view of
+ * what data used for rendering of the item in the different possible
+ * role (edition, ...).
+ */
+QVariant TreeModel::data(const QModelIndex &index, int role) const
+{
+  if (!index.isValid())
+    return QVariant();
+
+  if (role != Qt::DisplayRole && role != Qt::EditRole)
+    return QVariant();
+
+  TreeItem *item = getItem(index);
+
+  return item->data(index.column());
+}
+
+Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
+{
+  if (!index.isValid())
+    return 0;
+
+  return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+/*!
+ * This retrieves the item asociated to the specified index.
+ */
+TreeItem *TreeModel::getItem(const QModelIndex &index) const
+{
+  // The item associated to an index can be retrieved using the
+  // internalPointer() function on the index object.
+  if (index.isValid()) {
+    TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
+    if (item) return item;
+  }
+  return _rootItem;
+}
+
+QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
+                               int role) const
+{
+  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+    return _rootItem->data(section);
+
+  return QVariant();
+}
+
+/*!
+ * This retrieves the index of the item located at (row,column) place
+ * relative to the parent specified by its index.
+ */
+QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
+{
+  if (parent.isValid() && parent.column() != 0)
+    return QModelIndex();
+
+  TreeItem *parentItem = getItem(parent);
+
+  TreeItem *childItem = parentItem->child(row);
+  if (childItem)
+    return createIndex(row, column, childItem);
+  else
+    return QModelIndex();
+}
+
+QModelIndex TreeModel::parent(const QModelIndex &index) const
+{
+  if (!index.isValid())
+    return QModelIndex();
+
+  TreeItem *childItem = getItem(index);
+  TreeItem *parentItem = childItem->parent();
+
+  if (parentItem == _rootItem)
+    return QModelIndex();
+
+  return createIndex(parentItem->rowIndex(), 0, parentItem);
+}
+
+int TreeModel::rowCount(const QModelIndex &parent) const
+{
+  TreeItem *parentItem = getItem(parent);
+
+  return parentItem->childCount();
+}
+
+bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
+                        int role)
+{
+  if (role != Qt::EditRole)
+    return false;
+
+  TreeItem *item = getItem(index);
+  bool result = item->setData(index.column(), value);
+
+  if (result)
+    emit dataChanged(index, index);
+
+  return result;
+}
+
+bool TreeModel::setHeaderData(int section, Qt::Orientation orientation,
+                              const QVariant &value, int role)
+{
+  if (role != Qt::EditRole || orientation != Qt::Horizontal)
+    return false;
+
+  bool result = _rootItem->setData(section, value);
+
+  if (result)
+    emit headerDataChanged(orientation, section, section);
+
+  return result;
+}
+
+
+//
+// =================================================================
+// This part is a specific behavior to get a TreeModel that can
+// organize itself the tree hierarchy using data provided in a
+// filesystem-like format:
+// 
+// data="a/b/c" ==> creation/filling of the hierarchy a->b->c
+// The "folder" categories are unique whereas the leaves may exists
+// in multiple instances.
+// =================================================================
+//
+
+/*
+ * The addData functions run a recurcive filling of the tree model, starting
+ * form the rootItem and descending in the tree using the recurcive
+ * function TreeItem::addData.
+ */
+
+bool TreeModel::addData(DataObject * dataObject) {
+  QStringList path = QString(dataObject->getPath().c_str()).split(DataObject::pathsep.c_str());
+  return addData(dataObject, path);
+}
+bool TreeModel::addData(DataObject * dataObject, const QStringList &path) {
+  TreeItem * rootItem = this->getItem();
+  rootItem->appendChild(dataObject, path);
+  return true;
+}
diff --git a/src/TreeData/TreeModel.hxx b/src/TreeData/TreeModel.hxx
new file mode 100644 (file)
index 0000000..c588235
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef TREEMODEL_H
+#define TREEMODEL_H
+
+#include <QAbstractItemModel>
+#include <QModelIndex>
+#include <QVariant>
+#include <QStringList>
+
+#include "DataObject.hxx"
+
+class TreeItem;
+class TreeView;
+
+class TreeModel : public QAbstractItemModel
+{
+  Q_OBJECT
+
+  // IMPORTANT NOTE:
+  // In this implementation of QAbstractItemModel, a tree item is
+  // associated to the tree model it belongs to (it can request its
+  // model throw a pointer to this model). Then we declare the
+  // TreeItem as a friend class so that it can request the protected
+  // methods (for example beginInsertRows and endInsertRows, required
+  // to manage correctly the addition of an item in the model. An
+  // item can append a child to itself, so it needs to inform the
+  // model when it begins and when it ends).
+  friend class TreeItem;
+  friend class TreeView;
+
+public:
+  TreeModel(const QStringList &headers, QObject *parent = 0);
+  ~TreeModel();
+
+  //
+  // =================================================================
+  // This part of the specification is the standard interface required
+  // for providing an operational TreeModel. These methods are used by
+  // the TreeView for display purpose. We just have to implement how
+  // we want the items to be displayed in the view.
+  // =================================================================
+  //
+  // MEM: note that these methods are not intended to be used
+  // directly. That's the job of the viewer to know how to use
+  // them. We just have to give the implementation for customizing the
+  // appearance of the tree. The implementation generally requests the
+  // items'data to set the appearance features.
+  QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+  QModelIndex parent(const QModelIndex &index) const;
+  int rowCount(const QModelIndex &parent = QModelIndex()) const;
+  int columnCount(const QModelIndex &parent = QModelIndex()) const;
+  QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
+  bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+  Qt::ItemFlags flags(const QModelIndex &index) const;
+
+  //
+  // =================================================================
+  // This part is a specific behavior to get a TreeModel that can
+  // organize itself the tree hierarchy using data provided in a
+  // filesystem-like format:
+  // 
+  // data="a/b/c" ==> creation/filling of the hierarchy a->b->c
+  // The "folder" categories are unique whereas the leaves may exists
+  // in multiple instances.
+  // =================================================================
+  //
+  bool addData(DataObject * dataObject);
+  bool addData(DataObject * dataObject, const QStringList &path);
+
+  // TODO: We should implement the delete and the update fucntions
+
+  // This part contains helper functions for general purposes
+  TreeItem * getRootItem();
+
+private:
+  TreeItem *getItem(const QModelIndex &index = QModelIndex()) const;
+  TreeItem * _rootItem;
+};
+
+#endif // TREEMODEL_H
diff --git a/src/TreeData/TreeObserver.cxx b/src/TreeData/TreeObserver.cxx
new file mode 100644 (file)
index 0000000..310ea13
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#include "TreeObserver.hxx"
+#include "QtHelper.hxx"
+
+TreeObserver::TreeObserver() : QObject() {
+}
+
+/*!
+ * This declares the TreeView to be observed by this tree events
+ * listener.
+ */
+void TreeObserver::observe(TreeView * treeView) {
+  // We just connect the signals emitted from the treeview to
+  // corresponding slots of this observer.
+  connect(treeView, SIGNAL(itemListToProcess(QStringList,int)),
+          this, SLOT(processItemList(QStringList,int)));
+}
+
+/*!
+ * This slot should be implemented in a specialized version of
+ * TreeObserver to process the signal emitted from the TreeView. The
+ * parameters are:
+ * - itemNameIdList: the list of name identifiers of model objects
+ *   associated to the selected qt items in the TreeView (ids for
+ *   requesting directly the data model).
+ * - actionId: the identifier of the action selected in the popup menu
+ *   that triggered this signal.
+ */
+void TreeObserver::processItemList(QStringList itemNameIdList, int actionId) {
+  LOG("TreeObserver::processItemList: signal received:\n"<<
+      "item list: "<<itemNameIdList<<"\n"<<
+      "action id: "<<actionId);
+}
+
diff --git a/src/TreeData/TreeObserver.hxx b/src/TreeData/TreeObserver.hxx
new file mode 100644 (file)
index 0000000..8d7bf66
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+#ifndef _TREEOBSERVER_
+#define _TREEOBSERVER_
+
+#include <QObject>
+#include "TreeView.hxx"
+
+class TreeObserver : public QObject {
+
+  Q_OBJECT
+
+public:
+  TreeObserver();
+  void observe(TreeView * treeView);
+
+public slots:
+ /* These slots should be implemented in a specialized version of
+    the TreeObserver to process signals emitted from the TreeView */
+  virtual void processItemList(QStringList itemNameIdList, int actionId);
+};
+
+#endif // _TREEOBSERVER_
diff --git a/src/TreeData/TreeView.cxx b/src/TreeData/TreeView.cxx
new file mode 100644 (file)
index 0000000..462fad8
--- /dev/null
@@ -0,0 +1,144 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+// include Qt
+#include <QString>
+#include <QMenu>
+#include <QModelIndex>
+#include <QAbstractItemView>
+
+// include Xcad
+#include "TreeView.hxx"
+#include "TreeModel.hxx"
+#include "TreeItem.hxx"
+#include "QtHelper.hxx"
+
+TreeView::TreeView(QWidget * parent)
+  : QTreeView(parent)
+{
+  // We authorize the multiple selection of items
+  this->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+  _lastActionId = 0;
+
+  // Default actions for tests
+  int displayActionId = addAction(QObject::tr("Afficher"));
+  int editActionId    = addAction(QObject::tr("Editer"));
+}
+
+TreeView::~TreeView() {
+}
+
+/*!
+ * This function defines a menu item to add in the popup menu
+ * associated to this TreeView, and return an integer that corresponds
+ * to the unique identifier of this action (identifier used in the
+ * signal emitted to notify observers that an action has been
+ * selected). Then the caller of this function has to take care of
+ * this return id (i.e. has to store it in its internal tables) to be
+ * able to process the notifications from this TreeView.
+ */
+int TreeView::addAction(QString label) {
+  QAction * action = new QAction(this);
+  int actionId = _lastActionId;
+  action->setObjectName(_idToName(actionId));
+  action->setText(label);
+  _listActions << action;
+  _lastActionId++;
+
+  return actionId;
+}
+
+/*!
+ * This function removes all actions previously defined for the popup
+ * menu of this TreeView.
+ */
+void TreeView::clearActions() {
+  _listActions.clear();
+}
+
+/*!
+ * You must use this function to create the name of an action object
+ * from its id.
+ */
+QString TreeView::_idToName(int actionId) {
+  return QString::number(actionId);
+}
+/*!
+ * You must use this function to create the id of an action object
+ * from its name (stored in objectName() attribute of the QAction).
+ */
+int TreeView::_nameToId(QString actionName) {
+  return actionName.toInt();
+}
+
+void TreeView::contextMenuEvent(QContextMenuEvent *event) {
+  if ( _listActions.size() == 0 ) {
+    // Just return there is no actions defined for this popup menu
+    return;
+  }
+
+  // _TODO_ display the QMenu only if the selected item is acceptable
+  QMenu menu(this);
+  for (int i = 0; i < _listActions.size(); ++i) {
+    menu.addAction(_listActions.at(i));
+  }
+  connect(&menu, SIGNAL(triggered(QAction*)),
+         this,  SLOT(processMenuAction(QAction*)));
+
+  menu.exec(event->globalPos());
+}
+
+/*!
+ * This SLOT is connected on the signal emited by the menu when an
+ * action is selected.
+ */
+void TreeView::processMenuAction(QAction * actionSelected) {
+  LOG("processMenuAction: START");
+
+  // We first check than at least on item is selected
+  QModelIndexList indexList = this->selectionModel()->selectedRows(0);
+  if ( indexList.isEmpty() ) {
+    LOG("No item selected");
+    return;
+  }
+
+  // Then we can gather the list of model item ids associated the
+  // selection.
+  TreeModel *model = (TreeModel *)this->model();
+  QListIterator<QModelIndex> it(indexList);
+  QStringList nameIdList;
+  while (it.hasNext()) {
+    TreeItem * item = model->getItem(it.next());
+    nameIdList << item->nameId();
+  }
+
+  // Finally, one can emit a signal to observers specifying the list of
+  // id and the type of action (i.e. the action identifier)
+  int actionId = _nameToId(actionSelected->objectName());
+  LOG("TreeView::processMenuAction: signal emitted:\n"<<
+      "item list: "<<nameIdList<<"\n"<<
+      "action id: "<<actionId);
+  emit itemListToProcess(nameIdList, actionId);
+
+  LOG("processMenuAction: END");
+}
diff --git a/src/TreeData/TreeView.hxx b/src/TreeData/TreeView.hxx
new file mode 100644 (file)
index 0000000..60a4b44
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+// Author: Guillaume Boulant (EDF/R&D)
+
+
+#ifndef TREEVIEW_H
+#define TREEVIEW_H
+
+#include <QTreeView>
+#include <QAction>
+#include <QContextMenuEvent>
+#include <QList>
+
+class TreeView : public QTreeView
+{
+  Q_OBJECT
+
+public:
+  TreeView(QWidget * parent = 0 );
+  ~TreeView();
+  int  addAction(QString label);
+  void clearActions();
+  
+protected:
+  void contextMenuEvent(QContextMenuEvent *event);
+
+private:
+  int _lastActionId;
+  QList<QAction*> _listActions;
+  QString _idToName(int actionId);
+  int _nameToId(QString actionName);
+  
+  // ---
+
+private slots:
+  void processMenuAction(QAction * actionSelected);
+  
+signals:
+  void itemListToProcess(QStringList itemNameIdList, int actionId);
+};
+
+#endif // TREEVIEW_H
+