Salome HOME
Redevelopment of object browser data model
[modules/shaper.git] / src / XGUI / XGUI_DataModel.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "XGUI_DataModel.h"
22 //#include "XGUI_Workshop.h"
23 #include "XGUI_ObjectsBrowser.h"
24 //#include "XGUI_Displayer.h"
25
26 #include <ModuleBase_IconFactory.h>
27 #include <ModuleBase_ITreeNode.h>
28
29 #include <ModelAPI_Session.h>
30 //#include <ModelAPI_Events.h>
31 //#include <ModelAPI_ResultParameter.h>
32 //#include <ModelAPI_AttributeDouble.h>
33 //#include <ModelAPI_ResultPart.h>
34 //#include <ModelAPI_Feature.h>
35 //#include <ModelAPI_CompositeFeature.h>
36 //#include <ModelAPI_ResultCompSolid.h>
37 //#include <ModelAPI_ResultField.h>
38 //#include <ModelAPI_Tools.h>
39 //#include <ModelAPI_Folder.h>
40 //#include <ModelAPI_AttributeReference.h>
41
42 #include <Config_FeatureMessage.h>
43 //#include <Config_DataModelReader.h>
44
45 #include <Events_Loop.h>
46
47 //#include <QIcon>
48 //#include <QBrush>
49
50 #include <cassert>
51
52 //#define ACTIVE_COLOR QColor(Qt::black)
53 //#define ACTIVE_COLOR QColor(0,72,140)
54 //#define PASSIVE_COLOR Qt::black
55
56 /// Returns ResultPart object if the given object is a Part feature
57 /// Otherwise returns NULL
58
59 //#define SELECTABLE_COLOR QColor(110, 110, 110)
60 //#define DISABLED_COLOR QColor(200, 200, 200)
61
62
63 //ResultPartPtr getPartResult(ModelAPI_Object* theObj)
64 //{
65 //  ModelAPI_Feature* aFeature = dynamic_cast<ModelAPI_Feature*>(theObj);
66 //  if (aFeature) {
67 //    ResultPtr aRes = aFeature->firstResult();
68 //    if (aRes.get() && (aRes->groupName() == ModelAPI_ResultPart::group())) {
69 //      ResultPartPtr aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aRes);
70 //      // Use only original parts, not a placement results
71 //      if (aPartRes == aPartRes->original())
72 //      return aPartRes;
73 //    }
74 //  }
75 //  return ResultPartPtr();
76 //}
77 //
78 /// Returns pointer on document if the given object is document object
79 //ModelAPI_Document* getSubDocument(void* theObj)
80 //{
81 //  ModelAPI_Document* aDoc = 0;
82 //  try {
83 //    aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
84 //  } catch(...) {}
85 //  return aDoc;
86 //}
87
88
89
90
91 // Constructor *************************************************
92 XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent)//,
93   //myIsEventsProcessingBlocked(false)
94 {
95   XGUI_ObjectsBrowser* aOB = qobject_cast<XGUI_ObjectsBrowser*>(theParent);
96   myWorkshop = aOB->workshop();
97
98   Events_Loop* aLoop = Events_Loop::loop();
99   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
100   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
101   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
102   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_ORDER_UPDATED));
103   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED));
104 }
105
106 XGUI_DataModel::~XGUI_DataModel()
107 {
108   clear();
109 }
110
111 //******************************************************
112 void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMessage)
113 {
114   if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
115     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
116         std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
117     std::set<ObjectPtr> aObjects = aUpdMsg->objects();
118     QObjectPtrList aCreated;
119     std::set<ObjectPtr>::const_iterator aIt;
120     for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++)
121       aCreated.append(*aIt);
122     QTreeNodesList aNodes = myRoot->objectCreated(aCreated);
123     ModuleBase_ITreeNode* aParent;
124     int aRow = 0;
125     QModelIndex aParentIndex;
126     foreach(ModuleBase_ITreeNode* aNode, aNodes) {
127       aParent = aNode->parent();
128       aRow = aParent->nodeRow(aNode);
129       aParentIndex = getParentIndex(aNode, 0);
130       insertRows(aRow, 1, aParentIndex);
131     }
132   }
133   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
134       std::shared_ptr<ModelAPI_ObjectDeletedMessage> aUpdMsg =
135           std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
136       DocumentPtr aDoc = aUpdMsg->document();
137       std::set<std::string> aMsgGroups = aUpdMsg->groups();
138       std::set<std::string>::const_iterator aIt;
139       for (aIt = aMsgGroups.cbegin(); aIt != aMsgGroups.cend(); aIt++)
140         QTreeNodesList aList = myRoot->objectsDeleted(aDoc, (*aIt).c_str());
141       rebuildDataTree();
142   }
143   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) {
144     std::shared_ptr<ModelAPI_OrderUpdatedMessage> aUpdMsg =
145       std::dynamic_pointer_cast<ModelAPI_OrderUpdatedMessage>(theMessage);
146     if (aUpdMsg->reordered().get()) {
147       DocumentPtr aDoc = aUpdMsg->reordered()->document();
148       std::string aGroup = aUpdMsg->reordered()->group();
149       ModuleBase_ITreeNode* aNode = myRoot->findParent(aDoc, aGroup.c_str());
150       if (aNode) {
151         aNode->update();
152         int aRows = aNode->childrenCount();
153         if (aRows) {
154           QModelIndex aParent = getIndex(aNode, 0);
155           QModelIndex aFirstIdx = aParent.child(0, 0);
156           QModelIndex aLastIdx = aParent.child(aRows - 1, 2);
157           dataChanged(aFirstIdx, aLastIdx);
158         }
159       }
160     }
161   }
162   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
163     DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument();
164   }
165   //if (myIsEventsProcessingBlocked)
166   //  return;
167   //DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
168   //std::string aRootType = myXMLReader->rootType();
169   //std::string aSubType = myXMLReader->subType();
170   //int aNbFolders = foldersCount();
171
172   //// Created object event *******************
173   //if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
174   //  std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
175   //      std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
176   //  std::set<ObjectPtr> aObjects = aUpdMsg->objects();
177
178   //  std::set<ObjectPtr>::const_iterator aIt;
179   //  std::string aObjType;
180   //  for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
181   //    ObjectPtr aObject = (*aIt);
182   //    // We do not show objects which does not need to be shown in object browser
183   //    if (!aObject->isInHistory())
184   //      continue;
185
186   //    aObjType = aObject->groupName();
187   //    DocumentPtr aDoc = aObject->document();
188   //    if (aDoc == aRootDoc) {
189   //      // Check that new folders could appear
190   //      QStringList aNotEmptyFolders = listOfShowNotEmptyFolders();
191   //      foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
192   //        if ((aNotEmptyFolder.toStdString() == aObjType) && (aRootDoc->size(aObjType) > 0)) {
193   //          // Appears first object in folder which can not be shown empty
194   //          if (!hasShownFolder(aRootDoc, aNotEmptyFolder)) {
195   //            insertRow(myXMLReader->rootFolderId(aObjType));
196   //            addShownFolder(aRootDoc, aNotEmptyFolder);
197   //          }
198   //        }
199   //      }
200   //      // Insert new object
201   //      int aRow = aRootDoc->size(aObjType) - 1;
202   //      if (aRow != -1) {
203   //        if ((aObjType == aRootType) || (aObjType == ModelAPI_Folder::group())) {
204   //          insertRow(aRow + aNbFolders + 1);
205   //        } else {
206   //          int aFolderId = myXMLReader->rootFolderId(aObjType);
207   //          if (aFolderId != -1) {
208   //            insertRow(aRow, createIndex(aFolderId, 0, (void*)Q_NULLPTR));
209   //          }
210   //        }
211   //      }
212   //    } else {
213   //      // Object created in sub-document
214   //      QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0);
215   //      if (aDocRoot.isValid()) {
216   //        // Check that new folders could appear
217   //        QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false);
218   //        foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
219   //          if ((aNotEmptyFolder.toStdString() == aObjType) && (aDoc->size(aObjType) > 0)) {
220   //            // Appears first object in folder which can not be shown empty
221   //            if (!hasShownFolder(aDoc, aNotEmptyFolder)) {
222   //              insertRow(myXMLReader->subFolderId(aObjType), aDocRoot);
223   //              addShownFolder(aDoc, aNotEmptyFolder);
224   //            }
225   //          }
226   //       }
227   //        int aRow = aDoc->index(aObject, true);
228   //        if (aRow != -1) {
229   //          int aNbSubFolders = foldersCount(aDoc.get());
230   //          if ((aObjType == aSubType) || (aObjType == ModelAPI_Folder::group())) {
231   //            // List of objects under document root
232   //            insertRow(aRow + aNbSubFolders, aDocRoot);
233   //          } else {
234   //            // List of objects under a folder
235   //            if (aRow != -1) {
236   //              int aFolderId = folderId(aObjType, aDoc.get());
237   //              if (aFolderId != -1) {
238   //                QModelIndex aParentFolder = createIndex(aFolderId, 0, aDoc.get());
239   //                insertRow(aRow, aParentFolder);
240   //                emit dataChanged(aParentFolder, aParentFolder);
241   //              }
242   //            }
243   //          }
244   //        } else {
245   //          rebuildDataTree();
246   //          break;
247   //        }
248   //      } else {
249   //        rebuildDataTree();
250   //        break;
251   //      }
252   //    }
253   //  }
254   //  // Deleted object event ***********************
255   //} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
256   //  std::shared_ptr<ModelAPI_ObjectDeletedMessage> aUpdMsg =
257   //      std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
258   //  DocumentPtr aDoc = aUpdMsg->document();
259   //  std::set<std::string> aMsgGroups = aUpdMsg->groups();
260
261   //  /// Sort groups because RootType deletion has to be done after others
262   //  std::string aType = (aDoc == aRootDoc)? aRootType : aSubType;
263   //  std::list<std::string> aGroups;
264   //  std::set<std::string>::const_iterator aSetIt;
265   //  for (aSetIt = aMsgGroups.begin(); aSetIt != aMsgGroups.end(); ++aSetIt) {
266   //    std::string aGroup = (*aSetIt);
267   //    if (aGroup == aType)
268   //      aGroups.push_back(aGroup);
269   //    else
270   //      aGroups.push_front(aGroup);
271   //  }
272
273   //  std::list<std::string>::const_iterator aIt;
274   //  for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) {
275   //    std::string aGroup = (*aIt);
276   //    if (aDoc == aRootDoc) {  // If root objects
277   //      int aRow = aRootDoc->size(aGroup, true);
278   //      if (aGroup == aRootType) {
279   //        // Process root folder
280   //        // remove optimization due to the issue #2456
281   //        //removeRow(aRow + aNbFolders);
282   //        //rebuildBranch(aNbFolders, aRow);
283   //        rebuildDataTree();
284   //      } else if (aGroup == ModelAPI_Folder::group()) {
285   //        rebuildDataTree();
286   //      } else {
287   //        // Process root sub-folder
288   //        int aFolderId = myXMLReader->rootFolderId(aGroup);
289   //        if (aFolderId != -1) {
290   //          QModelIndex aFolderIndex = createIndex(aFolderId, 0, (void*)Q_NULLPTR);
291   //          removeRow(aRow, aFolderIndex);
292   //          //rebuildBranch(0, aRow);
293   //        }
294   //      }
295   //      // Check that some folders could erased
296   //      QStringList aNotEmptyFolders = listOfShowNotEmptyFolders();
297   //      foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
298   //        if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup, true) == 0)) {
299   //          // Appears first object in folder which can not be shown empty
300   //          removeRow(myXMLReader->rootFolderId(aGroup));
301   //          removeShownFolder(aRootDoc, aNotEmptyFolder);
302   //          //rebuildBranch(0, aNbFolders + aDoc->size(myXMLReader->rootType()));
303   //          break;
304   //        }
305   //      }
306   //    } else {
307   //      // Remove row for sub-document
308   //      QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0);
309   //      if (aDocRoot.isValid()) {
310   //        int aRow = aDoc->size(aGroup, true);
311   //        int aNbSubFolders = foldersCount(aDoc.get());
312   //        if (aGroup == aSubType) {
313   //          // List of objects under document root
314   //          removeRow(aRow + aNbSubFolders, aDocRoot);
315   //          rebuildBranch(aNbSubFolders, aRow, aDocRoot);
316   //        } if (aGroup == ModelAPI_Folder::group()) {
317   //          rebuildDataTree();
318   //        } else {
319   //          // List of objects under a folder
320   //          int aFolderId = folderId(aGroup, aDoc.get());
321   //          if (aFolderId != -1) {
322   //            QModelIndex aFolderRoot = createIndex(aFolderId, 0, aDoc.get());
323   //            removeRow(aRow, aFolderRoot);
324   //            //rebuildBranch(0, aRow, aFolderRoot);
325   //          }
326   //        }
327   //        // Check that some folders could disappear
328   //        QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false);
329   //        int aSize = aDoc->size(aGroup, true);
330   //        foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
331   //          if ((aNotEmptyFolder.toStdString() == aGroup) && (aSize == 0)) {
332   //            // Appears first object in folder which can not be shown empty
333   //            removeRow(myXMLReader->subFolderId(aGroup), aDocRoot);
334   //            removeShownFolder(aDoc, aNotEmptyFolder);
335   //            //rebuildBranch(0, aNbSubFolders + aDoc->size(myXMLReader->subType()), aDocRoot);
336   //            break;
337   //          }
338   //        }
339   //      } else {
340   //        rebuildDataTree();
341   //        break;
342   //      }
343   //    }
344   //  }
345   //} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {
346   //  std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
347   //      std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
348   //  std::set<ObjectPtr> aObjects = aUpdMsg->objects();
349
350   //  std::set<ObjectPtr>::const_iterator aIt;
351   //  for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
352   //    ObjectPtr aObject = (*aIt);
353   //    if (aObject->data()->isValid()) {
354   //      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
355   //      if (aFeature.get() && aFeature->firstResult().get()
356   //        && (aFeature->firstResult()->groupName() == ModelAPI_ResultField::group())) {
357   //          ResultFieldPtr aResult =
358   //            std::dynamic_pointer_cast<ModelAPI_ResultField>(aFeature->firstResult());
359   //          QModelIndex aIndex = objectIndex(aResult, 0);
360   //          removeRows(0, aResult->stepsSize(), aIndex);
361   //      } else {
362   //        if (aObject->groupName() == ModelAPI_Folder::group()) {
363   //          rebuildDataTree();
364   //        } else {
365   //          QModelIndex aIndex = objectIndex(aObject, 0);
366   //          if (aIndex.isValid()) {
367   //            emit dataChanged(aIndex, aIndex);
368   //          }
369   //        }
370   //      }
371   //    } else {
372   //      rebuildDataTree();
373   //      break;
374   //    }
375   //  }
376   //} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) {
377   //  std::shared_ptr<ModelAPI_OrderUpdatedMessage> aUpdMsg =
378   //      std::dynamic_pointer_cast<ModelAPI_OrderUpdatedMessage>(theMessage);
379   //  if (aUpdMsg->reordered().get()) {
380   //    DocumentPtr aDoc = aUpdMsg->reordered()->document();
381   //    std::string aGroup = aUpdMsg->reordered()->group();
382
383   //    QModelIndex aParent;
384   //    int aStartId = 0;
385   //    if (aDoc == aRootDoc) {
386   //      // Update a group under root
387   //      if (aGroup == myXMLReader->rootType()) // Update objects under root
388   //        aStartId = foldersCount();
389   //      else // Update objects in folder under root
390   //        aParent = createIndex(folderId(aGroup), 0, (void*)Q_NULLPTR);
391   //    } else {
392   //      // Update a sub-document
393   //      if (aGroup == myXMLReader->subType()) {
394   //        // Update sub-document root
395   //        aParent = findDocumentRootIndex(aDoc.get(), 0);
396   //        aStartId = foldersCount(aDoc.get());
397   //      } else
398   //        // update folder in sub-document
399   //        aParent = createIndex(folderId(aGroup, aDoc.get()), 0, aDoc.get());
400   //    }
401   //    int aChildNb = rowCount(aParent);
402   //    rebuildBranch(aStartId, aChildNb - aStartId, aParent);
403   //  } else {
404   //    rebuildDataTree();
405   //  }
406   //} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
407   //  DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument();
408   //  if (aDoc != aRootDoc) {
409   //    QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0);
410   //    if (aDocRoot.isValid())
411   //      emit dataChanged(aDocRoot, aDocRoot);
412   //    else
413   //      // We have got a new document
414   //      rebuildDataTree();
415   //  }
416   //}
417 }
418
419 //******************************************************
420 void XGUI_DataModel::clear()
421 {
422   beginResetModel();
423   endResetModel();
424 }
425
426 //******************************************************
427 void XGUI_DataModel::rebuildDataTree()
428 {
429   beginResetModel();
430   endResetModel();
431   emit treeRebuilt();
432 }
433
434 //******************************************************
435 ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const
436 {
437   if (theIndex.isValid()) {
438     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
439     return aNode->object();
440   }
441   return ObjectPtr();
442
443   //if (theIndex.internalId() == 0) // this is a folder
444   //  return ObjectPtr();
445   //ModelAPI_Object* aObj = 0;
446   //try {
447   //  aObj = dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theIndex.internalPointer());
448   //} catch(...) {}
449
450   //if (!aObj)
451   //  return ObjectPtr();
452   //if (getSubDocument(aObj)) // the selected index is a folder of sub-document
453   //  return ObjectPtr();
454
455   //return aObj->data()->owner();
456 }
457
458 //******************************************************
459 QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn) const
460 {
461   ModuleBase_ITreeNode* aNode = myRoot->subNode(theObject);
462   if (aNode) {
463     ModuleBase_ITreeNode* aParent = aNode->parent();
464     assert(aParent);
465     return getIndex(aNode, theColumn);
466   }
467   return QModelIndex();
468   //std::string aType = theObject->groupName();
469   //DocumentPtr aDoc = theObject->document();
470   //int aRow = aDoc->index(theObject, true);
471   //if (aRow == -1) {
472   //  // it could be a part of complex object
473   //  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
474   //  if (aFeature.get()) {
475   //    CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature);
476   //    if (aCompFea.get()) {
477   //      for (int i = 0; i < aCompFea->numberOfSubs(true); i++) {
478   //        if (aCompFea->subFeature(i, true) == theObject) {
479   //          aRow = i;
480   //          break;
481   //        }
482   //      }
483   //    }
484   //    int aFRow = -1;
485   //    FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aFRow);
486   //    if (aFolder.get())
487   //      aRow = aFRow;
488   //  } else {
489   //    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
490   //    if (aResult.get()) {
491   //      ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult);
492   //      if (aCompRes.get()) {
493   //        aRow = ModelAPI_Tools::compSolidIndex(aResult);
494   //      }
495   //    }
496   //  }
497   //  if (aRow == -1)
498   //    return QModelIndex();
499   //  else
500   //    return createIndex(aRow, theColumn, theObject.get());
501   //}
502   //SessionPtr aSession = ModelAPI_Session::get();
503   //DocumentPtr aRootDoc = aSession->moduleDocument();
504   //if (aDoc == aRootDoc &&
505   //  ((myXMLReader->rootType() == aType) || (aType == ModelAPI_Folder::group()))) {
506   //  // The object from root document
507   //  aRow += foldersCount();
508   //} else if ((myXMLReader->subType() == aType) || (aType == ModelAPI_Folder::group())) {
509   //  // The object from sub document
510   //  aRow += foldersCount(aDoc.get());
511   //}
512   //return createIndex(aRow, theColumn, theObject.get());
513 }
514
515 //******************************************************
516 QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
517 {
518   if (theIndex.isValid()) {
519     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
520     return aNode->data(theIndex.column(), theRole);
521   }
522   return QVariant();
523
524   //SessionPtr aSession = ModelAPI_Session::get();
525   //DocumentPtr aRootDoc = aSession->moduleDocument();
526   //int aNbFolders = foldersCount();
527   //int theIndexRow = theIndex.row();
528
529   //if (theRole == Qt::DecorationRole) {
530   //  if (theIndex == lastHistoryIndex())
531   //    return QIcon(":pictures/arrow.png");
532   //  else if (theIndex.column() == 0) {
533   //    VisibilityState aState = getVisibilityState(theIndex);
534   //    switch (aState) {
535   //    case NoneState:
536   //      return QIcon();
537   //    case Visible:
538   //      return QIcon(":pictures/eyeopen.png");
539   //    case SemiVisible:
540   //      return QIcon(":pictures/eyemiclosed.png");
541   //    case Hidden:
542   //      return QIcon(":pictures/eyeclosed.png");
543   //    }
544   //  }
545   //}
546
547   ////if (theIndex.column() == 1)
548   //if (theIndex.column() != 1)
549   //  return QVariant();
550
551   //quintptr aParentId = theIndex.internalId();
552   //if (aParentId == 0) { // root folders
553   //  switch (theRole) {
554   //    case Qt::DisplayRole:
555   //      return QString(myXMLReader->rootFolderName(theIndexRow).c_str()) +
556   //        QString(" (%1)").arg(rowCount(theIndex));
557   //    case Qt::DecorationRole:
558   //      return QIcon(myXMLReader->rootFolderIcon(theIndexRow).c_str());
559   //    case Qt::ForegroundRole:
560   //      {
561   //        Qt::ItemFlags aFlags = theIndex.flags();
562   //        if (aFlags == Qt::ItemFlags())
563   //          return QBrush(DISABLED_COLOR);
564   //        if (!aFlags.testFlag(Qt::ItemIsEditable))
565   //          return QBrush(SELECTABLE_COLOR);
566   //      }
567   //      return ACTIVE_COLOR;
568   //  }
569   //} else { // an object or sub-document
570   //  if (theRole == Qt::ForegroundRole) {
571   //    Qt::ItemFlags aFlags = theIndex.flags();
572   //    if (aFlags == Qt::ItemFlags())
573   //      return QBrush(DISABLED_COLOR);
574   //    if (!aFlags.testFlag(Qt::ItemIsEditable))
575   //      return QBrush(SELECTABLE_COLOR);
576   //    return ACTIVE_COLOR;
577   //  }
578
579   //  ModelAPI_Document* aSubDoc = getSubDocument(theIndex.internalPointer());
580   //  if (aSubDoc) { // this is a folder of sub document
581   //    QIntList aMissedIdx = missedFolderIndexes(aSubDoc);
582   //    int aRow = theIndexRow;
583   //    while (aMissedIdx.contains(aRow))
584   //      aRow++;
585   //    if (aRow < myXMLReader->subFoldersNumber()) {
586   //      switch (theRole) {
587   //        case Qt::DisplayRole:
588   //          return QString(myXMLReader->subFolderName(aRow).c_str()) +
589   //            QString(" (%1)").arg(rowCount(theIndex));
590   //        case Qt::DecorationRole:
591   //          return QIcon(myXMLReader->subFolderIcon(aRow).c_str());
592   //      }
593   //    }
594   //  } else {
595   //    ObjectPtr aObj = object(theIndex);
596   //    if (aObj) {
597   //      switch (theRole) {
598   //      case Qt::DisplayRole:
599   //        {
600   //          if (aObj->groupName() == ModelAPI_ResultParameter::group()) {
601   //            ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObj);
602   //            AttributeDoublePtr aValueAttribute =
603   //              aParam->data()->real(ModelAPI_ResultParameter::VALUE());
604   //            QString aVal = QString::number(aValueAttribute->value());
605   //            QString aTitle = QString(aObj->data()->name().c_str());
606   //            return aTitle + " = " + aVal;
607   //          }
608   //          QString aSuffix;
609   //          if (aObj->groupName() == myXMLReader->subType()) {
610   //            ResultPartPtr aPartRes = getPartResult(aObj.get());
611   //            if (aPartRes.get()) {
612   //              if (aPartRes->partDoc().get() == NULL)
613   //                aSuffix = " (Not loaded)";
614   //            }
615   //          }
616   //          return aObj->data()->name().c_str() + aSuffix;
617   //        }
618   //      case Qt::DecorationRole:
619   //        {
620   //          if (aObj->groupName() == ModelAPI_Folder::group())
621   //            return QIcon(":pictures/features_folder.png");
622   //          else
623   //            return ModuleBase_IconFactory::get()->getIcon(aObj);
624   //        }
625   //      }
626   //    } else {
627   //      switch (theRole) {
628   //      case Qt::DisplayRole:
629   //        {
630   //          ModelAPI_ResultField::ModelAPI_FieldStep* aStep =
631   //            dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
632   //            ((ModelAPI_Entity*)theIndex.internalPointer());
633   //          if (aStep) {
634   //            return "Step " + QString::number(aStep->id() + 1) + " " +
635   //              aStep->field()->textLine(aStep->id()).c_str();
636   //          }
637   //        }
638   //        break;
639   //      }
640   //    }
641   //  }
642   //}
643   //return QVariant();
644 }
645
646 //******************************************************
647 QVariant XGUI_DataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
648 {
649   return QVariant();
650 }
651
652 //******************************************************
653 int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
654 {
655   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
656     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
657   return aParentNode->childrenCount();
658
659   //SessionPtr aSession = ModelAPI_Session::get();
660   //if (!aSession->hasModuleDocument())
661   //  return 0;
662   //DocumentPtr aRootDoc = aSession->moduleDocument();
663
664   //if (!theParent.isValid()) {
665   //  // Return number of items in root
666   //  int aNbFolders = foldersCount();
667   //  int aNbItems = 0;
668   //  std::string aType = myXMLReader->rootType();
669   //  if (!aType.empty())
670   //    aNbItems = aRootDoc->size(aType, true);
671   //  return aNbFolders + aNbItems;
672   //}
673
674   //quintptr aId = theParent.internalId();
675   //if (aId == 0) {
676   //  // this is a folder under root
677   //  int aParentPos = theParent.row();
678   //  std::string aType = myXMLReader->rootFolderType(aParentPos);
679   //  return aRootDoc->size(aType);
680   //} else {
681   //  // It is an object which could have children
682   //  ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer());
683   //  if (aDoc) {
684   //    // a folder of sub-document
685   //    QIntList aMissedIdx = missedFolderIndexes(aDoc);
686   //    int aRow = theParent.row();
687   //    while (aMissedIdx.contains(aRow))
688   //      aRow++;
689   //    if (aRow < myXMLReader->subFoldersNumber()) {
690   //      std::string aType = myXMLReader->subFolderType(aRow);
691   //      return aDoc->size(aType);
692   //    }
693   //  } else {
694   //    ModelAPI_Object* aObj =
695   //      dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theParent.internalPointer());
696   //    // Check for Part feature
697   //    ResultPartPtr aPartRes = getPartResult(aObj);
698   //    if (aPartRes.get()) {
699   //      DocumentPtr aSubDoc = aPartRes->partDoc();
700   //      if (!aSubDoc.get())
701   //        return 0;
702
703   //      int aNbSubFolders = foldersCount(aSubDoc.get());
704   //      int aNbSubItems = 0;
705   //      std::string aSubType = myXMLReader->subType();
706   //      if (!aSubType.empty())
707   //        aNbSubItems = aSubDoc->size(aSubType, true);
708   //      return aNbSubItems + aNbSubFolders;
709   //    } else {
710   //      // Check for composite object
711   //      ModelAPI_CompositeFeature* aCompFeature = dynamic_cast<ModelAPI_CompositeFeature*>(aObj);
712   //      if (aCompFeature)
713   //        return aCompFeature->numberOfSubs(true);
714   //      ModelAPI_ResultCompSolid* aCompRes = dynamic_cast<ModelAPI_ResultCompSolid*>(aObj);
715   //      if (aCompRes)
716   //        return aCompRes->numberOfSubs(true);
717   //      ModelAPI_ResultField* aFieldRes = dynamic_cast<ModelAPI_ResultField*>(aObj);
718   //      if (aFieldRes)
719   //        return aFieldRes->stepsSize();
720   //      ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aObj);
721   //      if (aFolder)
722   //        return getNumberOfFolderItems(aFolder);
723   //    }
724   //  }
725   //}
726   //return 0;
727 }
728
729 //******************************************************
730 int XGUI_DataModel::columnCount(const QModelIndex& theParent) const
731 {
732   return 3;
733 }
734
735 //******************************************************
736 QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
737 {
738   int aa = theParent.row();
739   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
740     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
741   ModuleBase_ITreeNode* aSubNode = aParentNode->subNode(theRow);
742   assert(aSubNode);
743   return createIndex(theRow, theColumn, aSubNode);
744
745   //SessionPtr aSession = ModelAPI_Session::get();
746   //DocumentPtr aRootDoc = aSession->moduleDocument();
747   //int aNbFolders = foldersCount();
748
749   //QModelIndex aIndex;
750
751   //if (!theParent.isValid()) {
752   //  if (theRow < aNbFolders) // Return first level folder index
753   //    return createIndex(theRow, theColumn, (void*)Q_NULLPTR);
754   //  else { // return object under root index
755   //    std::string aType = myXMLReader->rootType();
756   //    int aObjId = theRow - aNbFolders;
757   //    if (aObjId < aRootDoc->size(aType, true)) {
758   //      ObjectPtr aObj = aRootDoc->object(aType, aObjId, true);
759   //      aIndex = objectIndex(aObj, theColumn);
760   //    }
761   //  }
762   //} else {
763   //  quintptr aId = theParent.internalId();
764   //  int aParentPos = theParent.row();
765   //  if (aId == 0) { // return object index inside of first level of folders
766   //    std::string aType = myXMLReader->rootFolderType(aParentPos);
767   //    if (theRow < aRootDoc->size(aType)) {
768   //      ObjectPtr aObj = aRootDoc->object(aType, theRow, true);
769   //      aIndex = objectIndex(aObj, theColumn);
770   //    }
771   //  } else {
772   //    // It is an object which could have children
773   //    ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer());
774   //    if (aDoc) {
775   //      // It is a folder of sub-document
776   //      int aParentRow = aParentPos;
777   //      QIntList aMissedIdx = missedFolderIndexes(aDoc);
778   //      while (aMissedIdx.contains(aParentRow))
779   //        aParentRow++;
780   //      if (aParentRow < myXMLReader->subFoldersNumber()) {
781   //        std::string aType = myXMLReader->subFolderType(aParentRow);
782   //        if (theRow < aDoc->size(aType)) {
783   //          ObjectPtr aObj = aDoc->object(aType, theRow);
784   //          aIndex = objectIndex(aObj, theColumn);
785   //        }
786   //      }
787   //    } else {
788   //      ModelAPI_Object* aParentObj =
789   //        dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theParent.internalPointer());
790
791   //      // Check for Part feature
792   //      ResultPartPtr aPartRes = getPartResult(aParentObj);
793   //      if (aPartRes.get()) {
794   //        DocumentPtr aSubDoc = aPartRes->partDoc();
795   //        int aNbSubFolders = foldersCount(aSubDoc.get());
796   //        if (theRow < aNbSubFolders) { // Create a Folder of sub-document
797   //          aIndex = createIndex(theRow, theColumn, aSubDoc.get());
798   //        } else {
799   //          // this is an object under sub document root
800   //          std::string aType = myXMLReader->subType();
801   //          ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders, true);
802   //          aIndex = objectIndex(aObj, theColumn);
803   //        }
804   //      } else {
805   //        // Check for composite object
806   //        ModelAPI_CompositeFeature* aCompFeature =
807   //          dynamic_cast<ModelAPI_CompositeFeature*>(aParentObj);
808   //        if (aCompFeature) {
809   //          aIndex = objectIndex(aCompFeature->subFeature(theRow), theColumn);
810   //        } else {
811   //          ModelAPI_ResultCompSolid* aCompRes =
812   //            dynamic_cast<ModelAPI_ResultCompSolid*>(aParentObj);
813   //          if (aCompRes)
814   //            aIndex = objectIndex(aCompRes->subResult(theRow), theColumn);
815   //          else {
816   //            ModelAPI_ResultField* aFieldRes =
817   //              dynamic_cast<ModelAPI_ResultField*>(aParentObj);
818   //            if (aFieldRes) {
819   //              aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow));
820   //            } else {
821   //              ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aParentObj);
822   //              ObjectPtr aObj = getObjectInFolder(aFolder, theRow);
823   //              if (aObj.get())
824   //                aIndex = objectIndex(aObj, theColumn);
825   //            }
826   //          }
827   //        }
828   //      }
829   //    }
830   //  }
831   //}
832   //return aIndex;
833 }
834
835 //******************************************************
836 //static QModelIndex MYLastDeleted;
837 QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
838 {
839   if (theIndex.isValid()) {
840     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
841     return getParentIndex(aNode, 1);
842   }
843   return QModelIndex();
844
845   //if (!theIndex.isValid())
846   //  return QModelIndex();
847   //// To avoid additional request about index which was already deleted
848   //if (theIndex == MYLastDeleted)
849   //  return QModelIndex();
850
851   //SessionPtr aSession = ModelAPI_Session::get();
852   //quintptr aId = theIndex.internalId();
853   //if (aId != 0) { // The object is not a root folder
854   //  ModelAPI_Document* aDoc = getSubDocument(theIndex.internalPointer());
855   //  if (aDoc) {
856   //    // It is a folder of sub-document
857   //    return findDocumentRootIndex(aDoc);
858   //  }
859   //  ObjectPtr aObj = object(theIndex);
860   //  if (!aObj.get()) {
861   //    // It can be a step of a field
862   //    ModelAPI_ResultField::ModelAPI_FieldStep* aStep = 0;
863   //    try {
864   //      aStep = dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
865   //              ((ModelAPI_Entity*)theIndex.internalPointer());
866   //    } catch(...) {}
867
868   //    if (aStep) {
869   //      ModelAPI_ResultField* aField = aStep->field();
870   //      DocumentPtr aDoc = aSession->activeDocument();
871   //      ObjectPtr aFld;
872   //      for(int i = 0; i < aDoc->size(ModelAPI_ResultField::group()); i++) {
873   //        aFld = aDoc->object(ModelAPI_ResultField::group(), i);
874   //        if (aFld.get() == aField)
875   //          return objectIndex(aFld);
876   //      }
877   //    }
878   //    // To avoid additional request about index which was already deleted
879   //    // If deleted it causes a crash on delete object from Part
880   //    MYLastDeleted = theIndex;
881   //    return QModelIndex();
882   //  }
883   //  // Check is it object a sub-object of a complex object
884   //  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
885   //  if (aFeature.get()) {
886   //    CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature);
887   //    if (aCompFea.get()) {
888   //      return objectIndex(aCompFea);
889   //    }
890   //    DocumentPtr aDoc = aFeature->document();
891   //    int aRow;
892   //    FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aRow);
893   //    if (aFolder.get())
894   //      return objectIndex(aFolder);
895   //  }
896   //  ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
897   //  if (aResult.get()) {
898   //    ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult);
899   //    if (aCompRes.get()) {
900   //      return objectIndex(aCompRes);
901   //    }
902   //  }
903   //  // Use as ordinary object
904   //  std::string aType = aObj->groupName();
905   //  DocumentPtr aRootDoc = aSession->moduleDocument();
906   //  DocumentPtr aSubDoc = aObj->document();
907   //  if (aSubDoc == aRootDoc) {
908   //    if ((aType == myXMLReader->rootType()) || (aType == ModelAPI_Folder::group()))
909   //      return QModelIndex();
910   //    else {
911   //      // return first level of folder index
912   //      int aFolderId = myXMLReader->rootFolderId(aType);
913   //      // Items in a one row must have the same parent
914   //      return createIndex(aFolderId, 1, (void*)Q_NULLPTR);
915   //    }
916   //  } else {
917   //    if ((aType == myXMLReader->subType()) || (aType == ModelAPI_Folder::group()))
918   //      return findDocumentRootIndex(aSubDoc.get());
919   //    else {
920   //      // return first level of folder index
921   //      int aFolderId = folderId(aType, aSubDoc.get());
922   //      // Items in a one row must have the same parent
923   //      return createIndex(aFolderId, 1, aSubDoc.get());
924   //    }
925   //  }
926   //}
927 }
928
929 //******************************************************
930 bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const
931 {
932   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
933     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
934   return aParentNode->childrenCount() > 0;
935 }
936
937 //******************************************************
938 bool XGUI_DataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
939 {
940   beginInsertRows(theParent, theRow, theRow + theCount - 1);
941   endInsertRows();
942   return true;
943 }
944
945 //******************************************************
946 bool XGUI_DataModel::removeRows(int theRow, int theCount, const QModelIndex& theParent)
947 {
948   beginRemoveRows(theParent, theRow, theRow + theCount - 1);
949   endRemoveRows();
950   return true;
951 }
952
953 //******************************************************
954 Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const
955 {
956   if (theIndex.isValid()) {
957     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
958     return aNode->flags(theIndex.column());
959   }
960   return Qt::ItemFlags();
961
962   //quintptr aIt = theIndex.internalId();
963   //ModelAPI_Object* aObj = 0;
964   //ModelAPI_Document* aDoc = 0;
965   //SessionPtr aSession = ModelAPI_Session::get();
966   //DocumentPtr aActiveDoc = aSession->activeDocument();
967
968   //Qt::ItemFlags aNullFlag;
969   //Qt::ItemFlags aDefaultFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
970   //Qt::ItemFlags aEditingFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
971
972
973   //if (aIt == 0) {
974   //  // Folders under root
975   //  DocumentPtr aRootDoc = aSession->moduleDocument();
976   //  if (aRootDoc != aActiveDoc)
977   //    return aDefaultFlag;
978   //} else {
979   //  aDoc = getSubDocument(theIndex.internalPointer());
980   //  if (!aDoc)
981   //    aObj = dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theIndex.internalPointer());
982   //}
983
984   //if (aObj) {
985   //  // An object
986   //  if (aObj->isDisabled())
987   //    return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag;
988
989   //  if (aSession->moduleDocument() != aObj->document())
990   //    if (aActiveDoc != aObj->document())
991   //      return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag;
992
993   //  bool isCompositeSub = false;
994   //  // An object which is sub-object of a composite object can not be accessible in column 2
995   //  if (theIndex.column() == 2) {
996   //    ObjectPtr aObjPtr = aObj->data()->owner();
997   //    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObjPtr);
998   //    if (aFeature.get()) {
999   //      CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature);
1000   //      if (aCompFea.get())
1001   //        isCompositeSub = true;
1002   //    } else {
1003   //      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObjPtr);
1004   //      if (aResult.get()) {
1005   //        ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult);
1006   //        if (aCompRes.get())
1007   //          isCompositeSub = true;
1008   //      }
1009   //    }
1010   //  }
1011   //  if (isCompositeSub)
1012   //    return Qt::ItemIsSelectable;
1013
1014   //  if (aObj->document() != aActiveDoc) {
1015   //    // The object could be a root of sub-tree
1016   //    ResultPartPtr aPartRes = getPartResult(aObj);
1017   //    if (aPartRes.get()) {
1018   //      if (aPartRes->partDoc() == aActiveDoc)
1019   //        return aEditingFlag;
1020   //    }
1021   //    return aDefaultFlag;
1022   //  }
1023   //} else if (aDoc) {
1024   //  // A folder under sub-document
1025   //  if (aActiveDoc.get() != aDoc)
1026   //    return aNullFlag;
1027   //}
1028   //return aEditingFlag;
1029 }
1030
1031 //******************************************************
1032 //QModelIndex
1033 //  XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc, int aColumn) const
1034 //{
1035 //  SessionPtr aSession = ModelAPI_Session::get();
1036 //  DocumentPtr aRootDoc = aSession->moduleDocument();
1037 //  if (myXMLReader->isAttachToResult()) { // If document is attached to result
1038 //    int aNb = aRootDoc->size(ModelAPI_ResultPart::group());
1039 //    ObjectPtr aObj;
1040 //    ResultPartPtr aPartRes;
1041 //    for (int i = 0; i < aNb; i++) {
1042 //      aObj = aRootDoc->object(ModelAPI_ResultPart::group(), i);
1043 //      aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
1044 //      if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
1045 //        int aRow = i;
1046 //        if (myXMLReader->rootType() == ModelAPI_Feature::group()) {
1047 //          aRow += foldersCount();
1048 //        }
1049 //        return createIndex(aRow, aColumn, aObj.get());
1050 //      }
1051 //    }
1052 //  } else { // If document is attached to feature
1053 //    int aNb = aRootDoc->size(ModelAPI_Feature::group(), true);
1054 //    ObjectPtr aObj;
1055 //    ResultPartPtr aPartRes;
1056 //    for (int i = 0; i < aNb; i++) {
1057 //      aObj = aRootDoc->object(ModelAPI_Feature::group(), i, true);
1058 //      aPartRes = getPartResult(aObj.get());
1059 //      if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
1060 //        int aRow = i;
1061 //        if (myXMLReader->rootType() == ModelAPI_Feature::group())
1062 //          aRow += foldersCount();
1063 //        return createIndex(aRow, aColumn, aObj.get());
1064 //      }
1065 //    }
1066 //  }
1067 //  return QModelIndex();
1068 //}
1069
1070 //******************************************************
1071 QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) const
1072 {
1073   SessionPtr aSession = ModelAPI_Session::get();
1074   DocumentPtr aRootDoc = aSession->moduleDocument();
1075   if (theDoc == aRootDoc)
1076     return QModelIndex();
1077   else {
1078     ModuleBase_ITreeNode* aDocNode = 0;
1079     foreach(ModuleBase_ITreeNode* aNode, myRoot->children()) {
1080       if (aNode->document() == theDoc) {
1081         aDocNode = aNode;
1082         break;
1083       }
1084     }
1085     if (aDocNode)
1086       return getIndex(aDocNode, theColumn);
1087   }
1088   return QModelIndex();
1089   //  return findDocumentRootIndex(theDoc.get(), theColumn);
1090 }
1091
1092 //******************************************************
1093 //int XGUI_DataModel::foldersCount(ModelAPI_Document* theDoc) const
1094 //{
1095 //  int aNb = 0;
1096 //  SessionPtr aSession = ModelAPI_Session::get();
1097 //  DocumentPtr aRootDoc = aSession->moduleDocument();
1098 //  if ((theDoc == 0) || (theDoc == aRootDoc.get())) {
1099 //    for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) {
1100 //      if (myXMLReader->rootShowEmpty(i))
1101 //        aNb++;
1102 //      else {
1103 //        if (aRootDoc->size(myXMLReader->rootFolderType(i)) > 0)
1104 //          aNb++;
1105 //      }
1106 //    }
1107 //  } else {
1108 //    for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) {
1109 //      if (myXMLReader->subShowEmpty(i))
1110 //        aNb++;
1111 //      else {
1112 //        if (theDoc->size(myXMLReader->subFolderType(i)) > 0)
1113 //          aNb++;
1114 //      }
1115 //    }
1116 //  }
1117 //  return aNb;
1118 //}
1119
1120
1121 //******************************************************
1122 //QIntList XGUI_DataModel::missedFolderIndexes(ModelAPI_Document* theDoc) const
1123 //{
1124 //  QIntList aList;
1125 //  SessionPtr aSession = ModelAPI_Session::get();
1126 //  DocumentPtr aRootDoc = aSession->moduleDocument();
1127 //  if ((theDoc == 0) || (theDoc == aRootDoc.get())) {
1128 //    for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) {
1129 //      if (!myXMLReader->rootShowEmpty(i)) {
1130 //        if (aRootDoc->size(myXMLReader->rootFolderType(i)) == 0)
1131 //          aList.append(i);
1132 //      }
1133 //    }
1134 //  } else {
1135 //    for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) {
1136 //      if (!myXMLReader->subShowEmpty(i)) {
1137 //        if (theDoc->size(myXMLReader->subFolderType(i)) == 0)
1138 //          aList.append(i);
1139 //      }
1140 //    }
1141 //  }
1142 //  return aList;
1143 //}
1144
1145
1146 //******************************************************
1147 //QStringList XGUI_DataModel::listOfShowNotEmptyFolders(bool fromRoot) const
1148 //{
1149 //  QStringList aResult;
1150 //  if (fromRoot) {
1151 //    for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) {
1152 //      if (!myXMLReader->rootShowEmpty(i))
1153 //        aResult << myXMLReader->rootFolderType(i).c_str();
1154 //    }
1155 //  } else {
1156 //    for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) {
1157 //      if (!myXMLReader->subShowEmpty(i))
1158 //        aResult << myXMLReader->subFolderType(i).c_str();
1159 //    }
1160 //  }
1161 //  return aResult;
1162 //}
1163
1164 //******************************************************
1165 //QModelIndex XGUI_DataModel::lastHistoryIndex() const
1166 //{
1167   //SessionPtr aSession = ModelAPI_Session::get();
1168   //DocumentPtr aCurDoc = aSession->activeDocument();
1169   //FeaturePtr aFeature = aCurDoc->currentFeature(true);
1170   //if (aFeature.get()) {
1171   //  QModelIndex aInd = objectIndex(aFeature);
1172   //  return createIndex(aInd.row(), 2, aInd.internalPointer());
1173   //} else {
1174   //  if (aCurDoc == aSession->moduleDocument())
1175   //    return createIndex(foldersCount() - 1, 2, -1);
1176   //  else
1177   //    return createIndex(foldersCount(aCurDoc.get()) - 1, 2, aCurDoc.get());
1178   //}
1179 //}
1180
1181 //******************************************************
1182 bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex)
1183 {
1184   return false;
1185   //return getVisibilityState(theIndex) == Hidden;
1186 }
1187
1188 //******************************************************
1189 //int XGUI_DataModel::folderId(std::string theType, ModelAPI_Document* theDoc) const
1190 //{
1191 //  SessionPtr aSession = ModelAPI_Session::get();
1192 //  ModelAPI_Document* aDoc = theDoc;
1193 //  if (aDoc == 0)
1194 //    aDoc = aSession->moduleDocument().get();
1195 //
1196 //  bool aUseSubDoc = (aDoc != aSession->moduleDocument().get());
1197 //
1198 //  int aRes = -1;
1199 //  if (aUseSubDoc) {
1200 //    int aId = myXMLReader->subFolderId(theType);
1201 //    aRes = aId;
1202 //    for (int i = 0; i < aId; i++) {
1203 //      if (!myXMLReader->subShowEmpty(i)) {
1204 //        if (aDoc->size(myXMLReader->subFolderType(i)) == 0)
1205 //          aRes--;
1206 //      }
1207 //    }
1208 //  } else {
1209 //    int aId = myXMLReader->rootFolderId(theType);
1210 //    aRes = aId;
1211 //    for (int i = 0; i < aId; i++) {
1212 //      if (!myXMLReader->rootShowEmpty(i)) {
1213 //        if (aDoc->size(myXMLReader->rootFolderType(i)) == 0)
1214 //          aRes--;
1215 //      }
1216 //    }
1217 //  }
1218 //  return aRes;
1219 //}
1220
1221 //******************************************************
1222 //void XGUI_DataModel::rebuildBranch(int theRow, int theCount, const QModelIndex& theParent)
1223 //{
1224 //  if (theCount > 0) {
1225 //    removeRows(theRow, theCount, theParent);
1226 //    insertRows(theRow, theCount, theParent);
1227 //  }
1228 //}
1229
1230 //******************************************************
1231 //bool XGUI_DataModel::blockEventsProcessing(const bool theState)
1232 //{
1233 //  bool aPreviousState = myIsEventsProcessingBlocked;
1234 //  myIsEventsProcessingBlocked = theState;
1235 //  return aPreviousState;
1236 //}
1237
1238 //******************************************************
1239 //XGUI_DataModel::VisibilityState
1240 //  XGUI_DataModel::getVisibilityState(const QModelIndex& theIndex) const
1241 //{
1242 //  Qt::ItemFlags aFlags = theIndex.flags();
1243 //  if (aFlags == Qt::ItemFlags())
1244 //    return NoneState;
1245 //
1246 //  ObjectPtr aObj = object(theIndex);
1247 //  if (aObj.get()) {
1248 //    if (aObj->groupName() == ModelAPI_ResultParameter::group())
1249 //      return NoneState;
1250 //    ResultPtr aResObj = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
1251 //    if (aResObj.get()) {
1252 //      XGUI_Displayer* aDisplayer = myWorkshop->displayer();
1253 //      ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResObj);
1254 //      if (aCompRes.get()) {
1255 //        VisibilityState aState = aCompRes->numberOfSubs(true) == 0 ?
1256 //          (aDisplayer->isVisible(aCompRes)? Visible : Hidden) : NoneState;
1257 //        for (int i = 0; i < aCompRes->numberOfSubs(true); i++) {
1258 //          ResultPtr aSubRes = aCompRes->subResult(i, true);
1259 //          VisibilityState aS = aDisplayer->isVisible(aSubRes)? Visible : Hidden;
1260 //          if (aState == NoneState)
1261 //            aState = aS;
1262 //          else if (aState != aS) {
1263 //            aState = SemiVisible;
1264 //            break;
1265 //          }
1266 //        }
1267 //        return aState;
1268 //      } else {
1269 //        if (aDisplayer->isVisible(aResObj))
1270 //          return Visible;
1271 //        else
1272 //          return Hidden;
1273 //      }
1274 //    }
1275 //  }
1276 //  return NoneState;
1277 //}
1278
1279
1280 //int XGUI_DataModel::getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const
1281 //{
1282 //  DocumentPtr aDoc = theFolder->document();
1283 //
1284 //  FeaturePtr aFirstFeatureInFolder;
1285 //  AttributeReferencePtr aFirstFeatAttr =
1286 //      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
1287 //  if (aFirstFeatAttr)
1288 //    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
1289 //  if (!aFirstFeatureInFolder.get())
1290 //    return 0;
1291 //
1292 //  FeaturePtr aLastFeatureInFolder;
1293 //  AttributeReferencePtr aLastFeatAttr =
1294 //      theFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
1295 //  if (aLastFeatAttr)
1296 //    aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
1297 //  if (!aLastFeatureInFolder.get())
1298 //    return 0;
1299 //
1300 //  int aFirst = aDoc->index(aFirstFeatureInFolder);
1301 //  int aLast = aDoc->index(aLastFeatureInFolder);
1302 //  return aLast - aFirst + 1;
1303 //}
1304
1305 //ObjectPtr XGUI_DataModel::getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const
1306 //{
1307 //  DocumentPtr aDoc = theFolder->document();
1308 //
1309 //  FeaturePtr aFirstFeatureInFolder;
1310 //  AttributeReferencePtr aFirstFeatAttr =
1311 //      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
1312 //  if (aFirstFeatAttr)
1313 //    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
1314 //  if (!aFirstFeatureInFolder.get())
1315 //    return ObjectPtr();
1316 //
1317 //  int aFirst = aDoc->index(aFirstFeatureInFolder);
1318 //  return aDoc->object(ModelAPI_Feature::group(), aFirst + theId);
1319 //}
1320
1321 bool XGUI_DataModel::hasIndex(const QModelIndex& theIndex) const
1322 {
1323   ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
1324   return myRoot->hasSubNode(aNode);
1325 }
1326
1327 QModelIndex XGUI_DataModel::getParentIndex(ModuleBase_ITreeNode* theNode, int thCol) const
1328 {
1329   ModuleBase_ITreeNode* aParent = theNode->parent();
1330   if (aParent == myRoot) {
1331     return QModelIndex();
1332   } else {
1333     return getIndex(aParent, thCol);
1334   }
1335 }
1336
1337 QModelIndex XGUI_DataModel::getIndex(ModuleBase_ITreeNode* theNode, int thCol) const
1338 {
1339   int aRow = theNode->parent()->nodeRow(theNode);
1340   return createIndex(aRow, 0, theNode);
1341 }