]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_DataModel.cpp
Salome HOME
Improvement of the structure
[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       if ((*aIt)->isInHistory())
122         aCreated.append(*aIt);
123     }
124     QTreeNodesList aNodes = myRoot->objectCreated(aCreated);
125     ModuleBase_ITreeNode* aParent;
126     int aRow = 0;
127     QModelIndex aParentIndex;
128     foreach(ModuleBase_ITreeNode* aNode, aNodes) {
129       aParent = aNode->parent();
130       aRow = aParent->nodeRow(aNode);
131       aParentIndex = getParentIndex(aNode, 0);
132       insertRows(aRow, 1, aParentIndex);
133     }
134   }
135   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
136       std::shared_ptr<ModelAPI_ObjectDeletedMessage> aUpdMsg =
137           std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
138       DocumentPtr aDoc = aUpdMsg->document();
139       std::set<std::string> aMsgGroups = aUpdMsg->groups();
140       std::set<std::string>::const_iterator aIt;
141       for (aIt = aMsgGroups.cbegin(); aIt != aMsgGroups.cend(); aIt++)
142         QTreeNodesList aList = myRoot->objectsDeleted(aDoc, (*aIt).c_str());
143       rebuildDataTree();
144   }
145   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) {
146     std::shared_ptr<ModelAPI_OrderUpdatedMessage> aUpdMsg =
147       std::dynamic_pointer_cast<ModelAPI_OrderUpdatedMessage>(theMessage);
148     if (aUpdMsg->reordered().get()) {
149       DocumentPtr aDoc = aUpdMsg->reordered()->document();
150       std::string aGroup = aUpdMsg->reordered()->group();
151       ModuleBase_ITreeNode* aNode = myRoot->findParent(aDoc, aGroup.c_str());
152       if (aNode) {
153         aNode->update();
154         updateSubTree(aNode);
155       }
156     }
157   }
158   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
159     DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument();
160     ModuleBase_ITreeNode* aRoot = myRoot->findRoot(aDoc);
161     if (aRoot) {
162       updateSubTree(aRoot);
163     }
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     return getIndex(aNode, theColumn);
464   }
465   return QModelIndex();
466
467   //std::string aType = theObject->groupName();
468   //DocumentPtr aDoc = theObject->document();
469   //int aRow = aDoc->index(theObject, true);
470   //if (aRow == -1) {
471   //  // it could be a part of complex object
472   //  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
473   //  if (aFeature.get()) {
474   //    CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature);
475   //    if (aCompFea.get()) {
476   //      for (int i = 0; i < aCompFea->numberOfSubs(true); i++) {
477   //        if (aCompFea->subFeature(i, true) == theObject) {
478   //          aRow = i;
479   //          break;
480   //        }
481   //      }
482   //    }
483   //    int aFRow = -1;
484   //    FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aFRow);
485   //    if (aFolder.get())
486   //      aRow = aFRow;
487   //  } else {
488   //    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
489   //    if (aResult.get()) {
490   //      ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult);
491   //      if (aCompRes.get()) {
492   //        aRow = ModelAPI_Tools::compSolidIndex(aResult);
493   //      }
494   //    }
495   //  }
496   //  if (aRow == -1)
497   //    return QModelIndex();
498   //  else
499   //    return createIndex(aRow, theColumn, theObject.get());
500   //}
501   //SessionPtr aSession = ModelAPI_Session::get();
502   //DocumentPtr aRootDoc = aSession->moduleDocument();
503   //if (aDoc == aRootDoc &&
504   //  ((myXMLReader->rootType() == aType) || (aType == ModelAPI_Folder::group()))) {
505   //  // The object from root document
506   //  aRow += foldersCount();
507   //} else if ((myXMLReader->subType() == aType) || (aType == ModelAPI_Folder::group())) {
508   //  // The object from sub document
509   //  aRow += foldersCount(aDoc.get());
510   //}
511   //return createIndex(aRow, theColumn, theObject.get());
512 }
513
514 //******************************************************
515 QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
516 {
517   if (theIndex.isValid()) {
518     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
519     return aNode->data(theIndex.column(), theRole);
520   }
521   return QVariant();
522
523   //SessionPtr aSession = ModelAPI_Session::get();
524   //DocumentPtr aRootDoc = aSession->moduleDocument();
525   //int aNbFolders = foldersCount();
526   //int theIndexRow = theIndex.row();
527
528   //if (theRole == Qt::DecorationRole) {
529   //  if (theIndex == lastHistoryIndex())
530   //    return QIcon(":pictures/arrow.png");
531   //  else if (theIndex.column() == 0) {
532   //    VisibilityState aState = getVisibilityState(theIndex);
533   //    switch (aState) {
534   //    case NoneState:
535   //      return QIcon();
536   //    case Visible:
537   //      return QIcon(":pictures/eyeopen.png");
538   //    case SemiVisible:
539   //      return QIcon(":pictures/eyemiclosed.png");
540   //    case Hidden:
541   //      return QIcon(":pictures/eyeclosed.png");
542   //    }
543   //  }
544   //}
545
546   ////if (theIndex.column() == 1)
547   //if (theIndex.column() != 1)
548   //  return QVariant();
549
550   //quintptr aParentId = theIndex.internalId();
551   //if (aParentId == 0) { // root folders
552   //  switch (theRole) {
553   //    case Qt::DisplayRole:
554   //      return QString(myXMLReader->rootFolderName(theIndexRow).c_str()) +
555   //        QString(" (%1)").arg(rowCount(theIndex));
556   //    case Qt::DecorationRole:
557   //      return QIcon(myXMLReader->rootFolderIcon(theIndexRow).c_str());
558   //    case Qt::ForegroundRole:
559   //      {
560   //        Qt::ItemFlags aFlags = theIndex.flags();
561   //        if (aFlags == Qt::ItemFlags())
562   //          return QBrush(DISABLED_COLOR);
563   //        if (!aFlags.testFlag(Qt::ItemIsEditable))
564   //          return QBrush(SELECTABLE_COLOR);
565   //      }
566   //      return ACTIVE_COLOR;
567   //  }
568   //} else { // an object or sub-document
569   //  if (theRole == Qt::ForegroundRole) {
570   //    Qt::ItemFlags aFlags = theIndex.flags();
571   //    if (aFlags == Qt::ItemFlags())
572   //      return QBrush(DISABLED_COLOR);
573   //    if (!aFlags.testFlag(Qt::ItemIsEditable))
574   //      return QBrush(SELECTABLE_COLOR);
575   //    return ACTIVE_COLOR;
576   //  }
577
578   //  ModelAPI_Document* aSubDoc = getSubDocument(theIndex.internalPointer());
579   //  if (aSubDoc) { // this is a folder of sub document
580   //    QIntList aMissedIdx = missedFolderIndexes(aSubDoc);
581   //    int aRow = theIndexRow;
582   //    while (aMissedIdx.contains(aRow))
583   //      aRow++;
584   //    if (aRow < myXMLReader->subFoldersNumber()) {
585   //      switch (theRole) {
586   //        case Qt::DisplayRole:
587   //          return QString(myXMLReader->subFolderName(aRow).c_str()) +
588   //            QString(" (%1)").arg(rowCount(theIndex));
589   //        case Qt::DecorationRole:
590   //          return QIcon(myXMLReader->subFolderIcon(aRow).c_str());
591   //      }
592   //    }
593   //  } else {
594   //    ObjectPtr aObj = object(theIndex);
595   //    if (aObj) {
596   //      switch (theRole) {
597   //      case Qt::DisplayRole:
598   //        {
599   //          if (aObj->groupName() == ModelAPI_ResultParameter::group()) {
600   //            ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObj);
601   //            AttributeDoublePtr aValueAttribute =
602   //              aParam->data()->real(ModelAPI_ResultParameter::VALUE());
603   //            QString aVal = QString::number(aValueAttribute->value());
604   //            QString aTitle = QString(aObj->data()->name().c_str());
605   //            return aTitle + " = " + aVal;
606   //          }
607   //          QString aSuffix;
608   //          if (aObj->groupName() == myXMLReader->subType()) {
609   //            ResultPartPtr aPartRes = getPartResult(aObj.get());
610   //            if (aPartRes.get()) {
611   //              if (aPartRes->partDoc().get() == NULL)
612   //                aSuffix = " (Not loaded)";
613   //            }
614   //          }
615   //          return aObj->data()->name().c_str() + aSuffix;
616   //        }
617   //      case Qt::DecorationRole:
618   //        {
619   //          if (aObj->groupName() == ModelAPI_Folder::group())
620   //            return QIcon(":pictures/features_folder.png");
621   //          else
622   //            return ModuleBase_IconFactory::get()->getIcon(aObj);
623   //        }
624   //      }
625   //    } else {
626   //      switch (theRole) {
627   //      case Qt::DisplayRole:
628   //        {
629   //          ModelAPI_ResultField::ModelAPI_FieldStep* aStep =
630   //            dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
631   //            ((ModelAPI_Entity*)theIndex.internalPointer());
632   //          if (aStep) {
633   //            return "Step " + QString::number(aStep->id() + 1) + " " +
634   //              aStep->field()->textLine(aStep->id()).c_str();
635   //          }
636   //        }
637   //        break;
638   //      }
639   //    }
640   //  }
641   //}
642   //return QVariant();
643 }
644
645 //******************************************************
646 QVariant XGUI_DataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
647 {
648   return QVariant();
649 }
650
651 //******************************************************
652 int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
653 {
654   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
655     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
656   return aParentNode->childrenCount();
657
658   //SessionPtr aSession = ModelAPI_Session::get();
659   //if (!aSession->hasModuleDocument())
660   //  return 0;
661   //DocumentPtr aRootDoc = aSession->moduleDocument();
662
663   //if (!theParent.isValid()) {
664   //  // Return number of items in root
665   //  int aNbFolders = foldersCount();
666   //  int aNbItems = 0;
667   //  std::string aType = myXMLReader->rootType();
668   //  if (!aType.empty())
669   //    aNbItems = aRootDoc->size(aType, true);
670   //  return aNbFolders + aNbItems;
671   //}
672
673   //quintptr aId = theParent.internalId();
674   //if (aId == 0) {
675   //  // this is a folder under root
676   //  int aParentPos = theParent.row();
677   //  std::string aType = myXMLReader->rootFolderType(aParentPos);
678   //  return aRootDoc->size(aType);
679   //} else {
680   //  // It is an object which could have children
681   //  ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer());
682   //  if (aDoc) {
683   //    // a folder of sub-document
684   //    QIntList aMissedIdx = missedFolderIndexes(aDoc);
685   //    int aRow = theParent.row();
686   //    while (aMissedIdx.contains(aRow))
687   //      aRow++;
688   //    if (aRow < myXMLReader->subFoldersNumber()) {
689   //      std::string aType = myXMLReader->subFolderType(aRow);
690   //      return aDoc->size(aType);
691   //    }
692   //  } else {
693   //    ModelAPI_Object* aObj =
694   //      dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theParent.internalPointer());
695   //    // Check for Part feature
696   //    ResultPartPtr aPartRes = getPartResult(aObj);
697   //    if (aPartRes.get()) {
698   //      DocumentPtr aSubDoc = aPartRes->partDoc();
699   //      if (!aSubDoc.get())
700   //        return 0;
701
702   //      int aNbSubFolders = foldersCount(aSubDoc.get());
703   //      int aNbSubItems = 0;
704   //      std::string aSubType = myXMLReader->subType();
705   //      if (!aSubType.empty())
706   //        aNbSubItems = aSubDoc->size(aSubType, true);
707   //      return aNbSubItems + aNbSubFolders;
708   //    } else {
709   //      // Check for composite object
710   //      ModelAPI_CompositeFeature* aCompFeature = dynamic_cast<ModelAPI_CompositeFeature*>(aObj);
711   //      if (aCompFeature)
712   //        return aCompFeature->numberOfSubs(true);
713   //      ModelAPI_ResultCompSolid* aCompRes = dynamic_cast<ModelAPI_ResultCompSolid*>(aObj);
714   //      if (aCompRes)
715   //        return aCompRes->numberOfSubs(true);
716   //      ModelAPI_ResultField* aFieldRes = dynamic_cast<ModelAPI_ResultField*>(aObj);
717   //      if (aFieldRes)
718   //        return aFieldRes->stepsSize();
719   //      ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aObj);
720   //      if (aFolder)
721   //        return getNumberOfFolderItems(aFolder);
722   //    }
723   //  }
724   //}
725   //return 0;
726 }
727
728 //******************************************************
729 int XGUI_DataModel::columnCount(const QModelIndex& theParent) const
730 {
731   return 3;
732 }
733
734 //******************************************************
735 QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
736 {
737   int aa = theParent.row();
738   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
739     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
740   ModuleBase_ITreeNode* aSubNode = aParentNode->subNode(theRow);
741   assert(aSubNode);
742   return createIndex(theRow, theColumn, aSubNode);
743
744   //SessionPtr aSession = ModelAPI_Session::get();
745   //DocumentPtr aRootDoc = aSession->moduleDocument();
746   //int aNbFolders = foldersCount();
747
748   //QModelIndex aIndex;
749
750   //if (!theParent.isValid()) {
751   //  if (theRow < aNbFolders) // Return first level folder index
752   //    return createIndex(theRow, theColumn, (void*)Q_NULLPTR);
753   //  else { // return object under root index
754   //    std::string aType = myXMLReader->rootType();
755   //    int aObjId = theRow - aNbFolders;
756   //    if (aObjId < aRootDoc->size(aType, true)) {
757   //      ObjectPtr aObj = aRootDoc->object(aType, aObjId, true);
758   //      aIndex = objectIndex(aObj, theColumn);
759   //    }
760   //  }
761   //} else {
762   //  quintptr aId = theParent.internalId();
763   //  int aParentPos = theParent.row();
764   //  if (aId == 0) { // return object index inside of first level of folders
765   //    std::string aType = myXMLReader->rootFolderType(aParentPos);
766   //    if (theRow < aRootDoc->size(aType)) {
767   //      ObjectPtr aObj = aRootDoc->object(aType, theRow, true);
768   //      aIndex = objectIndex(aObj, theColumn);
769   //    }
770   //  } else {
771   //    // It is an object which could have children
772   //    ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer());
773   //    if (aDoc) {
774   //      // It is a folder of sub-document
775   //      int aParentRow = aParentPos;
776   //      QIntList aMissedIdx = missedFolderIndexes(aDoc);
777   //      while (aMissedIdx.contains(aParentRow))
778   //        aParentRow++;
779   //      if (aParentRow < myXMLReader->subFoldersNumber()) {
780   //        std::string aType = myXMLReader->subFolderType(aParentRow);
781   //        if (theRow < aDoc->size(aType)) {
782   //          ObjectPtr aObj = aDoc->object(aType, theRow);
783   //          aIndex = objectIndex(aObj, theColumn);
784   //        }
785   //      }
786   //    } else {
787   //      ModelAPI_Object* aParentObj =
788   //        dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theParent.internalPointer());
789
790   //      // Check for Part feature
791   //      ResultPartPtr aPartRes = getPartResult(aParentObj);
792   //      if (aPartRes.get()) {
793   //        DocumentPtr aSubDoc = aPartRes->partDoc();
794   //        int aNbSubFolders = foldersCount(aSubDoc.get());
795   //        if (theRow < aNbSubFolders) { // Create a Folder of sub-document
796   //          aIndex = createIndex(theRow, theColumn, aSubDoc.get());
797   //        } else {
798   //          // this is an object under sub document root
799   //          std::string aType = myXMLReader->subType();
800   //          ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders, true);
801   //          aIndex = objectIndex(aObj, theColumn);
802   //        }
803   //      } else {
804   //        // Check for composite object
805   //        ModelAPI_CompositeFeature* aCompFeature =
806   //          dynamic_cast<ModelAPI_CompositeFeature*>(aParentObj);
807   //        if (aCompFeature) {
808   //          aIndex = objectIndex(aCompFeature->subFeature(theRow), theColumn);
809   //        } else {
810   //          ModelAPI_ResultCompSolid* aCompRes =
811   //            dynamic_cast<ModelAPI_ResultCompSolid*>(aParentObj);
812   //          if (aCompRes)
813   //            aIndex = objectIndex(aCompRes->subResult(theRow), theColumn);
814   //          else {
815   //            ModelAPI_ResultField* aFieldRes =
816   //              dynamic_cast<ModelAPI_ResultField*>(aParentObj);
817   //            if (aFieldRes) {
818   //              aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow));
819   //            } else {
820   //              ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aParentObj);
821   //              ObjectPtr aObj = getObjectInFolder(aFolder, theRow);
822   //              if (aObj.get())
823   //                aIndex = objectIndex(aObj, theColumn);
824   //            }
825   //          }
826   //        }
827   //      }
828   //    }
829   //  }
830   //}
831   //return aIndex;
832 }
833
834 //******************************************************
835 //static QModelIndex MYLastDeleted;
836 QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
837 {
838   if (theIndex.isValid()) {
839     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
840     return getParentIndex(aNode, 1);
841   }
842   return QModelIndex();
843
844   //if (!theIndex.isValid())
845   //  return QModelIndex();
846   //// To avoid additional request about index which was already deleted
847   //if (theIndex == MYLastDeleted)
848   //  return QModelIndex();
849
850   //SessionPtr aSession = ModelAPI_Session::get();
851   //quintptr aId = theIndex.internalId();
852   //if (aId != 0) { // The object is not a root folder
853   //  ModelAPI_Document* aDoc = getSubDocument(theIndex.internalPointer());
854   //  if (aDoc) {
855   //    // It is a folder of sub-document
856   //    return findDocumentRootIndex(aDoc);
857   //  }
858   //  ObjectPtr aObj = object(theIndex);
859   //  if (!aObj.get()) {
860   //    // It can be a step of a field
861   //    ModelAPI_ResultField::ModelAPI_FieldStep* aStep = 0;
862   //    try {
863   //      aStep = dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
864   //              ((ModelAPI_Entity*)theIndex.internalPointer());
865   //    } catch(...) {}
866
867   //    if (aStep) {
868   //      ModelAPI_ResultField* aField = aStep->field();
869   //      DocumentPtr aDoc = aSession->activeDocument();
870   //      ObjectPtr aFld;
871   //      for(int i = 0; i < aDoc->size(ModelAPI_ResultField::group()); i++) {
872   //        aFld = aDoc->object(ModelAPI_ResultField::group(), i);
873   //        if (aFld.get() == aField)
874   //          return objectIndex(aFld);
875   //      }
876   //    }
877   //    // To avoid additional request about index which was already deleted
878   //    // If deleted it causes a crash on delete object from Part
879   //    MYLastDeleted = theIndex;
880   //    return QModelIndex();
881   //  }
882   //  // Check is it object a sub-object of a complex object
883   //  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
884   //  if (aFeature.get()) {
885   //    CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature);
886   //    if (aCompFea.get()) {
887   //      return objectIndex(aCompFea);
888   //    }
889   //    DocumentPtr aDoc = aFeature->document();
890   //    int aRow;
891   //    FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aRow);
892   //    if (aFolder.get())
893   //      return objectIndex(aFolder);
894   //  }
895   //  ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
896   //  if (aResult.get()) {
897   //    ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult);
898   //    if (aCompRes.get()) {
899   //      return objectIndex(aCompRes);
900   //    }
901   //  }
902   //  // Use as ordinary object
903   //  std::string aType = aObj->groupName();
904   //  DocumentPtr aRootDoc = aSession->moduleDocument();
905   //  DocumentPtr aSubDoc = aObj->document();
906   //  if (aSubDoc == aRootDoc) {
907   //    if ((aType == myXMLReader->rootType()) || (aType == ModelAPI_Folder::group()))
908   //      return QModelIndex();
909   //    else {
910   //      // return first level of folder index
911   //      int aFolderId = myXMLReader->rootFolderId(aType);
912   //      // Items in a one row must have the same parent
913   //      return createIndex(aFolderId, 1, (void*)Q_NULLPTR);
914   //    }
915   //  } else {
916   //    if ((aType == myXMLReader->subType()) || (aType == ModelAPI_Folder::group()))
917   //      return findDocumentRootIndex(aSubDoc.get());
918   //    else {
919   //      // return first level of folder index
920   //      int aFolderId = folderId(aType, aSubDoc.get());
921   //      // Items in a one row must have the same parent
922   //      return createIndex(aFolderId, 1, aSubDoc.get());
923   //    }
924   //  }
925   //}
926 }
927
928 //******************************************************
929 bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const
930 {
931   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
932     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
933   return aParentNode->childrenCount() > 0;
934 }
935
936 //******************************************************
937 bool XGUI_DataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
938 {
939   beginInsertRows(theParent, theRow, theRow + theCount - 1);
940   endInsertRows();
941   return true;
942 }
943
944 //******************************************************
945 bool XGUI_DataModel::removeRows(int theRow, int theCount, const QModelIndex& theParent)
946 {
947   beginRemoveRows(theParent, theRow, theRow + theCount - 1);
948   endRemoveRows();
949   return true;
950 }
951
952 //******************************************************
953 Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const
954 {
955   if (theIndex.isValid()) {
956     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
957     return aNode->flags(theIndex.column());
958   }
959   return Qt::ItemFlags();
960
961   //quintptr aIt = theIndex.internalId();
962   //ModelAPI_Object* aObj = 0;
963   //ModelAPI_Document* aDoc = 0;
964   //SessionPtr aSession = ModelAPI_Session::get();
965   //DocumentPtr aActiveDoc = aSession->activeDocument();
966
967   //Qt::ItemFlags aNullFlag;
968   //Qt::ItemFlags aDefaultFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
969   //Qt::ItemFlags aEditingFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
970
971
972   //if (aIt == 0) {
973   //  // Folders under root
974   //  DocumentPtr aRootDoc = aSession->moduleDocument();
975   //  if (aRootDoc != aActiveDoc)
976   //    return aDefaultFlag;
977   //} else {
978   //  aDoc = getSubDocument(theIndex.internalPointer());
979   //  if (!aDoc)
980   //    aObj = dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theIndex.internalPointer());
981   //}
982
983   //if (aObj) {
984   //  // An object
985   //  if (aObj->isDisabled())
986   //    return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag;
987
988   //  if (aSession->moduleDocument() != aObj->document())
989   //    if (aActiveDoc != aObj->document())
990   //      return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag;
991
992   //  bool isCompositeSub = false;
993   //  // An object which is sub-object of a composite object can not be accessible in column 2
994   //  if (theIndex.column() == 2) {
995   //    ObjectPtr aObjPtr = aObj->data()->owner();
996   //    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObjPtr);
997   //    if (aFeature.get()) {
998   //      CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature);
999   //      if (aCompFea.get())
1000   //        isCompositeSub = true;
1001   //    } else {
1002   //      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObjPtr);
1003   //      if (aResult.get()) {
1004   //        ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult);
1005   //        if (aCompRes.get())
1006   //          isCompositeSub = true;
1007   //      }
1008   //    }
1009   //  }
1010   //  if (isCompositeSub)
1011   //    return Qt::ItemIsSelectable;
1012
1013   //  if (aObj->document() != aActiveDoc) {
1014   //    // The object could be a root of sub-tree
1015   //    ResultPartPtr aPartRes = getPartResult(aObj);
1016   //    if (aPartRes.get()) {
1017   //      if (aPartRes->partDoc() == aActiveDoc)
1018   //        return aEditingFlag;
1019   //    }
1020   //    return aDefaultFlag;
1021   //  }
1022   //} else if (aDoc) {
1023   //  // A folder under sub-document
1024   //  if (aActiveDoc.get() != aDoc)
1025   //    return aNullFlag;
1026   //}
1027   //return aEditingFlag;
1028 }
1029
1030 //******************************************************
1031 //QModelIndex
1032 //  XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc, int aColumn) const
1033 //{
1034 //  SessionPtr aSession = ModelAPI_Session::get();
1035 //  DocumentPtr aRootDoc = aSession->moduleDocument();
1036 //  if (myXMLReader->isAttachToResult()) { // If document is attached to result
1037 //    int aNb = aRootDoc->size(ModelAPI_ResultPart::group());
1038 //    ObjectPtr aObj;
1039 //    ResultPartPtr aPartRes;
1040 //    for (int i = 0; i < aNb; i++) {
1041 //      aObj = aRootDoc->object(ModelAPI_ResultPart::group(), i);
1042 //      aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
1043 //      if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
1044 //        int aRow = i;
1045 //        if (myXMLReader->rootType() == ModelAPI_Feature::group()) {
1046 //          aRow += foldersCount();
1047 //        }
1048 //        return createIndex(aRow, aColumn, aObj.get());
1049 //      }
1050 //    }
1051 //  } else { // If document is attached to feature
1052 //    int aNb = aRootDoc->size(ModelAPI_Feature::group(), true);
1053 //    ObjectPtr aObj;
1054 //    ResultPartPtr aPartRes;
1055 //    for (int i = 0; i < aNb; i++) {
1056 //      aObj = aRootDoc->object(ModelAPI_Feature::group(), i, true);
1057 //      aPartRes = getPartResult(aObj.get());
1058 //      if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
1059 //        int aRow = i;
1060 //        if (myXMLReader->rootType() == ModelAPI_Feature::group())
1061 //          aRow += foldersCount();
1062 //        return createIndex(aRow, aColumn, aObj.get());
1063 //      }
1064 //    }
1065 //  }
1066 //  return QModelIndex();
1067 //}
1068
1069 //******************************************************
1070 QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) const
1071 {
1072   SessionPtr aSession = ModelAPI_Session::get();
1073   DocumentPtr aRootDoc = aSession->moduleDocument();
1074   if (theDoc == aRootDoc)
1075     return QModelIndex();
1076   else {
1077     ModuleBase_ITreeNode* aDocNode = 0;
1078     foreach(ModuleBase_ITreeNode* aNode, myRoot->children()) {
1079       if (aNode->document() == theDoc) {
1080         aDocNode = aNode;
1081         break;
1082       }
1083     }
1084     if (aDocNode)
1085       return getIndex(aDocNode, theColumn);
1086   }
1087   return QModelIndex();
1088   //  return findDocumentRootIndex(theDoc.get(), theColumn);
1089 }
1090
1091 //******************************************************
1092 //int XGUI_DataModel::foldersCount(ModelAPI_Document* theDoc) const
1093 //{
1094 //  int aNb = 0;
1095 //  SessionPtr aSession = ModelAPI_Session::get();
1096 //  DocumentPtr aRootDoc = aSession->moduleDocument();
1097 //  if ((theDoc == 0) || (theDoc == aRootDoc.get())) {
1098 //    for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) {
1099 //      if (myXMLReader->rootShowEmpty(i))
1100 //        aNb++;
1101 //      else {
1102 //        if (aRootDoc->size(myXMLReader->rootFolderType(i)) > 0)
1103 //          aNb++;
1104 //      }
1105 //    }
1106 //  } else {
1107 //    for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) {
1108 //      if (myXMLReader->subShowEmpty(i))
1109 //        aNb++;
1110 //      else {
1111 //        if (theDoc->size(myXMLReader->subFolderType(i)) > 0)
1112 //          aNb++;
1113 //      }
1114 //    }
1115 //  }
1116 //  return aNb;
1117 //}
1118
1119
1120 //******************************************************
1121 //QIntList XGUI_DataModel::missedFolderIndexes(ModelAPI_Document* theDoc) const
1122 //{
1123 //  QIntList aList;
1124 //  SessionPtr aSession = ModelAPI_Session::get();
1125 //  DocumentPtr aRootDoc = aSession->moduleDocument();
1126 //  if ((theDoc == 0) || (theDoc == aRootDoc.get())) {
1127 //    for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) {
1128 //      if (!myXMLReader->rootShowEmpty(i)) {
1129 //        if (aRootDoc->size(myXMLReader->rootFolderType(i)) == 0)
1130 //          aList.append(i);
1131 //      }
1132 //    }
1133 //  } else {
1134 //    for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) {
1135 //      if (!myXMLReader->subShowEmpty(i)) {
1136 //        if (theDoc->size(myXMLReader->subFolderType(i)) == 0)
1137 //          aList.append(i);
1138 //      }
1139 //    }
1140 //  }
1141 //  return aList;
1142 //}
1143
1144
1145 //******************************************************
1146 //QStringList XGUI_DataModel::listOfShowNotEmptyFolders(bool fromRoot) const
1147 //{
1148 //  QStringList aResult;
1149 //  if (fromRoot) {
1150 //    for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) {
1151 //      if (!myXMLReader->rootShowEmpty(i))
1152 //        aResult << myXMLReader->rootFolderType(i).c_str();
1153 //    }
1154 //  } else {
1155 //    for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) {
1156 //      if (!myXMLReader->subShowEmpty(i))
1157 //        aResult << myXMLReader->subFolderType(i).c_str();
1158 //    }
1159 //  }
1160 //  return aResult;
1161 //}
1162
1163 //******************************************************
1164 //QModelIndex XGUI_DataModel::lastHistoryIndex() const
1165 //{
1166   //SessionPtr aSession = ModelAPI_Session::get();
1167   //DocumentPtr aCurDoc = aSession->activeDocument();
1168   //FeaturePtr aFeature = aCurDoc->currentFeature(true);
1169   //if (aFeature.get()) {
1170   //  QModelIndex aInd = objectIndex(aFeature);
1171   //  return createIndex(aInd.row(), 2, aInd.internalPointer());
1172   //} else {
1173   //  if (aCurDoc == aSession->moduleDocument())
1174   //    return createIndex(foldersCount() - 1, 2, -1);
1175   //  else
1176   //    return createIndex(foldersCount(aCurDoc.get()) - 1, 2, aCurDoc.get());
1177   //}
1178 //}
1179
1180 //******************************************************
1181 bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex)
1182 {
1183   return false;
1184   //return getVisibilityState(theIndex) == Hidden;
1185 }
1186
1187 //******************************************************
1188 //int XGUI_DataModel::folderId(std::string theType, ModelAPI_Document* theDoc) const
1189 //{
1190 //  SessionPtr aSession = ModelAPI_Session::get();
1191 //  ModelAPI_Document* aDoc = theDoc;
1192 //  if (aDoc == 0)
1193 //    aDoc = aSession->moduleDocument().get();
1194 //
1195 //  bool aUseSubDoc = (aDoc != aSession->moduleDocument().get());
1196 //
1197 //  int aRes = -1;
1198 //  if (aUseSubDoc) {
1199 //    int aId = myXMLReader->subFolderId(theType);
1200 //    aRes = aId;
1201 //    for (int i = 0; i < aId; i++) {
1202 //      if (!myXMLReader->subShowEmpty(i)) {
1203 //        if (aDoc->size(myXMLReader->subFolderType(i)) == 0)
1204 //          aRes--;
1205 //      }
1206 //    }
1207 //  } else {
1208 //    int aId = myXMLReader->rootFolderId(theType);
1209 //    aRes = aId;
1210 //    for (int i = 0; i < aId; i++) {
1211 //      if (!myXMLReader->rootShowEmpty(i)) {
1212 //        if (aDoc->size(myXMLReader->rootFolderType(i)) == 0)
1213 //          aRes--;
1214 //      }
1215 //    }
1216 //  }
1217 //  return aRes;
1218 //}
1219
1220 //******************************************************
1221 //void XGUI_DataModel::rebuildBranch(int theRow, int theCount, const QModelIndex& theParent)
1222 //{
1223 //  if (theCount > 0) {
1224 //    removeRows(theRow, theCount, theParent);
1225 //    insertRows(theRow, theCount, theParent);
1226 //  }
1227 //}
1228
1229 //******************************************************
1230 //bool XGUI_DataModel::blockEventsProcessing(const bool theState)
1231 //{
1232 //  bool aPreviousState = myIsEventsProcessingBlocked;
1233 //  myIsEventsProcessingBlocked = theState;
1234 //  return aPreviousState;
1235 //}
1236
1237 //******************************************************
1238 //XGUI_DataModel::VisibilityState
1239 //  XGUI_DataModel::getVisibilityState(const QModelIndex& theIndex) const
1240 //{
1241 //  Qt::ItemFlags aFlags = theIndex.flags();
1242 //  if (aFlags == Qt::ItemFlags())
1243 //    return NoneState;
1244 //
1245 //  ObjectPtr aObj = object(theIndex);
1246 //  if (aObj.get()) {
1247 //    if (aObj->groupName() == ModelAPI_ResultParameter::group())
1248 //      return NoneState;
1249 //    ResultPtr aResObj = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
1250 //    if (aResObj.get()) {
1251 //      XGUI_Displayer* aDisplayer = myWorkshop->displayer();
1252 //      ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResObj);
1253 //      if (aCompRes.get()) {
1254 //        VisibilityState aState = aCompRes->numberOfSubs(true) == 0 ?
1255 //          (aDisplayer->isVisible(aCompRes)? Visible : Hidden) : NoneState;
1256 //        for (int i = 0; i < aCompRes->numberOfSubs(true); i++) {
1257 //          ResultPtr aSubRes = aCompRes->subResult(i, true);
1258 //          VisibilityState aS = aDisplayer->isVisible(aSubRes)? Visible : Hidden;
1259 //          if (aState == NoneState)
1260 //            aState = aS;
1261 //          else if (aState != aS) {
1262 //            aState = SemiVisible;
1263 //            break;
1264 //          }
1265 //        }
1266 //        return aState;
1267 //      } else {
1268 //        if (aDisplayer->isVisible(aResObj))
1269 //          return Visible;
1270 //        else
1271 //          return Hidden;
1272 //      }
1273 //    }
1274 //  }
1275 //  return NoneState;
1276 //}
1277
1278
1279 //int XGUI_DataModel::getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const
1280 //{
1281 //  DocumentPtr aDoc = theFolder->document();
1282 //
1283 //  FeaturePtr aFirstFeatureInFolder;
1284 //  AttributeReferencePtr aFirstFeatAttr =
1285 //      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
1286 //  if (aFirstFeatAttr)
1287 //    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
1288 //  if (!aFirstFeatureInFolder.get())
1289 //    return 0;
1290 //
1291 //  FeaturePtr aLastFeatureInFolder;
1292 //  AttributeReferencePtr aLastFeatAttr =
1293 //      theFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
1294 //  if (aLastFeatAttr)
1295 //    aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
1296 //  if (!aLastFeatureInFolder.get())
1297 //    return 0;
1298 //
1299 //  int aFirst = aDoc->index(aFirstFeatureInFolder);
1300 //  int aLast = aDoc->index(aLastFeatureInFolder);
1301 //  return aLast - aFirst + 1;
1302 //}
1303
1304 //ObjectPtr XGUI_DataModel::getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const
1305 //{
1306 //  DocumentPtr aDoc = theFolder->document();
1307 //
1308 //  FeaturePtr aFirstFeatureInFolder;
1309 //  AttributeReferencePtr aFirstFeatAttr =
1310 //      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
1311 //  if (aFirstFeatAttr)
1312 //    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
1313 //  if (!aFirstFeatureInFolder.get())
1314 //    return ObjectPtr();
1315 //
1316 //  int aFirst = aDoc->index(aFirstFeatureInFolder);
1317 //  return aDoc->object(ModelAPI_Feature::group(), aFirst + theId);
1318 //}
1319
1320 bool XGUI_DataModel::hasIndex(const QModelIndex& theIndex) const
1321 {
1322   ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
1323   return myRoot->hasSubNode(aNode);
1324 }
1325
1326 QModelIndex XGUI_DataModel::getParentIndex(ModuleBase_ITreeNode* theNode, int thCol) const
1327 {
1328   ModuleBase_ITreeNode* aParent = theNode->parent();
1329   if (aParent == myRoot) {
1330     return QModelIndex();
1331   } else {
1332     return getIndex(aParent, thCol);
1333   }
1334 }
1335
1336 QModelIndex XGUI_DataModel::getIndex(ModuleBase_ITreeNode* theNode, int thCol) const
1337 {
1338   if (theNode == myRoot)
1339     return QModelIndex();
1340   int aRow = theNode->parent()->nodeRow(theNode);
1341   return createIndex(aRow, thCol, theNode);
1342 }
1343
1344
1345 void XGUI_DataModel::updateSubTree(ModuleBase_ITreeNode* theParent)
1346 {
1347   int aRows = theParent->childrenCount();
1348   if (aRows) {
1349     QModelIndex aParent = getIndex(theParent, 0);
1350     QModelIndex aFirstIdx = aParent.child(0, 0);
1351     QModelIndex aLastIdx = aParent.child(aRows - 1, 2);
1352     dataChanged(aFirstIdx, aLastIdx);
1353   }
1354 }