Salome HOME
Update just modified part tree in object browser
[modules/shaper.git] / src / XGUI / XGUI_DocumentDataModel.cpp
1 #include "XGUI_DocumentDataModel.h"
2 #include "XGUI_PartDataModel.h"
3
4 #include <ModelAPI_PluginManager.h>
5 #include <ModelAPI_Iterator.h>
6 #include <ModelAPI_Document.h>
7 #include <ModelAPI_Feature.h>
8 #include <ModelAPI_Data.h>
9 #include <Model_Events.h>
10
11 #include <Event_Loop.h>
12
13
14 #include <QIcon>
15 #include <QString>
16
17
18 XGUI_DocumentDataModel::XGUI_DocumentDataModel(QObject* theParent)
19   : QAbstractItemModel(theParent)
20 {
21   // Find Document object
22   std::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
23   myDocument = aMgr->currentDocument();
24
25   // Register in event loop
26   Event_Loop::loop()->registerListener(this, Event_Loop::eventByName(EVENT_FEATURE_CREATED));
27   Event_Loop::loop()->registerListener(this, Event_Loop::eventByName(EVENT_FEATURE_UPDATED));
28
29   // Create a top part of data tree model
30   myModel = new XGUI_TopDataModel(myDocument, this);
31 }
32
33
34 XGUI_DocumentDataModel::~XGUI_DocumentDataModel()
35 {
36   clearModelIndexes();
37 }
38
39
40 void XGUI_DocumentDataModel::processEvent(const Event_Message* theMessage)
41 {
42   if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_CREATED) {
43     // Add a new part
44     int aStart = myModel->rowCount(QModelIndex()) + myPartModels.size();
45     beginInsertRows(QModelIndex(), aStart, aStart + 1);
46     XGUI_PartDataModel* aModel = new XGUI_PartDataModel(myDocument, this);
47     aModel->setPartId(myPartModels.count());
48     myPartModels.append(aModel);
49     endInsertRows();
50   } else {
51     // Reset whole tree
52     beginResetModel();
53     int aNbParts = myDocument->featuresIterator(PARTS_GROUP)->numIterationsLeft();
54     if (myPartModels.size() != aNbParts) { // resize internal models
55       while (myPartModels.size() > aNbParts) {
56         delete myPartModels.last();
57         myPartModels.removeLast();
58       }
59       while (myPartModels.size() < aNbParts) {
60         myPartModels.append(new XGUI_PartDataModel(myDocument, this));
61       }
62       for (int i = 0; i < myPartModels.size(); i++)
63         myPartModels.at(i)->setPartId(i);
64     }
65     clearModelIndexes();
66     endResetModel();
67   }
68 }
69
70 QVariant XGUI_DocumentDataModel::data(const QModelIndex& theIndex, int theRole) const
71 {
72   if (!theIndex.isValid())
73     return QVariant();
74   return toSourceModel(theIndex).data(theRole);
75 }
76
77
78 QVariant XGUI_DocumentDataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
79 {
80   return QVariant();
81 }
82
83 int XGUI_DocumentDataModel::rowCount(const QModelIndex& theParent) const
84 {
85   if (!theParent.isValid()) 
86     return myModel->rowCount(theParent) + myPartModels.size();
87
88   QModelIndex aParent = toSourceModel(theParent);
89   return aParent.model()->rowCount(aParent);
90 }
91
92 int XGUI_DocumentDataModel::columnCount(const QModelIndex& theParent) const
93 {
94   return 1;
95 }
96
97 QModelIndex XGUI_DocumentDataModel::index(int theRow, int theColumn, const QModelIndex& theParent) const
98 {
99   QModelIndex aIndex;
100   if (!theParent.isValid()) {
101     int aOffs = myModel->rowCount();
102     if (theRow < aOffs) 
103       aIndex = myModel->index(theRow, theColumn, theParent);
104     else
105       aIndex = myPartModels.at(theRow - aOffs)->index(theRow - aOffs, theColumn, theParent);
106
107     aIndex = createIndex(theRow, theColumn, (void*)getModelIndex(aIndex));
108   } else {
109     QModelIndex* aParent = (QModelIndex*)theParent.internalPointer();
110     aIndex = aParent->model()->index(theRow, theColumn, (*aParent));
111
112     aIndex = createIndex(theRow, theColumn, (void*)getModelIndex(aIndex));
113   }
114   return aIndex;
115 }
116
117
118 QModelIndex XGUI_DocumentDataModel::parent(const QModelIndex& theIndex) const
119 {
120   QModelIndex aParent = toSourceModel(theIndex);
121   aParent = aParent.model()->parent(aParent);
122   if (aParent.isValid())
123     return createIndex(aParent.row(), aParent.column(), (void*)getModelIndex(aParent));
124   return aParent;
125 }
126
127
128 bool XGUI_DocumentDataModel::hasChildren(const QModelIndex& theParent) const
129 {
130   if (!theParent.isValid())
131     return true;
132   return rowCount(theParent) > 0;
133 }
134
135
136 QModelIndex XGUI_DocumentDataModel::toSourceModel(const QModelIndex& theProxy) const
137 {
138   QModelIndex* aIndexPtr = static_cast<QModelIndex*>(theProxy.internalPointer());
139   return (*aIndexPtr);
140 }
141
142
143 QModelIndex* XGUI_DocumentDataModel::findModelIndex(const QModelIndex& theIndex) const
144 {
145   QList<QModelIndex*>::const_iterator aIt;
146   for (aIt = myIndexes.constBegin(); aIt != myIndexes.constEnd(); ++aIt) {
147     QModelIndex* aIndex = (*aIt);
148     if ((*aIndex) == theIndex)
149       return aIndex;
150   }
151   return 0;
152 }
153
154 QModelIndex* XGUI_DocumentDataModel::getModelIndex(const QModelIndex& theIndex) const
155 {
156   QModelIndex* aIndexPtr = findModelIndex(theIndex);
157   if (!aIndexPtr) {
158     aIndexPtr = new QModelIndex(theIndex);
159     XGUI_DocumentDataModel* that = (XGUI_DocumentDataModel*) this;
160     that->myIndexes.append(aIndexPtr);
161   }
162   return aIndexPtr;
163 }
164
165 void XGUI_DocumentDataModel::clearModelIndexes()
166 {
167   QList<QModelIndex*>::const_iterator aIt;
168   for (aIt = myIndexes.constBegin(); aIt != myIndexes.constEnd(); ++aIt) 
169     delete (*aIt);
170   myIndexes.clear();
171 }
172
173 FeaturePtr XGUI_DocumentDataModel::feature(const QModelIndex& theIndex) const
174 {
175   QModelIndex aIndex = toSourceModel(theIndex);
176   const XGUI_FeaturesModel* aModel = dynamic_cast<const XGUI_FeaturesModel*>(aIndex.model());
177   return aModel->feature(aIndex);
178 }