]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_DocumentDataModel.cpp
Salome HOME
Merge branch 'master' of newgeom:newgeom
[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   Event_Loop::loop()->registerListener(this, Event_Loop::eventByName(EVENT_FEATURE_DELETED));
29
30   // Create a top part of data tree model
31   myModel = new XGUI_TopDataModel(myDocument, this);
32 }
33
34
35 XGUI_DocumentDataModel::~XGUI_DocumentDataModel()
36 {
37   clearModelIndexes();
38 }
39
40
41 void XGUI_DocumentDataModel::processEvent(const Event_Message* theMessage)
42 {
43   // Created object event *******************
44   if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_CREATED) {
45     const ModelAPI_FeatureUpdatedMessage* aUpdMsg = dynamic_cast<const ModelAPI_FeatureUpdatedMessage*>(theMessage);
46     std::shared_ptr<ModelAPI_Document> aDoc = aUpdMsg->document();
47     std::shared_ptr<ModelAPI_Feature> aFeature = aUpdMsg->feature();
48
49     if (aDoc == myDocument) {  // If root objects
50       if (aFeature->getGroup().compare(PARTS_GROUP) == 0) { // Updsate only Parts group
51         // Add a new part
52         int aStart = myModel->rowCount(QModelIndex()) + myPartModels.size() + 1;
53         XGUI_PartDataModel* aModel = new XGUI_PartDataModel(myDocument, this);
54         aModel->setPartId(myPartModels.count());
55         myPartModels.append(aModel);
56         insertRows(QModelIndex(), aStart, aStart);
57       } else { // Update top groups (other except parts
58         QModelIndex aIndex = myModel->findParent(aFeature);
59         int aStart = myModel->rowCount(aIndex) - 1;
60         aIndex = createIndex(aIndex.row(), aIndex.column(), (void*)getModelIndex(aIndex));
61         insertRows(aIndex, aStart, aStart);
62       }
63     } else { // if sub-objects of first level nodes
64       XGUI_PartModel* aPartModel = 0;
65       QList<XGUI_PartModel*>::const_iterator aIt;
66       for (aIt = myPartModels.constBegin(); aIt != myPartModels.constEnd(); ++aIt) {
67         if ((*aIt)->hasDocument(aDoc)) {
68           aPartModel = (*aIt);
69           break;
70         }
71       }
72       if (aPartModel) {
73         QModelIndex aIndex = aPartModel->findParent(aFeature);
74         int aStart = aPartModel->rowCount(aIndex) - 1;
75         aIndex = createIndex(aIndex.row(), aIndex.column(), (void*)getModelIndex(aIndex));
76         insertRows(aIndex, aStart, aStart);
77       }
78     }
79
80   // Deteted object event ***********************
81   } else if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_DELETED) {
82     const ModelAPI_FeatureDeletedMessage* aUpdMsg = dynamic_cast<const ModelAPI_FeatureDeletedMessage*>(theMessage);
83     std::shared_ptr<ModelAPI_Document> aDoc = aUpdMsg->document();
84
85     if (aDoc == myDocument) {  // If root objects
86       if (aUpdMsg->group().compare(PARTS_GROUP) == 0) { // Updsate only Parts group
87         int aStart = myModel->rowCount(QModelIndex()) + myPartModels.size() - 1;
88         beginRemoveRows(QModelIndex(), aStart, aStart);
89         endRemoveRows();
90         delete myPartModels.last();
91         myPartModels.removeLast();
92       } else { // Update top groups (other except parts
93         QModelIndex aIndex = myModel->findGroup(aUpdMsg->group());
94         int aStart = myModel->rowCount(aIndex);
95         aIndex = createIndex(aIndex.row(), aIndex.column(), (void*)getModelIndex(aIndex));
96         beginRemoveRows(aIndex, aStart, aStart);
97         endRemoveRows();
98       }
99     } else {
100       XGUI_PartModel* aPartModel = 0;
101       QList<XGUI_PartModel*>::const_iterator aIt;
102       for (aIt = myPartModels.constBegin(); aIt != myPartModels.constEnd(); ++aIt) {
103         if ((*aIt)->hasDocument(aDoc)) {
104           aPartModel = (*aIt);
105           break;
106         }
107       }
108       if (aPartModel) {
109         QModelIndex aIndex = aPartModel->findGroup(aUpdMsg->group());
110         int aStart = aPartModel->rowCount(aIndex);
111         aIndex = createIndex(aIndex.row(), aIndex.column(), (void*)getModelIndex(aIndex));
112         beginRemoveRows(aIndex, aStart, aStart);
113         endRemoveRows();
114       }
115     }
116
117   // Reset whole tree **************************
118   } else {  
119     beginResetModel();
120     int aNbParts = myDocument->featuresIterator(PARTS_GROUP)->numIterationsLeft();
121     if (myPartModels.size() != aNbParts) { // resize internal models
122       while (myPartModels.size() > aNbParts) {
123         delete myPartModels.last();
124         myPartModels.removeLast();
125       }
126       while (myPartModels.size() < aNbParts) {
127         myPartModels.append(new XGUI_PartDataModel(myDocument, this));
128       }
129       for (int i = 0; i < myPartModels.size(); i++)
130         myPartModels.at(i)->setPartId(i);
131     }
132     clearModelIndexes();
133     endResetModel();
134   }
135 }
136
137 QVariant XGUI_DocumentDataModel::data(const QModelIndex& theIndex, int theRole) const
138 {
139   if (!theIndex.isValid())
140     return QVariant();
141   return toSourceModelIndex(theIndex).data(theRole);
142 }
143
144
145 QVariant XGUI_DocumentDataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
146 {
147   return QVariant();
148 }
149
150 int XGUI_DocumentDataModel::rowCount(const QModelIndex& theParent) const
151 {
152   if (!theParent.isValid()) {
153     int aVal = myModel->rowCount(theParent) + myPartModels.size();
154     return myModel->rowCount(theParent) + myPartModels.size();
155   }
156   QModelIndex aParent = toSourceModelIndex(theParent);
157   return aParent.model()->rowCount(aParent);
158 }
159
160 int XGUI_DocumentDataModel::columnCount(const QModelIndex& theParent) const
161 {
162   return 1;
163 }
164
165 QModelIndex XGUI_DocumentDataModel::index(int theRow, int theColumn, const QModelIndex& theParent) const
166 {
167   QModelIndex aIndex;
168   if (!theParent.isValid()) {
169     int aOffs = myModel->rowCount();
170     if (theRow < aOffs) 
171       aIndex = myModel->index(theRow, theColumn, theParent);
172     else  {
173       if (myPartModels.size() > 0) {
174         int aPos = theRow - aOffs;
175         if (aPos >= myPartModels.size())
176           aPos = 0;
177         aIndex = myPartModels.at(aPos)->index(aPos, theColumn, theParent);
178       } else 
179         return aIndex;
180     }
181     aIndex = createIndex(theRow, theColumn, (void*)getModelIndex(aIndex));
182   } else {
183     QModelIndex* aParent = (QModelIndex*)theParent.internalPointer();
184     aIndex = aParent->model()->index(theRow, theColumn, (*aParent));
185
186     aIndex = createIndex(theRow, theColumn, (void*)getModelIndex(aIndex));
187   }
188   return aIndex;
189 }
190
191
192 QModelIndex XGUI_DocumentDataModel::parent(const QModelIndex& theIndex) const
193 {
194   QModelIndex aParent = toSourceModelIndex(theIndex);
195   const QAbstractItemModel* a = aParent.model();
196   aParent = aParent.model()->parent(aParent);
197   if (aParent.isValid())
198     return createIndex(aParent.row(), aParent.column(), (void*)getModelIndex(aParent));
199   return aParent;
200 }
201
202
203 bool XGUI_DocumentDataModel::hasChildren(const QModelIndex& theParent) const
204 {
205   if (!theParent.isValid())
206     return true;
207   return rowCount(theParent) > 0;
208 }
209
210
211 QModelIndex XGUI_DocumentDataModel::toSourceModelIndex(const QModelIndex& theProxy) const
212 {
213   QModelIndex* aIndexPtr = static_cast<QModelIndex*>(theProxy.internalPointer());
214   return (*aIndexPtr);
215 }
216
217
218 QModelIndex* XGUI_DocumentDataModel::findModelIndex(const QModelIndex& theIndex) const
219 {
220   QList<QModelIndex*>::const_iterator aIt;
221   for (aIt = myIndexes.constBegin(); aIt != myIndexes.constEnd(); ++aIt) {
222     QModelIndex* aIndex = (*aIt);
223     if ((*aIndex) == theIndex)
224       return aIndex;
225   }
226   return 0;
227 }
228
229 QModelIndex* XGUI_DocumentDataModel::getModelIndex(const QModelIndex& theIndex) const
230 {
231   QModelIndex* aIndexPtr = findModelIndex(theIndex);
232   if (!aIndexPtr) {
233     aIndexPtr = new QModelIndex(theIndex);
234     XGUI_DocumentDataModel* that = (XGUI_DocumentDataModel*) this;
235     that->myIndexes.append(aIndexPtr);
236   }
237   return aIndexPtr;
238 }
239
240 void XGUI_DocumentDataModel::clearModelIndexes()
241 {
242   QList<QModelIndex*>::const_iterator aIt;
243   for (aIt = myIndexes.constBegin(); aIt != myIndexes.constEnd(); ++aIt) 
244     delete (*aIt);
245   myIndexes.clear();
246 }
247
248 FeaturePtr XGUI_DocumentDataModel::feature(const QModelIndex& theIndex) const
249 {
250   QModelIndex aIndex = toSourceModelIndex(theIndex);
251   const XGUI_FeaturesModel* aModel = dynamic_cast<const XGUI_FeaturesModel*>(aIndex.model());
252   return aModel->feature(aIndex);
253 }
254
255 void XGUI_DocumentDataModel::insertRows(const QModelIndex& theParent, int theStart, int theEnd)
256 {
257   beginInsertRows(theParent, theStart, theEnd);
258   endInsertRows();
259   if (theStart == 0) // Update parent if this is a first child in order to update node decoration
260     emit dataChanged(theParent, theParent);
261 }