1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "XGUI_DataModel.h"
22 #include "XGUI_ObjectsBrowser.h"
24 #include <ModuleBase_IconFactory.h>
25 #include <ModuleBase_ITreeNode.h>
27 #include <ModelAPI_Session.h>
29 #include <Config_FeatureMessage.h>
31 #include <Events_Loop.h>
37 // Constructor *************************************************
38 XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent)//,
39 //myIsEventsProcessingBlocked(false)
41 XGUI_ObjectsBrowser* aOB = qobject_cast<XGUI_ObjectsBrowser*>(theParent);
42 myWorkshop = aOB->workshop();
44 Events_Loop* aLoop = Events_Loop::loop();
45 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
46 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
47 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
48 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_ORDER_UPDATED));
49 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED));
52 XGUI_DataModel::~XGUI_DataModel()
57 //******************************************************
58 void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMessage)
60 if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
61 std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
62 std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
63 std::set<ObjectPtr> aObjects = aUpdMsg->objects();
64 QObjectPtrList aCreated;
65 std::set<ObjectPtr>::const_iterator aIt;
66 for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) {
67 if ((*aIt)->isInHistory())
68 aCreated.append(*aIt);
70 QTreeNodesList aNodes = myRoot->objectCreated(aCreated);
71 ModuleBase_ITreeNode* aParent;
73 QModelIndex aParentIndex1, aParentIndex2;
74 foreach(ModuleBase_ITreeNode* aNode, aNodes) {
75 aParent = aNode->parent();
76 aRow = aParent->nodeRow(aNode);
77 aParentIndex1 = getParentIndex(aNode, 0);
78 aParentIndex2 = getParentIndex(aNode, 2);
79 insertRows(aRow, 1, aParentIndex1);
80 dataChanged(aParentIndex1, aParentIndex2);
83 else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
84 std::shared_ptr<ModelAPI_ObjectDeletedMessage> aUpdMsg =
85 std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
86 const std::list<std::pair<std::shared_ptr<ModelAPI_Document>, std::string>>& aMsgGroups =
88 std::list<std::pair<std::shared_ptr<ModelAPI_Document>, std::string>>::const_iterator aIt;
89 for (aIt = aMsgGroups.cbegin(); aIt != aMsgGroups.cend(); aIt++)
90 QTreeNodesList aList = myRoot->objectsDeleted(aIt->first, aIt->second.c_str());
93 else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {
94 std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
95 std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
96 std::set<ObjectPtr> aObjects = aUpdMsg->objects();
98 QObjectPtrList aCreated;
99 std::set<ObjectPtr>::const_iterator aIt;
100 bool aRebuildAll = false;
101 for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) {
102 ObjectPtr aObj = (*aIt);
103 if (!aObj->isInHistory())
106 if (aObj->data()->isValid()) {
107 if (aObj->groupName() == ModelAPI_Folder::group()) {
111 aCreated.append(*aIt);
118 foreach(ObjectPtr aObj, aCreated) {
119 ModuleBase_ITreeNode* aNode = myRoot->subNode(aObj);
121 QModelIndex aFirstIdx = getIndex(aNode, 0);
122 QModelIndex aLastIdx = getIndex(aNode, 2);
123 dataChanged(aFirstIdx, aLastIdx);
128 else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) {
129 std::shared_ptr<ModelAPI_OrderUpdatedMessage> aUpdMsg =
130 std::dynamic_pointer_cast<ModelAPI_OrderUpdatedMessage>(theMessage);
131 if (aUpdMsg->reordered().get()) {
132 DocumentPtr aDoc = aUpdMsg->reordered()->document();
133 std::string aGroup = aUpdMsg->reordered()->group();
134 ModuleBase_ITreeNode* aNode = myRoot->findParent(aDoc, aGroup.c_str());
137 updateSubTree(aNode);
141 else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
142 DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument();
143 ModuleBase_ITreeNode* aRoot = myRoot->findRoot(aDoc);
145 updateSubTree(aRoot);
150 //******************************************************
151 void XGUI_DataModel::clear()
157 //******************************************************
158 void XGUI_DataModel::rebuildDataTree()
165 //******************************************************
166 ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const
168 if (theIndex.isValid()) {
169 ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
170 return aNode->object();
175 //******************************************************
176 QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn) const
178 ModuleBase_ITreeNode* aNode = myRoot->subNode(theObject);
180 return getIndex(aNode, theColumn);
182 return QModelIndex();
185 //******************************************************
186 QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
188 if (theIndex.isValid()) {
189 ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
190 return aNode->data(theIndex.column(), theRole);
195 //******************************************************
196 QVariant XGUI_DataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
201 //******************************************************
202 int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
204 ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
205 (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
206 return aParentNode->childrenCount();
209 //******************************************************
210 int XGUI_DataModel::columnCount(const QModelIndex& theParent) const
215 //******************************************************
216 QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
218 int aa = theParent.row();
219 ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
220 (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
221 ModuleBase_ITreeNode* aSubNode = aParentNode->subNode(theRow);
223 return createIndex(theRow, theColumn, aSubNode);
226 //******************************************************
227 QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
229 if (theIndex.isValid()) {
230 ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
231 return getParentIndex(aNode, 1);
233 return QModelIndex();
236 //******************************************************
237 bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const
239 ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ?
240 (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot;
241 return aParentNode->childrenCount() > 0;
244 //******************************************************
245 bool XGUI_DataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
247 beginInsertRows(theParent, theRow, theRow + theCount - 1);
252 //******************************************************
253 bool XGUI_DataModel::removeRows(int theRow, int theCount, const QModelIndex& theParent)
255 beginRemoveRows(theParent, theRow, theRow + theCount - 1);
260 //******************************************************
261 Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const
263 if (theIndex.isValid()) {
264 ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
265 return aNode->flags(theIndex.column());
267 return Qt::ItemFlags();
271 //******************************************************
272 QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) const
274 SessionPtr aSession = ModelAPI_Session::get();
275 DocumentPtr aRootDoc = aSession->moduleDocument();
276 if (theDoc == aRootDoc)
277 return QModelIndex();
279 ModuleBase_ITreeNode* aDocNode = 0;
280 foreach(ModuleBase_ITreeNode* aNode, myRoot->children()) {
281 if (aNode->document() == theDoc) {
287 return getIndex(aDocNode, theColumn);
289 return QModelIndex();
292 //******************************************************
293 bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex)
295 if (theIndex.isValid()) {
296 ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
297 return aNode->visibilityState() == ModuleBase_ITreeNode::Hidden;
302 //******************************************************
303 bool XGUI_DataModel::hasIndex(const QModelIndex& theIndex) const
305 ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer();
306 return myRoot->hasSubNode(aNode);
309 //******************************************************
310 QModelIndex XGUI_DataModel::getParentIndex(ModuleBase_ITreeNode* theNode, int thCol) const
312 ModuleBase_ITreeNode* aParent = theNode->parent();
313 if (aParent == myRoot) {
314 return QModelIndex();
316 return getIndex(aParent, thCol);
320 //******************************************************
321 QModelIndex XGUI_DataModel::getIndex(ModuleBase_ITreeNode* theNode, int thCol) const
323 if (theNode == myRoot)
324 return QModelIndex();
325 int aRow = theNode->parent()->nodeRow(theNode);
326 return createIndex(aRow, thCol, theNode);
330 //******************************************************
331 void XGUI_DataModel::updateSubTree(ModuleBase_ITreeNode* theParent)
333 int aRows = theParent->childrenCount();
335 QModelIndex aParent = getIndex(theParent, 0);
336 QModelIndex aFirstIdx = aParent.child(0, 0);
337 QModelIndex aLastIdx = aParent.child(aRows - 1, 2);
338 dataChanged(aFirstIdx, aLastIdx);