Salome HOME
Initial pre-design of XML based Tree Model
authorvsv <vitaly.smetannikov@opencascade.com>
Wed, 22 Jul 2015 09:59:36 +0000 (12:59 +0300)
committervsv <vitaly.smetannikov@opencascade.com>
Wed, 22 Jul 2015 09:59:49 +0000 (12:59 +0300)
src/Config/CMakeLists.txt
src/Config/Config_DataModelReader.cpp [new file with mode: 0644]
src/Config/Config_DataModelReader.h [new file with mode: 0644]
src/Config/Config_Keywords.h
src/Config/dataModel.xml [new file with mode: 0644]
src/XGUI/CMakeLists.txt
src/XGUI/XGUI_DataModel.cpp [new file with mode: 0644]
src/XGUI/XGUI_DataModel.h [new file with mode: 0644]
src/XGUI/XGUI_ObjectsBrowser.cpp
src/XGUI/XGUI_ObjectsBrowser.h

index 0837555e7350b4e8419e7a660d8f0c6f9879cf46..1dfbae0b13590897a96d831bbb2fbc3be44f8cd3 100644 (file)
@@ -23,6 +23,7 @@ SET(PROJECT_HEADERS
   Config_AttributeMessage.h
   Config_SelectionFilterMessage.h
   Config_ValidatorReader.h
+  Config_DataModelReader.h
  )
  
 SET(PROJECT_SOURCES
@@ -40,10 +41,12 @@ SET(PROJECT_SOURCES
   Config_AttributeMessage.cpp
   Config_SelectionFilterMessage.cpp
   Config_ValidatorReader.cpp
+  Config_DataModelReader.cpp
 )
 
 SET(XML_RESOURCES
   plugins.xml
+  dataModel.xml
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/Config/Config_DataModelReader.cpp b/src/Config/Config_DataModelReader.cpp
new file mode 100644 (file)
index 0000000..5479a98
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * Config_DataModelReader.cpp
+ *
+ *  Created on: Jul 21, 2015
+ *      Author: vsv
+ */
+
+#include "Config_DataModelReader.h"
+#include <Config_Keywords.h>
+#include "Config_Common.h"
+
+#include <Events_Error.h>
+
+
+Config_DataModelReader::Config_DataModelReader()
+    : Config_XMLReader(DATAMODEL_FILE)
+{
+}
+
+Config_DataModelReader::~Config_DataModelReader()
+{
+}
+
+void Config_DataModelReader::processNode(xmlNodePtr theNode)
+{
+  if (isNode(theNode, NODE_FOLDER, NULL)) {
+    std::string aName = getProperty(theNode, FOLDER_NAME);
+    std::string aGroupType = getProperty(theNode, GROUP_TYPE);
+    if (aName.empty() || aGroupType.empty())
+      Events_Error::send("Reading dataModel.xml: wrong folder definition");
+   
+    myRootFolderNames.push_back(aName);
+    myRootFolderTypes.push_back(aGroupType);
+    myRootFolderIcons.push_back(getProperty(theNode, NODE_ICON));
+  } else if  (isNode(theNode, ROOT_NODE, NULL)) {
+    myRootTypes = getProperty(theNode, GROUP_TYPE);
+  }
+}
diff --git a/src/Config/Config_DataModelReader.h b/src/Config/Config_DataModelReader.h
new file mode 100644 (file)
index 0000000..caba2b6
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * Config_DataModelReader.h
+ *
+ *  Created on: Jul 21, 2015
+ *      Author: vsv
+ */
+
+#ifndef CONFIG_DATAMODELREADER_H_
+#define CONFIG_DATAMODELREADER_H_
+
+#include <Config_def.h>
+#include <Config_XMLReader.h>
+
+#include <vector>
+#include <string>
+
+/*!
+ * \class Config_DataModelReader
+ * \ingroup Config
+ * \brief Class that reads data model definition XML for
+ * further processing in the XGUI_DataModel
+ */
+class Config_DataModelReader : public Config_XMLReader
+{
+ public:
+  /*!
+   * Constructor
+   * \param theXmlFile - full path to the xml file which will be processed by the reader
+   */
+  CONFIG_EXPORT Config_DataModelReader();
+  CONFIG_EXPORT virtual ~Config_DataModelReader();
+
+  /// Returns name of type of tree items in root
+  CONFIG_EXPORT std::string rootType() const { return myRootTypes; }
+
+  /// Returns number of folders under root 
+  CONFIG_EXPORT int rootFoldersNumber() const { return myRootFolderNames.size(); }
+
+  /// Returns name of the folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string rootFolderName(int theId) const { return myRootFolderNames[theId]; }
+
+  /// Returns data type in the folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string rootFolderType(int theId) const { return myRootFolderTypes[theId]; }
+
+  /// Returns icon of a folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string rootFolderIcon(int theId) const { return myRootFolderIcons[theId]; }
+
+ protected:
+  /// Overloaded method. Defines how to process each node
+  virtual void processNode(xmlNodePtr theNode);
+
+private:
+  std::vector<std::string> myRootFolderNames;
+  std::vector<std::string> myRootFolderTypes;
+  std::vector<std::string> myRootFolderIcons;
+
+  std::string myRootTypes;
+};
+
+
+#endif
\ No newline at end of file
index 96adf95b2f2cb66c55499d41b838a73e88cd415d..46a7f013732d74fa44cea3736cfbc647fb5c2688 100644 (file)
@@ -95,6 +95,14 @@ const static char* PLUGIN_DEPENDENCY = "dependency";
 const static char* PLUGIN_PLATFORM_SALOME = "salome";
 const static char* PLUGIN_PLATFORM_NEWGEOM = "openparts";
 
-
+/*
+ * Hardcoded xml entities of dataModel.xml
+ */
+const static char* DATAMODEL_FILE = "dataModel.xml";
+const static char* NODE_FOLDER = "folder";
+const static char* FOLDER_NAME = "name";
+const static char* GROUP_TYPE = "group_type";
+const static char* ROOT_NODE = "tree_root";
+const static char* NODE_ICON = "icon";
 
 #endif /* CONFIG_KEYWORDS_H_ */
diff --git a/src/Config/dataModel.xml b/src/Config/dataModel.xml
new file mode 100644 (file)
index 0000000..fae0ff0
--- /dev/null
@@ -0,0 +1,8 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+<data_model>
+    <tree_root group_type="Features">
+        <folder name="Parameters" group_type="Parameters" icon=":pictures/constr_folder.png"/>
+        <folder name="Constructions" group_type="Construction" icon=":pictures/constr_folder.png"/>
+        <folder name="Parts" group_type="Parts" icon=":pictures/constr_folder.png"/>
+    </tree_root>
+</data_model>
\ No newline at end of file
index 494759b7645d3fced0ddece8d0d85af7d60a84d7..a5b6b0c2e74f58cf639af421fabdd645a65f440e 100644 (file)
@@ -24,6 +24,7 @@ SET(PROJECT_HEADERS
        XGUI_Workshop.h
        XGUI_WorkshopListener.h
        XGUI_HistoryMenu.h
+       XGUI_DataModel.h
 )
 
 SET(PROJECT_AUTOMOC 
@@ -50,6 +51,7 @@ SET(PROJECT_SOURCES
        XGUI_Workshop.cpp
        XGUI_WorkshopListener.cpp
        XGUI_HistoryMenu.cpp
+       XGUI_DataModel.cpp
 )
 
 SET(PROJECT_RESOURCES 
diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp
new file mode 100644 (file)
index 0000000..5efbb82
--- /dev/null
@@ -0,0 +1,166 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        ModuleBase_IDocumentDataModel.cpp
+// Created:     28 Apr 2015
+// Author:      Vitaly SMETANNIKOV
+
+#include "XGUI_DataModel.h"
+
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Document.h>
+
+#include <QIcon>
+
+XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent)
+{
+  myXMLReader.readAll();
+}
+
+//******************************************************
+void XGUI_DataModel::clear()
+{
+
+}
+
+//******************************************************
+void XGUI_DataModel::rebuildDataTree()
+{
+
+}
+
+//******************************************************
+ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const
+{
+  return ObjectPtr();
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject) const
+{
+  return QModelIndex();
+}
+
+//******************************************************
+QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  int aNbFolders = myXMLReader.rootFoldersNumber();
+  int theIndexRow = theIndex.row();
+
+  if ((theIndex.column() == 1) ) {
+    if (theIndexRow >= aNbFolders) {
+      if (theRole == Qt::DecorationRole) {
+        return QIcon(":pictures/arrow.png");
+      }
+    }
+    return QVariant();
+  }
+
+  int aParentRow = theIndex.internalId();
+  if (aParentRow == -1) { // First level of items
+    if (theIndexRow < aNbFolders) { // A folder
+      switch (theRole) {
+        case Qt::DisplayRole:
+          return QString(myXMLReader.rootFolderName(theIndexRow).c_str()) + 
+            QString(" (%1)").arg(rowCount(theIndex));
+        case Qt::DecorationRole:
+          return QIcon(myXMLReader.rootFolderIcon(theIndexRow).c_str());
+      }
+    } else {
+      ObjectPtr aObj = aRootDoc->object(myXMLReader.rootType(), theIndexRow - aNbFolders);
+      switch (theRole) {
+        case Qt::DisplayRole:
+          return aObj->data()->name().c_str();
+        //case Qt::DecorationRole:
+        //  return featureIcon(aFeature);
+      }
+    }
+  } else { // Content of folders
+    if (aParentRow < aNbFolders) {
+      std::string aType = myXMLReader.rootFolderType(aParentRow);
+      ObjectPtr aObj = aRootDoc->object(aType, theIndexRow);
+      switch (theRole) {
+        case Qt::DisplayRole:
+          return aObj->data()->name().c_str();
+      }
+    }
+  }
+  return QVariant();
+}
+
+//******************************************************
+QVariant XGUI_DataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
+{
+  return QVariant();
+}
+
+//******************************************************
+int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  if (!aSession->hasModuleDocument())
+    return 0;
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  int aNbFolders = myXMLReader.rootFoldersNumber();
+
+  int aNbItems = 0;
+  std::string aType = myXMLReader.rootType();
+  if (!aType.empty())
+    aNbItems = aRootDoc->size(aType);
+
+  if (!theParent.isValid())
+    return aNbFolders + aNbItems;
+
+  int aParentPos = theParent.row();
+  if (aParentPos < aNbFolders) {
+    // This is number of items under folder
+    aType = myXMLReader.rootFolderType(aParentPos);
+    return aRootDoc->size(aType);
+  }
+  return 0;
+}
+
+//******************************************************
+int XGUI_DataModel::columnCount(const QModelIndex& theParent) const
+{
+  return 2;
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
+{
+  if (!theParent.isValid())
+    return createIndex(theRow, theColumn, -1);
+
+  return createIndex(theRow, theColumn, theParent.row());
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
+{
+  if (theIndex.isValid() && (theIndex.internalId() != -1)) {
+    return createIndex(theIndex.internalId(), theIndex.column(), -1);
+  }
+  return QModelIndex();
+}
+
+//******************************************************
+bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const
+{
+  int aNbFolders = myXMLReader.rootFoldersNumber();
+  if (!theParent.isValid() && aNbFolders)
+    return true;
+  if (theParent.internalId() == -1) {
+    if (theParent.row() < aNbFolders) {
+      std::string aType = myXMLReader.rootFolderType(theParent.row());
+      if (!aType.empty()) {
+        SessionPtr aSession = ModelAPI_Session::get();
+        DocumentPtr aRootDoc = aSession->moduleDocument();
+        return aRootDoc->size(aType) > 0;
+      }
+    }
+  }
+  return false;
+}
+
diff --git a/src/XGUI/XGUI_DataModel.h b/src/XGUI/XGUI_DataModel.h
new file mode 100644 (file)
index 0000000..e1157cc
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        XGUI_DataModel.h
+// Created:     21 Jul 2015
+// Author:      Vitaly SMETANNIKOV
+
+
+#ifndef XGUI_DataModel_H
+#define XGUI_DataModel_H
+
+#include "XGUI.h"
+#include <ModelAPI_Object.h>
+#include <Config_DataModelReader.h>
+#include <QAbstractItemModel>
+
+class XGUI_EXPORT XGUI_DataModel : public QAbstractItemModel
+{
+Q_OBJECT
+public:
+  XGUI_DataModel(QObject* theParent);
+
+  //! Returns an object by the given Model index.
+  //! Returns 0 if the given index is not index of an object
+  virtual ObjectPtr object(const QModelIndex& theIndex) const;
+
+  //! Returns index of the object
+  //! \param theObject object to find
+  virtual QModelIndex objectIndex(const ObjectPtr theObject) const;
+
+  //! Clear internal data
+  virtual void clear();
+
+  //! Rebuild data tree
+  virtual void rebuildDataTree();
+
+
+  /// Returns the data stored under the given role for the item referred to by the index.
+  /// \param theIndex a model index
+  /// \param theRole a data role (see Qt::ItemDataRole)
+  virtual QVariant data(const QModelIndex& theIndex, int theRole) const;
+
+  /// Returns the data for the given role and section in the header with the specified orientation.
+  /// \param theSection a section
+  /// \param theOrient an orientation
+  /// \param theRole a data role (see Qt::ItemDataRole)
+  virtual QVariant headerData(int theSection, Qt::Orientation theOrient, int theRole =
+                                  Qt::DisplayRole) const;
+
+  /// Returns the number of rows under the given parent. When the parent is valid it means that 
+  /// rowCount is returning the number of children of parent.
+  /// \param theParent a parent model index
+  virtual int rowCount(const QModelIndex& theParent = QModelIndex()) const;
+
+  /// Returns the number of columns for the children of the given parent.
+  /// It has a one column
+  /// \param theParent a parent model index
+  virtual int columnCount(const QModelIndex& theParent = QModelIndex()) const;
+
+  /// Returns the index of the item in the model specified by the given row, column and parent index.
+  /// \param theRow a row
+  /// \param theColumn a column
+  /// \param theParent a parent model index
+  virtual QModelIndex index(int theRow, int theColumn, const QModelIndex &theParent =
+                                QModelIndex()) const;
+
+  /// Returns the parent of the model item with the given index. 
+  /// If the item has no parent, an invalid QModelIndex is returned.
+  /// \param theIndex a model index
+  virtual QModelIndex parent(const QModelIndex& theIndex) const;
+
+  /// Returns true if parent has any children; otherwise returns false.
+  /// \param theParent a parent model index
+  virtual bool hasChildren(const QModelIndex& theParent = QModelIndex()) const;
+
+
+private:
+  Config_DataModelReader myXMLReader;
+};
+
+#endif
\ No newline at end of file
index 417a95ec69da8682c58794dbf86abf09130ed11f..658a1d1e2e59003fc076cb6826c06886c9c94a17 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "XGUI_ObjectsBrowser.h"
 #include "XGUI_Tools.h"
+#include "XGUI_DataModel.h"
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Session.h>
@@ -349,7 +350,11 @@ void XGUI_ObjectsBrowser::clearContent()
 
 void XGUI_ObjectsBrowser::setDataModel(ModuleBase_IDocumentDataModel* theModel)
 {
+#ifdef ModuleDataModel
   myDocModel = theModel;
+#else
+  myDocModel = new XGUI_DataModel(this);
+#endif
   myTreeView->setModel(myDocModel);
   QItemSelectionModel* aSelMod = myTreeView->selectionModel();
   connect(aSelMod, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
@@ -366,7 +371,11 @@ QObjectPtrList XGUI_ObjectsBrowser::selectedObjects(QModelIndexList* theIndexes)
 {
   QObjectPtrList aList;
   QModelIndexList aIndexes = selectedIndexes();
+#ifdef ModuleDataModel
   ModuleBase_IDocumentDataModel* aModel = dataModel();
+#else
+  XGUI_DataModel* aModel = dataModel();
+#endif
   QModelIndexList::const_iterator aIt;
   for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
     if ((*aIt).column() == 0) {
index 09f9dc220764d1bede32452e75d40cd26c81eccb..a59ec8bd313a8ba99e5b299d8f6b85988a5a3919 100644 (file)
@@ -14,6 +14,9 @@
 
 class ModuleBase_IDocumentDataModel;
 class QLineEdit;
+class XGUI_DataModel;
+
+#define ModuleDataModel
 
 /**
 * \ingroup GUI
@@ -70,10 +73,17 @@ Q_OBJECT
   virtual ~XGUI_ObjectsBrowser();
 
   //! Returns Model which provides access to data objects
+#ifdef ModuleDataModel
   ModuleBase_IDocumentDataModel* dataModel() const
   {
     return myDocModel;
   }
+#else
+  XGUI_DataModel* dataModel() const
+  {
+    return myDocModel;
+  }
+#endif
 
   //! Returns list of currently selected objects
   //! \param theIndexes - output list of corresponded indexes (can be NULL)
@@ -140,8 +150,11 @@ signals:
   void closeDocNameEditing(bool toSave);
 
   //! Internal model
+#ifdef ModuleDataModel
   ModuleBase_IDocumentDataModel* myDocModel;
-
+#else
+  XGUI_DataModel* myDocModel;
+#endif
   QLineEdit* myActiveDocLbl;
   XGUI_DataTree* myTreeView;
 };