Salome HOME
Remove unused variable
[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_ObjectsBrowser.h"
23
24 #include <ModuleBase_IconFactory.h>
25 #include <ModuleBase_ITreeNode.h>
26
27 #include <ModelAPI_Session.h>
28 #include <ModelAPI_ResultField.h>
29
30 #include <Config_FeatureMessage.h>
31
32 #include <Events_Loop.h>
33
34 #include <cassert>
35
36
37
38 // Constructor *************************************************
39 XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent)//,
40   //myIsEventsProcessingBlocked(false)
41 {
42   XGUI_ObjectsBrowser* aOB = qobject_cast<XGUI_ObjectsBrowser*>(theParent);
43   myWorkshop = aOB->workshop();
44
45   Events_Loop* aLoop = Events_Loop::loop();
46   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
47   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
48   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
49   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_ORDER_UPDATED));
50   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED));
51   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
52 }
53
54 XGUI_DataModel::~XGUI_DataModel()
55 {
56   clear();
57 }
58
59 //******************************************************
60 void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMessage)
61 {
62   if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
63     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
64       std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
65     std::set<ObjectPtr> aObjects = aUpdMsg->objects();
66     QObjectPtrList aCreated;
67     std::set<ObjectPtr>::const_iterator aIt;
68     for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) {
69       if ((*aIt)->isInHistory())
70         aCreated.append(*aIt);
71     }
72     QTreeNodesList aNodes = myRoot->objectCreated(aCreated);
73     ModuleBase_ITreeNode* aParent;
74     int aRow = 0;
75     QModelIndex aParentIndex1, aParentIndex2;
76     foreach(ModuleBase_ITreeNode* aNode, aNodes) {
77       aParent = aNode->parent();
78       aRow = aParent->nodeRow(aNode);
79       aParentIndex1 = getParentIndex(aNode, 0);
80       aParentIndex2 = getParentIndex(aNode, 2);
81       insertRows(aRow, 1, aParentIndex1);
82       dataChanged(aParentIndex1, aParentIndex2);
83     }
84   }
85   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
86     std::shared_ptr<ModelAPI_ObjectDeletedMessage> aUpdMsg =
87       std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
88     const std::list<std::pair<std::shared_ptr<ModelAPI_Document>, std::string>>& aMsgGroups =
89       aUpdMsg->groups();
90     std::list<std::pair<std::shared_ptr<ModelAPI_Document>, std::string>>::const_iterator aIt;
91     for (aIt = aMsgGroups.cbegin(); aIt != aMsgGroups.cend(); aIt++)
92       QTreeNodesList aList = myRoot->objectsDeleted(aIt->first, aIt->second.c_str());
93     rebuildDataTree();
94   }
95   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {
96     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
97       std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
98     std::set<ObjectPtr> aObjects = aUpdMsg->objects();
99
100     QObjectPtrList aCreated;
101     std::set<ObjectPtr>::const_iterator aIt;
102     bool aRebuildAll = false;
103     for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) {
104       ObjectPtr aObj = (*aIt);
105       if (!aObj->isInHistory())
106         continue;
107
108       if (aObj->data()->isValid()) {
109         if (aObj->groupName() == ModelAPI_Folder::group()) {
110           aRebuildAll = true;
111           break;
112         }
113         aCreated.append(*aIt);
114       }
115     }
116     if (aRebuildAll) {
117       myRoot->update();
118       rebuildDataTree();
119     }
120     else {
121       foreach(ObjectPtr aObj, aCreated) {
122         ModuleBase_ITreeNode* aNode = myRoot->subNode(aObj);
123         if (aNode) {
124           int aOldNb = aNode->childrenCount();
125           aNode->update();
126           int aNewNb = aNode->childrenCount();
127
128           QModelIndex aFirstIdx = getIndex(aNode, 0);
129           QModelIndex aLastIdx = getIndex(aNode, 2);
130
131           if (aNewNb > aOldNb) {
132             insertRows(aOldNb - 1, aNewNb - aOldNb, aFirstIdx);
133           }
134           else if (aNewNb < aOldNb) {
135             if (aNewNb)
136               removeRows(aNewNb - 1, aOldNb - aNewNb, aFirstIdx);
137             else if (aOldNb)
138               removeRows(0, aOldNb, aFirstIdx);
139           }
140           dataChanged(aFirstIdx, aLastIdx);
141         }
142       }
143     }
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         rebuildDataTree();
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   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)) {
166     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
167       std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
168     std::set<ObjectPtr> aObjects = aUpdMsg->objects();
169
170     QObjectPtrList aCreated;
171     std::set<ObjectPtr>::const_iterator aIt;
172     bool aRebuildAll = false;
173     for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) {
174       ObjectPtr aObj = (*aIt);
175       if (aObj->groupName() == ModelAPI_ResultField::group()) {
176         aCreated.append(aObj);
177       }
178     }
179     foreach(ObjectPtr aObj, aCreated) {
180       ModuleBase_ITreeNode* aNode = myRoot->subNode(aObj);
181       if (aNode) {
182         int aOldNb = aNode->childrenCount();
183         aNode->update();
184         int aNewNb = aNode->childrenCount();
185
186         QModelIndex aFirstIdx = getIndex(aNode, 0);
187         QModelIndex aLastIdx = getIndex(aNode, 2);
188
189         if (aNewNb > aOldNb) {
190           insertRows(aOldNb - 1, aNewNb - aOldNb, aFirstIdx);
191         }
192         else if (aNewNb < aOldNb) {
193           if (aNewNb)
194             removeRows(aNewNb - 1, aOldNb - aNewNb, aFirstIdx);
195           else if (aOldNb)
196             removeRows(0, aOldNb, aFirstIdx);
197         }
198         dataChanged(aFirstIdx, aLastIdx);
199       }
200     }
201   }
202 }
203
204 //******************************************************
205 void XGUI_DataModel::clear()
206 {
207   beginResetModel();
208   endResetModel();
209 }
210
211 //******************************************************
212 void XGUI_DataModel::rebuildDataTree()
213 {
214   beginResetModel();
215   endResetModel();
216   emit treeRebuilt();
217 }
218
219 //******************************************************
220 ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const
221 {
222   if (theIndex.isValid()) {
223     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
224     return aNode->object();
225   }
226   return ObjectPtr();
227 }
228
229 //******************************************************
230 QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn) const
231 {
232   ModuleBase_ITreeNode* aNode = myRoot->subNode(theObject);
233   if (aNode) {
234     return getIndex(aNode, theColumn);
235   }
236   return QModelIndex();
237 }
238
239 //******************************************************
240 QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
241 {
242   if (theIndex.isValid()) {
243     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
244     return aNode->data(theIndex.column(), theRole);
245   }
246   return QVariant();
247 }
248
249 //******************************************************
250 QVariant XGUI_DataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
251 {
252   return QVariant();
253 }
254
255 //******************************************************
256 int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
257 {
258   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
259     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
260   return aParentNode->childrenCount();
261 }
262
263 //******************************************************
264 int XGUI_DataModel::columnCount(const QModelIndex& theParent) const
265 {
266   return 3;
267 }
268
269 //******************************************************
270 QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
271 {
272   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
273     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
274   ModuleBase_ITreeNode* aSubNode = aParentNode->subNode(theRow);
275   assert(aSubNode);
276   return createIndex(theRow, theColumn, aSubNode);
277 }
278
279 //******************************************************
280 QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
281 {
282   if (theIndex.isValid()) {
283     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
284     return getParentIndex(aNode, 1);
285   }
286   return QModelIndex();
287 }
288
289 //******************************************************
290 bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const
291 {
292   ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
293     (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
294   return aParentNode->childrenCount() > 0;
295 }
296
297 //******************************************************
298 bool XGUI_DataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
299 {
300   beginInsertRows(theParent, theRow, theRow + theCount - 1);
301   endInsertRows();
302   return true;
303 }
304
305 //******************************************************
306 bool XGUI_DataModel::removeRows(int theRow, int theCount, const QModelIndex& theParent)
307 {
308   beginRemoveRows(theParent, theRow, theRow + theCount - 1);
309   endRemoveRows();
310   return true;
311 }
312
313 //******************************************************
314 Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const
315 {
316   if (theIndex.isValid()) {
317     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
318     return aNode->flags(theIndex.column());
319   }
320   return Qt::ItemFlags();
321 }
322
323
324 //******************************************************
325 QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) const
326 {
327   SessionPtr aSession = ModelAPI_Session::get();
328   DocumentPtr aRootDoc = aSession->moduleDocument();
329   if (theDoc == aRootDoc)
330     return QModelIndex();
331   else {
332     ModuleBase_ITreeNode* aDocNode = 0;
333     foreach(ModuleBase_ITreeNode* aNode, myRoot->children()) {
334       if (aNode->document() == theDoc) {
335         aDocNode = aNode;
336         break;
337       }
338     }
339     if (aDocNode)
340       return getIndex(aDocNode, theColumn);
341   }
342   return QModelIndex();
343 }
344
345 //******************************************************
346 bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex)
347 {
348   if (theIndex.isValid()) {
349     ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
350     return aNode->visibilityState() == ModuleBase_ITreeNode::Hidden;
351   }
352   return false;
353 }
354
355 //******************************************************
356 bool XGUI_DataModel::hasIndex(const QModelIndex& theIndex) const
357 {
358   ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
359   return myRoot->hasSubNode(aNode);
360 }
361
362 //******************************************************
363 QModelIndex XGUI_DataModel::getParentIndex(ModuleBase_ITreeNode* theNode, int thCol) const
364 {
365   ModuleBase_ITreeNode* aParent = theNode->parent();
366   if (aParent == myRoot) {
367     return QModelIndex();
368   } else {
369     return getIndex(aParent, thCol);
370   }
371 }
372
373 //******************************************************
374 QModelIndex XGUI_DataModel::getIndex(ModuleBase_ITreeNode* theNode, int thCol) const
375 {
376   if (theNode == myRoot)
377     return QModelIndex();
378   int aRow = theNode->parent()->nodeRow(theNode);
379   return createIndex(aRow, thCol, theNode);
380 }
381
382
383 //******************************************************
384 void XGUI_DataModel::updateSubTree(ModuleBase_ITreeNode* theParent)
385 {
386   int aRows = theParent->childrenCount();
387   if (aRows) {
388     QModelIndex aParent = getIndex(theParent, 0);
389     QModelIndex aFirstIdx = aParent.child(0, 0);
390     QModelIndex aLastIdx = aParent.child(aRows - 1, 2);
391     dataChanged(aFirstIdx, aLastIdx);
392   }
393 }
394
395
396 //******************************************************
397 DocumentPtr XGUI_DataModel::document(const QModelIndex& theIndex) const
398 {
399   ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
400   return aNode->document();
401 }