1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 #include "PartSet_DocumentDataModel.h"
4 #include "PartSet_PartDataModel.h"
5 #include "PartSet_Module.h"
6 //#include "XGUI_Tools.h"
8 #include <ModelAPI_Session.h>
9 #include <ModelAPI_Document.h>
10 #include <ModelAPI_Feature.h>
11 #include <ModelAPI_Data.h>
12 #include <ModelAPI_ResultPart.h>
13 #include <ModelAPI_Events.h>
14 #include <ModelAPI_Object.h>
16 #include <Events_Loop.h>
18 #include <Config_FeatureMessage.h>
19 #include <ModuleBase_Tools.h>
20 #include <ModuleBase_ActionInfo.h>
22 #include <PartSetPlugin_Part.h>
31 #define ACTIVE_COLOR QColor(0,72,140)
32 #define PASSIVE_COLOR Qt::black
34 QMap<QString, QString> PartSet_DocumentDataModel::myIcons;
37 PartSet_DocumentDataModel::PartSet_DocumentDataModel(QObject* theParent)
38 : ModuleBase_IDocumentDataModel(theParent),
41 // Create a top part of data tree model
42 myModel = new PartSet_TopDataModel(this);
43 myModel->setItemsColor(ACTIVE_COLOR);
45 Events_Loop* aLoop = Events_Loop::loop();
46 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
47 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
48 aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
49 aLoop->registerListener(this, Events_Loop::eventByName(Config_FeatureMessage::GUI_EVENT()));
52 PartSet_DocumentDataModel::~PartSet_DocumentDataModel()
58 void PartSet_DocumentDataModel::processEvent(const std::shared_ptr<Events_Message>& theMessage)
60 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
63 // Created object event *******************
64 if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
65 std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
66 std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
67 std::set<ObjectPtr> aObjects = aUpdMsg->objects();
69 std::set<ObjectPtr>::const_iterator aIt;
70 for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
71 ObjectPtr aObject = (*aIt);
72 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
73 if (aFeature && (!aFeature->isInHistory()))
76 DocumentPtr aDoc = aObject->document();
77 if (aDoc == aRootDoc) { // If root objects
78 if (aObject->groupName() == ModelAPI_ResultPart::group()) { // Update only Parts group
80 int aStart = aRootDoc->size(ModelAPI_ResultPart::group());
82 FeaturePtr aPartFeature = ModelAPI_Feature::feature(aObject);
83 PartSet_PartDataModel* aModel = new PartSet_PartDataModel(this);
84 int anId = aRootDoc->index(aPartFeature);
85 aModel->setPart(aPartFeature);
86 myPartModels.append(aModel);
87 insertRow(aStart, partFolderNode(0));
89 } else { // Update top groups (other except parts
90 QModelIndex aIndex = myModel->findParent(aObject);
91 int aStart = myModel->rowCount(aIndex) - 1;
94 aIndex = createIndex(aIndex.row(), aIndex.column(), (void*) getModelIndex(aIndex));
95 insertRow(aStart, aIndex);
97 } else { // if sub-objects of first level nodes
98 PartSet_PartModel* aPartModel = 0;
99 foreach (PartSet_PartModel* aPart, myPartModels) {
100 if (aPart->hasDocument(aDoc)) {
106 QModelIndex aIndex = aPartModel->findParent(aObject);
107 int aStart = aPartModel->rowCount(aIndex); // check this index
108 aIndex = createIndex(aIndex.row(), aIndex.column(), (void*) getModelIndex(aIndex));
109 insertRow(aStart, aIndex);
114 // Deleted object event ***********************
115 } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
116 std::shared_ptr<ModelAPI_ObjectDeletedMessage> aUpdMsg =
117 std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
118 DocumentPtr aDoc = aUpdMsg->document();
119 std::set<std::string> aGroups = aUpdMsg->groups();
121 std::set<std::string>::const_iterator aIt;
122 for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) {
123 std::string aGroup = (*aIt);
124 if (aDoc == aRootDoc) { // If root objects
125 if (aGroup == ModelAPI_ResultPart::group()) { // Update only Parts group
126 PartSet_PartModel* aDelPartModel = 0;
127 foreach (PartSet_PartModel* aPartModel, myPartModels) {
128 if (aPartModel->position() == -1) {
129 aDelPartModel = aPartModel;
135 int aStart = myPartModels.size() - 1;
136 removeSubModel(aDelPartModel);
137 removeRow(aStart, partFolderNode(0));
139 } if (aGroup == ModelAPI_Feature::group()) { // Update History node
140 int aRow = historyOffset() + aRootDoc->size(ModelAPI_Feature::group());
142 } else { // Update top groups (other except parts
143 QModelIndex aIndex = myModel->findGroup(aGroup);
144 int aStart = myModel->rowCount(aIndex);
145 aIndex = createIndex(aIndex.row(), aIndex.column(), (void*) getModelIndex(aIndex));
146 removeRow(aStart, aIndex);
149 PartSet_PartModel* aPartModel = 0;
150 foreach (PartSet_PartModel* aPart, myPartModels) {
151 if (aPart->hasDocument(aDoc)) {
157 QModelIndex aIndex = aPartModel->findGroup(aGroup);
158 if (aIndex.isValid()) {
159 int aStart = aPartModel->rowCount(aIndex);
160 aIndex = createIndex(aIndex.row(), aIndex.column(), (void*) getModelIndex(aIndex));
161 removeRow(aStart, aIndex);
163 int aRow = aPartModel->rowCount();
164 aIndex = createIndex(aPartModel->position() + historyOffset(), 0, HistoryNode);
165 removeRow(aRow, aIndex);
170 // Deleted object event ***********************
171 } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {
172 //std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg = std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
173 //ObjectPtr aFeature = aUpdMsg->feature();
174 //DocumentPtr aDoc = aFeature->document();
176 // TODO: Identify the necessary index by the modified feature
178 emit dataChanged(aIndex, aIndex);
180 // Reset whole tree **************************
181 } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) {
182 std::shared_ptr<Config_FeatureMessage> aFeatureMsg =
183 std::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
184 if (!aFeatureMsg->isInternal()) {
185 ActionInfo aFeatureInfo;
186 aFeatureInfo.initFrom(aFeatureMsg);
187 // Remember features icons
188 myIcons[QString::fromStdString(aFeatureMsg->id())] = aFeatureInfo.iconFile;
195 void PartSet_DocumentDataModel::rebuildDataTree()
197 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
202 // Delete extra models
205 QList<PartSet_PartModel*> aDelList;
206 foreach (PartSet_PartModel* aPartModel, myPartModels) {
207 if (aPartModel->position() == -1)
208 aDelList.append(aPartModel);
210 foreach (PartSet_PartModel* aPartModel, aDelList) {
211 removeSubModel(aPartModel);
213 // Add non existing models
214 int aHistNb = aRootDoc->size(ModelAPI_Feature::group());
215 for (int i = 0; i < aHistNb; i++) {
216 aObj = aRootDoc->object(ModelAPI_Feature::group(), i);
217 aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
218 if (aFeature->getKind() == PartSetPlugin_Part::ID()) {
219 if (!findPartModel(aFeature)) {
220 PartSet_PartDataModel* aModel = new PartSet_PartDataModel(this);
221 aModel->setPart(aFeature);
222 myPartModels.append(aModel);
229 QVariant PartSet_DocumentDataModel::data(const QModelIndex& theIndex, int theRole) const
231 if (!theIndex.isValid())
234 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
235 QModelIndex aParent = theIndex.parent();
236 if ((theIndex.column() == 1) ) {
237 if ((theIndex.internalId() >= PartsFolder) && (theIndex.internalId() <= PartResult)) {
238 if (ModelAPI_Session::get()->activeDocument() == aRootDoc) {
239 if (!aParent.isValid()) {
241 case Qt::DecorationRole:
242 if (theIndex.row() == lastHistoryRow())
243 return QIcon(":pictures/arrow.png");
248 QModelIndex* aIndex = toSourceModelIndex(theIndex);
249 const QAbstractItemModel* aModel = aIndex->model();
250 if (isPartSubModel(aModel)) {
251 return aModel->data(*aIndex, theRole);
257 switch (theIndex.internalId()) {
260 case Qt::DisplayRole:
261 return tr("Parts") + QString(" (%1)").arg(rowCount(theIndex));
262 case Qt::DecorationRole:
263 return QIcon(":pictures/constr_folder.png");
264 case Qt::ToolTipRole:
265 return tr("Parts folder");
266 case Qt::ForegroundRole:
267 if (myActivePartIndex.isValid())
268 return QBrush(PASSIVE_COLOR);
270 return QBrush(ACTIVE_COLOR);
277 int aOffset = historyOffset();
278 ObjectPtr aObj = aRootDoc->object(ModelAPI_Feature::group(), theIndex.row() - aOffset);
279 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
283 case Qt::DisplayRole:
285 return aFeature->data()->name().c_str();
288 case Qt::DecorationRole:
289 return featureIcon(aFeature);
290 case Qt::ToolTipRole:
291 return tr("Feature object");
292 case Qt::ForegroundRole:
293 if (theIndex.row() > lastHistoryRow())
294 return QBrush(Qt::lightGray);
296 if (myActivePartIndex.isValid())
297 return QBrush(PASSIVE_COLOR);
299 return QBrush(ACTIVE_COLOR);
308 ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), theIndex.row());
311 case Qt::DisplayRole:
312 return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
313 case Qt::DecorationRole:
314 return QIcon(":pictures/part_ico.png");
315 case Qt::ForegroundRole:
317 if (theIndex == myActivePartIndex)
318 return QBrush(ACTIVE_COLOR);
320 return QBrush(PASSIVE_COLOR);
329 if (aParent.internalId() == HistoryNode) {
330 int aId = aParent.row() - historyOffset();
331 QModelIndex* aIndex = toSourceModelIndex(theIndex);
332 return findPartModel(aId)->data(*aIndex, theRole);
334 return toSourceModelIndex(theIndex)->data(theRole);
337 QVariant PartSet_DocumentDataModel::headerData(int theSection, Qt::Orientation theOrient,
343 int PartSet_DocumentDataModel::rowCount(const QModelIndex& theParent) const
345 SessionPtr aSession = ModelAPI_Session::get();
346 if (!aSession->hasModuleDocument())
348 DocumentPtr aRootDoc = aSession->moduleDocument();
349 if (!theParent.isValid()) {
350 // Size of external models
351 int aVal = historyOffset();
353 aVal += aRootDoc->size(ModelAPI_Feature::group());
356 if (theParent.internalId() == PartsFolder) {
357 return aRootDoc->size(ModelAPI_ResultPart::group());
358 //int aSize = myPartModels.size();
359 //return myPartModels.size();
361 if (theParent.internalId() == HistoryNode) {
362 int aId = theParent.row() - historyOffset();
363 PartSet_PartModel* aModel = findPartModel(aId);
365 return aModel->rowCount(QModelIndex());
368 if (theParent.internalId() == PartResult)
371 QModelIndex* aParent = toSourceModelIndex(theParent);
372 const QAbstractItemModel* aModel = aParent->model();
373 if (!isSubModel(aModel))
376 /*if (isPartSubModel(aModel)) {
377 if (aModel != myActivePart)
380 return aModel->rowCount(*aParent);
383 int PartSet_DocumentDataModel::columnCount(const QModelIndex& theParent) const
388 QModelIndex PartSet_DocumentDataModel::index(int theRow, int theColumn,
389 const QModelIndex& theParent) const
392 if (!theParent.isValid()) {
393 int aOffs = myModel->rowCount();
394 if (theRow < aOffs) {
395 aIndex = myModel->index(theRow, theColumn, theParent);
396 aIndex = createIndex(theRow, theColumn, (void*) getModelIndex(aIndex));
398 if (theRow == aOffs) // Create Parts node
399 aIndex = partFolderNode(theColumn);
401 // create history node
402 aIndex = createIndex(theRow, theColumn, HistoryNode);
406 if (theParent.internalId() == PartsFolder) {
407 aIndex = createIndex(theRow, theColumn, PartResult);
409 if (theParent.internalId() == HistoryNode) {
410 int aId = theParent.row() - historyOffset();
411 aIndex = findPartModel(aId)->index(theRow, theColumn, QModelIndex());
413 QModelIndex* aParent = (QModelIndex*) theParent.internalPointer();
414 aIndex = aParent->model()->index(theRow, theColumn, (*aParent));
416 aIndex = createIndex(theRow, theColumn, (void*) getModelIndex(aIndex));
422 QModelIndex PartSet_DocumentDataModel::parent(const QModelIndex& theIndex) const
424 if ((theIndex.internalId() == PartsFolder) || (theIndex.internalId() == HistoryNode))
425 return QModelIndex();
427 if (theIndex.internalId() == PartResult)
428 return partFolderNode(0);
430 QModelIndex* aIndex = toSourceModelIndex(theIndex);
431 const QAbstractItemModel* aModel = aIndex->model();
432 if (!isSubModel(aModel))
433 return QModelIndex();
435 QModelIndex aIndex1 = aModel->parent(*aIndex);
436 const PartSet_PartModel* aPartModel = dynamic_cast<const PartSet_PartModel*>(aModel);
437 if (aPartModel && (!aIndex1.isValid())) {
438 int aId = aPartModel->position();
439 int aRow = aId + historyOffset();
440 return createIndex(aRow, 0, (qint32) HistoryNode);
443 if (aIndex1.isValid())
444 return createIndex(aIndex1.row(), 0, (void*) getModelIndex(aIndex1));
448 bool PartSet_DocumentDataModel::hasChildren(const QModelIndex& theParent) const
450 if (!theParent.isValid())
452 return rowCount(theParent) > 0;
455 QModelIndex* PartSet_DocumentDataModel::toSourceModelIndex(const QModelIndex& theProxy) const
457 QModelIndex* aIndexPtr = static_cast<QModelIndex*>(theProxy.internalPointer());
461 QModelIndex* PartSet_DocumentDataModel::findModelIndex(const QModelIndex& theIndex) const
463 QList<QModelIndex*>::const_iterator aIt;
464 for (aIt = myIndexes.constBegin(); aIt != myIndexes.constEnd(); ++aIt) {
465 QModelIndex* aIndex = (*aIt);
466 if ((*aIndex) == theIndex)
472 QModelIndex* PartSet_DocumentDataModel::getModelIndex(const QModelIndex& theIndex) const
474 QModelIndex* aIndexPtr = findModelIndex(theIndex);
476 aIndexPtr = new QModelIndex(theIndex);
477 PartSet_DocumentDataModel* that = (PartSet_DocumentDataModel*) this;
478 that->myIndexes.append(aIndexPtr);
483 void PartSet_DocumentDataModel::clearModelIndexes()
485 foreach (QModelIndex* aIndex, myIndexes)
490 void PartSet_DocumentDataModel::clearSubModels()
492 foreach (PartSet_PartModel* aPart, myPartModels)
494 myPartModels.clear();
495 myActivePartModel = 0;
498 ObjectPtr PartSet_DocumentDataModel::object(const QModelIndex& theIndex) const
500 if (theIndex.internalId() == PartsFolder)
502 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
503 if (theIndex.internalId() == HistoryNode) {
504 int aOffset = historyOffset();
505 return aRootDoc->object(ModelAPI_Feature::group(), theIndex.row() - aOffset);
507 if (theIndex.internalId() == PartResult) {
508 return aRootDoc->object(ModelAPI_ResultPart::group(), theIndex.row());
510 QModelIndex* aIndex = toSourceModelIndex(theIndex);
511 if (!isSubModel(aIndex->model()))
514 const PartSet_FeaturesModel* aModel = dynamic_cast<const PartSet_FeaturesModel*>(aIndex->model());
515 return aModel->object(*aIndex);
518 bool PartSet_DocumentDataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
520 beginInsertRows(theParent, theRow, theRow + theCount - 1);
525 int aRow = rowCount(aRoot);
526 beginInsertRows(aRoot, aRow, aRow);
532 bool PartSet_DocumentDataModel::removeRows(int theRow, int theCount, const QModelIndex& theParent)
534 beginRemoveRows(theParent, theRow, theRow + theCount - 1);
539 void PartSet_DocumentDataModel::removeSubModel(int theModelId)
541 PartSet_PartModel* aModel = myPartModels.at(theModelId);
542 removeSubModel(aModel);
545 void PartSet_DocumentDataModel::removeSubModel(PartSet_PartModel* theModel)
548 for (int i = 0; i < myIndexes.size(); i++) {
549 if (myIndexes.at(i)->model() == theModel)
553 while (aToRemove.size() > 0) {
554 aId = aToRemove.last();
555 delete myIndexes.at(aId);
556 myIndexes.removeAt(aId);
557 aToRemove.removeLast();
559 if (theModel == myActivePartModel)
560 myActivePartModel = 0;
561 myPartModels.removeAll(theModel);
566 bool PartSet_DocumentDataModel::isSubModel(const QAbstractItemModel* theModel) const
568 if (theModel == myModel)
570 return isPartSubModel(theModel);
573 bool PartSet_DocumentDataModel::isPartSubModel(const QAbstractItemModel* theModel) const
575 return myPartModels.contains((PartSet_PartModel*) theModel);
578 QModelIndex PartSet_DocumentDataModel::partFolderNode(int theColumn) const
580 int aPos = myModel->rowCount(QModelIndex());
581 return createIndex(aPos, theColumn, PartsFolder);
584 int PartSet_DocumentDataModel::historyOffset() const
586 // Nb of rows of top model + Parts folder
587 return myModel->rowCount(QModelIndex()) + 1;
590 bool PartSet_DocumentDataModel::activatePart(const QModelIndex& theIndex)
592 if ((theIndex.internalId() == PartsFolder) || (theIndex.internalId() == HistoryNode))
595 if (theIndex.isValid() && (theIndex.internalId() == PartResult)) {
596 myActivePartIndex = theIndex;
597 myModel->setItemsColor(PASSIVE_COLOR);
598 if (myActivePartModel)
599 myActivePartModel->setItemsColor(PASSIVE_COLOR);
601 // Find activated part feature by its ID
602 ResultPartPtr aPartRes = activePart();
603 FeaturePtr aFeature = ModelAPI_Feature::feature(aPartRes);
604 if (aFeature.get()) {
605 myActivePartModel = findPartModel(aFeature);
606 myActivePartModel->setItemsColor(ACTIVE_COLOR);
612 ResultPartPtr PartSet_DocumentDataModel::activePart() const
614 if (myActivePartIndex.isValid()) {
615 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
616 ObjectPtr aObj = aRootDoc->object(ModelAPI_ResultPart::group(), myActivePartIndex.row());
617 return std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
619 return ResultPartPtr();
622 QModelIndex PartSet_DocumentDataModel::activePartTree() const
624 if (myActivePartModel) {
625 return createIndex(myActivePartModel->position() + historyOffset(), 0, HistoryNode);
627 return QModelIndex();
630 void PartSet_DocumentDataModel::deactivatePart()
632 if (myActivePartIndex.isValid()) {
633 if (myActivePartModel)
634 myActivePartModel->setItemsColor(PASSIVE_COLOR);
635 myActivePartModel = 0;
636 myActivePartIndex = QModelIndex();
637 myModel->setItemsColor(ACTIVE_COLOR);
641 Qt::ItemFlags PartSet_DocumentDataModel::flags(const QModelIndex& theIndex) const
643 if ((theIndex.internalId() >= PartsFolder) && (theIndex.internalId() <= PartResult)) {
644 Qt::ItemFlags aFlags = Qt::ItemIsSelectable;
645 if (object(theIndex).get()) {
646 aFlags |= Qt::ItemIsEditable;
648 // Disable items which are below of last history row
649 // Do not disable second column
650 if (theIndex.internalId() == HistoryNode) {
651 if (theIndex.row() <= lastHistoryRow() || (theIndex.column() == 1))
652 aFlags |= Qt::ItemIsEnabled;
654 aFlags |= Qt::ItemIsEnabled;
657 QModelIndex* aIndex = toSourceModelIndex(theIndex);
658 const QAbstractItemModel* aModel = aIndex->model();
659 Qt::ItemFlags aFlags = aModel->flags(*aIndex);
660 if (aModel == myModel) {
661 if (myModel->object(*aIndex).get())
662 aFlags |= Qt::ItemIsEditable;
668 QModelIndex PartSet_DocumentDataModel::partIndex(const ResultPartPtr& theObject) const
670 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
671 int aNb = aRootDoc->size(ModelAPI_ResultPart::group());
672 for (int aId = 0; aId < aNb; aId++) {
673 if (theObject == aRootDoc->object(ModelAPI_ResultPart::group(), aId))
674 return createIndex(aId, 0, PartResult);
676 return QModelIndex();
679 QModelIndex PartSet_DocumentDataModel::objectIndex(const ObjectPtr theObject) const
681 // Check that this feature belongs to root document
682 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
683 DocumentPtr aDoc = theObject->document();
684 if (aDoc == aRootDoc) {
685 // This feature belongs to histrory or top model
686 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
689 int aNb = aRootDoc->size(ModelAPI_Feature::group());
690 for (aId = 0; aId < aNb; aId++) {
691 if (theObject == aRootDoc->object(ModelAPI_Feature::group(), aId))
695 return index(aId + historyOffset(), 0, QModelIndex());
697 QModelIndex aIndex = myModel->objectIndex(theObject);
700 createIndex(aIndex.row(), 0, (void*) getModelIndex(aIndex)) :
704 PartSet_PartModel* aPartModel = 0;
705 foreach(PartSet_PartModel* aModel, myPartModels) {
706 if (aModel->hasDocument(aDoc)) {
712 QModelIndex aIndex = aPartModel->objectIndex(theObject);
713 return aIndex.isValid() ?
714 createIndex(aIndex.row(), 0, (void*) getModelIndex(aIndex)) :
718 return QModelIndex();
722 void PartSet_DocumentDataModel::clear()
727 myActivePartIndex = QModelIndex();
728 myModel->setItemsColor(ACTIVE_COLOR);
731 int PartSet_DocumentDataModel::lastHistoryRow() const
733 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
734 FeaturePtr aFeature = aRootDoc->currentFeature(true);
736 return historyOffset() + aRootDoc->index(aFeature);
738 return historyOffset() - 1;
741 void PartSet_DocumentDataModel::setLastHistoryItem(const QModelIndex& theIndex)
743 SessionPtr aMgr = ModelAPI_Session::get();
744 DocumentPtr aRootDoc = aMgr->moduleDocument();
745 std::string aOpName = tr("History change").toStdString();
746 if (theIndex.internalId() == HistoryNode) {
747 ObjectPtr aObject = object(theIndex);
748 aMgr->startOperation(aOpName);
749 aRootDoc->setCurrentFeature(std::dynamic_pointer_cast<ModelAPI_Feature>(aObject), true);
750 aMgr->finishOperation();
752 aMgr->startOperation(aOpName);
753 aRootDoc->setCurrentFeature(FeaturePtr(), true);
754 aMgr->finishOperation();
758 QModelIndex PartSet_DocumentDataModel::lastHistoryItem() const
760 return index(lastHistoryRow(), 1);
764 QIcon PartSet_DocumentDataModel::featureIcon(const FeaturePtr& theFeature)
768 std::string aKind = theFeature->getKind();
769 QString aId(aKind.c_str());
770 if (!myIcons.contains(aId))
773 QString anIconString = myIcons[aId];
775 ModelAPI_ExecState aState = theFeature->data()->execState();
777 case ModelAPI_StateDone:
778 case ModelAPI_StateNothing: {
779 anIcon = QIcon(anIconString);
782 case ModelAPI_StateMustBeUpdated: {
783 anIcon = ModuleBase_Tools::lighter(anIconString);
786 case ModelAPI_StateExecFailed: {
787 anIcon = ModuleBase_Tools::composite(":icons/exec_state_failed.png", anIconString);
790 case ModelAPI_StateInvalidArgument: {
791 anIcon = ModuleBase_Tools::composite(":icons/exec_state_invalid_parameters.png",
800 void PartSet_DocumentDataModel::onMouseDoubleClick(const QModelIndex& theIndex)
802 if (theIndex.column() != 1)
804 QTreeView* aTreeView = dynamic_cast<QTreeView*>(sender());
805 if ((theIndex.internalId() >= PartsFolder) && (theIndex.internalId() <= PartResult)) {
806 if (myActivePartModel)
807 // It means that the root document is not active
809 QModelIndex aNewIndex;
810 if (theIndex.internalId() == HistoryNode)
811 aNewIndex = theIndex;
812 int aOldId = lastHistoryRow();
813 setLastHistoryItem(theIndex);
814 int aStartRow = std::min(aOldId, theIndex.row());
815 int aEndRow = std::max(aOldId, theIndex.row());
816 for (int i = aStartRow; i <= aEndRow; i++) {
817 aTreeView->update(createIndex(i, 0, HistoryNode));
818 aTreeView->update(createIndex(i, 1, HistoryNode));
822 QModelIndex* aIndex = toSourceModelIndex(theIndex);
823 const QAbstractItemModel* aModel = aIndex->model();
824 if (isPartSubModel(aModel)) {
825 PartSet_PartDataModel* aPartModel = (PartSet_PartDataModel*)aModel;
826 QModelIndex aOldItem = aPartModel->lastHistoryItem();
827 aPartModel->setLastHistoryItem(*aIndex);
828 QModelIndex aOldIndex = createIndex(aOldItem.row(), aOldItem.column(), (void*) getModelIndex(aOldItem));
829 int aStartRow = std::min(aOldItem.row(), aIndex->row());
830 int aEndRow = std::max(aOldItem.row(), aIndex->row());
831 for (int i = aStartRow; i <= aEndRow; i++) {
832 QModelIndex aInd1 = aPartModel->index(i, 0);
833 QModelIndex aInd2 = createIndex(i, 0, (void*) getModelIndex(aInd1));
834 aTreeView->update(aInd2);
835 aInd1 = aPartModel->index(i, 1);
836 aInd2 = createIndex(i, 1, (void*) getModelIndex(aInd1));
837 aTreeView->update(aInd2);
844 PartSet_PartModel* PartSet_DocumentDataModel::findPartModel(FeaturePtr thePart) const
846 foreach (PartSet_PartModel* aModel, myPartModels) {
847 if (aModel->part() == thePart)
853 PartSet_PartModel* PartSet_DocumentDataModel::findPartModel(int thePosition) const
855 foreach (PartSet_PartModel* aModel, myPartModels) {
856 if (aModel->position() == thePosition)