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