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),
39 myActivePartId(-1), myHistoryBackOffset(0)
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->setPartId(anId);
86 myPartModels[anId] = 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
129 foreach (int aId, myPartModels.keys()) {
130 aObj = aDoc->object(ModelAPI_Feature::group(), aId);
132 aFeature = ModelAPI_Feature::feature(aObj);
133 if (aFeature.get()) {
134 if (aFeature->getKind() == PartSetPlugin_Part::ID())
143 int aStart = myPartModels.size() - 1;
144 removeSubModel(aDelId);
145 removeRow(aStart, partFolderNode(0));
147 } else { // Update top groups (other except parts
148 QModelIndex aIndex = myModel->findGroup(aGroup);
149 int aStart = myModel->rowCount(aIndex);
150 aIndex = createIndex(aIndex.row(), aIndex.column(), (void*) getModelIndex(aIndex));
151 removeRow(aStart, aIndex);
154 PartSet_PartModel* aPartModel = 0;
155 foreach (PartSet_PartModel* aPart, myPartModels) {
156 if (aPart->hasDocument(aDoc)) {
162 QModelIndex aIndex = aPartModel->findGroup(aGroup);
163 int aStart = aPartModel->rowCount(aIndex);
164 aIndex = createIndex(aIndex.row(), aIndex.column(), (void*) getModelIndex(aIndex));
165 removeRow(aStart, aIndex);
169 // Deleted object event ***********************
170 } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {
171 //std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg = std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
172 //ObjectPtr aFeature = aUpdMsg->feature();
173 //DocumentPtr aDoc = aFeature->document();
175 // TODO: Identify the necessary index by the modified feature
177 emit dataChanged(aIndex, aIndex);
179 // Reset whole tree **************************
180 } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) {
181 std::shared_ptr<Config_FeatureMessage> aFeatureMsg =
182 std::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
183 if (!aFeatureMsg->isInternal()) {
184 ActionInfo aFeatureInfo;
185 aFeatureInfo.initFrom(aFeatureMsg);
186 // Remember features icons
187 myIcons[QString::fromStdString(aFeatureMsg->id())] = aFeatureInfo.iconFile;
194 void PartSet_DocumentDataModel::rebuildDataTree()
196 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
201 // Delete extra models
205 foreach (int aId, myPartModels.keys()) {
206 aObj = aRootDoc->object(ModelAPI_Feature::group(), aId);
208 aFeature = ModelAPI_Feature::feature(aObj);
209 if (aFeature.get()) {
210 if (aFeature->getKind() == PartSetPlugin_Part::ID())
214 aDelList.append(aId);
217 foreach (int aId, aDelList) {
220 // Add non existing models
221 int aHistNb = aRootDoc->size(ModelAPI_Feature::group());
222 for (int i = 0; i < aHistNb; i++) {
223 aObj = aRootDoc->object(ModelAPI_Feature::group(), i);
224 aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
225 if (aFeature->getKind() == PartSetPlugin_Part::ID()) {
226 if (!myPartModels.contains(i)) {
227 PartSet_PartDataModel* aModel = new PartSet_PartDataModel(this);
228 aModel->setPartId(i);
229 myPartModels[i] = aModel;
236 QVariant PartSet_DocumentDataModel::data(const QModelIndex& theIndex, int theRole) const
238 if (!theIndex.isValid())
241 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
242 QModelIndex aParent = theIndex.parent();
243 if ((theIndex.column() == 1) ) {
244 if ((theIndex.internalId() >= PartsFolder) && (theIndex.internalId() <= PartResult)) {
245 if (ModelAPI_Session::get()->activeDocument() == aRootDoc) {
246 if ((theIndex.internalId() == HistoryNode) && (!aParent.isValid())) {
248 case Qt::DecorationRole:
249 if (theIndex.row() == lastHistoryRow())
250 return QIcon(":pictures/arrow.png");
255 QModelIndex* aIndex = toSourceModelIndex(theIndex);
256 const QAbstractItemModel* aModel = aIndex->model();
257 if (isPartSubModel(aModel)) {
258 return aModel->data(*aIndex, theRole);
264 switch (theIndex.internalId()) {
267 case Qt::DisplayRole:
268 return tr("Parts") + QString(" (%1)").arg(rowCount(theIndex));
269 case Qt::DecorationRole:
270 return QIcon(":pictures/constr_folder.png");
271 case Qt::ToolTipRole:
272 return tr("Parts folder");
273 case Qt::ForegroundRole:
274 if (myActivePartIndex.isValid())
275 return QBrush(PASSIVE_COLOR);
277 return QBrush(ACTIVE_COLOR);
284 int aOffset = historyOffset();
285 ObjectPtr aObj = aRootDoc->object(ModelAPI_Feature::group(), theIndex.row() - aOffset);
286 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
290 case Qt::DisplayRole:
292 return aFeature->data()->name().c_str();
295 case Qt::DecorationRole:
296 return featureIcon(aFeature);
297 case Qt::ToolTipRole:
298 return tr("Feature object");
299 case Qt::ForegroundRole:
300 if (theIndex.row() > lastHistoryRow())
301 return QBrush(Qt::lightGray);
303 if (myActivePartIndex.isValid())
304 return QBrush(PASSIVE_COLOR);
306 return QBrush(ACTIVE_COLOR);
315 ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), theIndex.row());
318 case Qt::DisplayRole:
319 return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
320 case Qt::DecorationRole:
321 return QIcon(":pictures/part_ico.png");
322 case Qt::ForegroundRole:
324 if (theIndex == myActivePartIndex)
325 return QBrush(ACTIVE_COLOR);
327 return QBrush(PASSIVE_COLOR);
336 if (aParent.internalId() == HistoryNode) {
337 int aId = aParent.row() - historyOffset();
338 QModelIndex* aIndex = toSourceModelIndex(theIndex);
339 return myPartModels[aId]->data(*aIndex, theRole);
341 return toSourceModelIndex(theIndex)->data(theRole);
344 QVariant PartSet_DocumentDataModel::headerData(int theSection, Qt::Orientation theOrient,
350 int PartSet_DocumentDataModel::rowCount(const QModelIndex& theParent) const
352 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
353 if (!theParent.isValid()) {
354 // Size of external models
355 int aVal = historyOffset();
357 aVal += aRootDoc->size(ModelAPI_Feature::group());
360 if (theParent.internalId() == PartsFolder) {
361 return aRootDoc->size(ModelAPI_ResultPart::group());
362 //int aSize = myPartModels.size();
363 //return myPartModels.size();
365 if (theParent.internalId() == HistoryNode) {
366 int aId = theParent.row() - historyOffset();
367 if (myPartModels.contains(aId))
368 return myPartModels[aId]->rowCount(QModelIndex());
371 if (theParent.internalId() == PartResult)
374 QModelIndex* aParent = toSourceModelIndex(theParent);
375 const QAbstractItemModel* aModel = aParent->model();
376 if (!isSubModel(aModel))
379 /*if (isPartSubModel(aModel)) {
380 if (aModel != myActivePart)
383 return aModel->rowCount(*aParent);
386 int PartSet_DocumentDataModel::columnCount(const QModelIndex& theParent) const
391 QModelIndex PartSet_DocumentDataModel::index(int theRow, int theColumn,
392 const QModelIndex& theParent) const
395 if (!theParent.isValid()) {
396 int aOffs = myModel->rowCount();
397 if (theRow < aOffs) {
398 aIndex = myModel->index(theRow, theColumn, theParent);
399 aIndex = createIndex(theRow, theColumn, (void*) getModelIndex(aIndex));
401 if (theRow == aOffs) // Create Parts node
402 aIndex = partFolderNode(theColumn);
404 // create history node
405 aIndex = createIndex(theRow, theColumn, HistoryNode);
409 if (theParent.internalId() == PartsFolder) {
410 aIndex = createIndex(theRow, theColumn, PartResult);
412 if (theParent.internalId() == HistoryNode) {
413 int aId = theParent.row() - historyOffset();
414 aIndex = myPartModels[aId]->index(theRow, theColumn, QModelIndex());
416 QModelIndex* aParent = (QModelIndex*) theParent.internalPointer();
417 aIndex = aParent->model()->index(theRow, theColumn, (*aParent));
419 aIndex = createIndex(theRow, theColumn, (void*) getModelIndex(aIndex));
425 QModelIndex PartSet_DocumentDataModel::parent(const QModelIndex& theIndex) const
427 if ((theIndex.internalId() == PartsFolder) || (theIndex.internalId() == HistoryNode))
428 return QModelIndex();
430 if (theIndex.internalId() == PartResult)
431 return partFolderNode(0);
433 QModelIndex* aIndex = toSourceModelIndex(theIndex);
434 const QAbstractItemModel* aModel = aIndex->model();
435 if (!isSubModel(aModel))
436 return QModelIndex();
438 QModelIndex aIndex1 = aModel->parent(*aIndex);
439 if (isPartSubModel(aModel) && (!aIndex1.isValid())) {
440 int aId = myPartModels.key((PartSet_PartModel*) aModel);
441 int aRow = aId + historyOffset();
442 return createIndex(aRow, 0, (qint32) HistoryNode);
445 if (aIndex1.isValid())
446 return createIndex(aIndex1.row(), 0, (void*) getModelIndex(aIndex1));
450 bool PartSet_DocumentDataModel::hasChildren(const QModelIndex& theParent) const
452 if (!theParent.isValid())
454 return rowCount(theParent) > 0;
457 QModelIndex* PartSet_DocumentDataModel::toSourceModelIndex(const QModelIndex& theProxy) const
459 QModelIndex* aIndexPtr = static_cast<QModelIndex*>(theProxy.internalPointer());
463 QModelIndex* PartSet_DocumentDataModel::findModelIndex(const QModelIndex& theIndex) const
465 QList<QModelIndex*>::const_iterator aIt;
466 for (aIt = myIndexes.constBegin(); aIt != myIndexes.constEnd(); ++aIt) {
467 QModelIndex* aIndex = (*aIt);
468 if ((*aIndex) == theIndex)
474 QModelIndex* PartSet_DocumentDataModel::getModelIndex(const QModelIndex& theIndex) const
476 QModelIndex* aIndexPtr = findModelIndex(theIndex);
478 aIndexPtr = new QModelIndex(theIndex);
479 PartSet_DocumentDataModel* that = (PartSet_DocumentDataModel*) this;
480 that->myIndexes.append(aIndexPtr);
485 void PartSet_DocumentDataModel::clearModelIndexes()
487 foreach (QModelIndex* aIndex, myIndexes)
492 void PartSet_DocumentDataModel::clearSubModels()
494 foreach (PartSet_PartModel* aPart, myPartModels)
496 myPartModels.clear();
499 ObjectPtr PartSet_DocumentDataModel::object(const QModelIndex& theIndex) const
501 if (theIndex.internalId() == PartsFolder)
503 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
504 if (theIndex.internalId() == HistoryNode) {
505 int aOffset = historyOffset();
506 return aRootDoc->object(ModelAPI_Feature::group(), theIndex.row() - aOffset);
508 if (theIndex.internalId() == PartResult) {
509 return aRootDoc->object(ModelAPI_ResultPart::group(), theIndex.row());
511 QModelIndex* aIndex = toSourceModelIndex(theIndex);
512 if (!isSubModel(aIndex->model()))
515 const PartSet_FeaturesModel* aModel = dynamic_cast<const PartSet_FeaturesModel*>(aIndex->model());
516 return aModel->object(*aIndex);
519 bool PartSet_DocumentDataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
521 beginInsertRows(theParent, theRow, theRow + theCount - 1);
526 int aRow = rowCount(aRoot);
527 beginInsertRows(aRoot, aRow, aRow);
533 bool PartSet_DocumentDataModel::removeRows(int theRow, int theCount, const QModelIndex& theParent)
535 beginRemoveRows(theParent, theRow, theRow + theCount - 1);
540 void PartSet_DocumentDataModel::removeSubModel(int theModelId)
542 PartSet_PartModel* aModel = myPartModels[theModelId];
544 for (int i = 0; i < myIndexes.size(); i++) {
545 if (myIndexes.at(i)->model() == aModel)
549 while (aToRemove.size() > 0) {
550 aId = aToRemove.last();
551 delete myIndexes.at(aId);
552 myIndexes.removeAt(aId);
553 aToRemove.removeLast();
556 myPartModels.remove(theModelId);
559 bool PartSet_DocumentDataModel::isSubModel(const QAbstractItemModel* theModel) const
561 if (theModel == myModel)
563 return isPartSubModel(theModel);
566 bool PartSet_DocumentDataModel::isPartSubModel(const QAbstractItemModel* theModel) const
568 return myPartModels.key((PartSet_PartModel*) theModel, -1) != -1;
571 QModelIndex PartSet_DocumentDataModel::partFolderNode(int theColumn) const
573 int aPos = myModel->rowCount(QModelIndex());
574 return createIndex(aPos, theColumn, PartsFolder);
577 int PartSet_DocumentDataModel::historyOffset() const
579 // Nb of rows of top model + Parts folder
580 return myModel->rowCount(QModelIndex()) + 1;
583 bool PartSet_DocumentDataModel::activatePart(const QModelIndex& theIndex)
585 if ((theIndex.internalId() == PartsFolder) || (theIndex.internalId() == HistoryNode))
588 if (theIndex.isValid() && (theIndex.internalId() == PartResult)) {
589 myActivePartIndex = theIndex;
590 myModel->setItemsColor(PASSIVE_COLOR);
591 if (myActivePartId != -1)
592 myPartModels[myActivePartId]->setItemsColor(PASSIVE_COLOR);
594 // Find activated part feature by its ID
595 ResultPartPtr aPartRes = activePart();
596 FeaturePtr aFeature = ModelAPI_Feature::feature(aPartRes);
597 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
598 myActivePartId = aRootDoc->index(aFeature);
599 myPartModels[myActivePartId]->setItemsColor(ACTIVE_COLOR);
601 //QModelIndex* aIndex = toSourceModelIndex(theIndex);
605 //const QAbstractItemModel* aModel = aIndex->model();
607 //if (isPartSubModel(aModel)) {
608 // // if this is root node (Part item index)
609 // if (!aIndex->parent().isValid()) {
611 // myActivePart->setItemsColor(PASSIVE_COLOR);
613 // if (myActivePart == aModel) {
615 // myActivePartIndex = QModelIndex();
617 // myActivePart = (PartSet_PartModel*)aModel;
618 // myActivePartIndex = theIndex;
621 // if (myActivePart) {
622 // myActivePart->setItemsColor(ACTIVE_COLOR);
623 // myModel->setItemsColor(PASSIVE_COLOR);
625 // myModel->setItemsColor(ACTIVE_COLOR);
632 ResultPartPtr PartSet_DocumentDataModel::activePart() const
634 if (myActivePartIndex.isValid()) {
635 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
636 ObjectPtr aObj = aRootDoc->object(ModelAPI_ResultPart::group(), myActivePartIndex.row());
637 return std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
639 return ResultPartPtr();
642 QModelIndex PartSet_DocumentDataModel::activePartTree() const
644 if (myActivePartId != -1) {
645 return createIndex(myActivePartId + historyOffset(), 0, HistoryNode);
647 return QModelIndex();
650 void PartSet_DocumentDataModel::deactivatePart()
652 if (myActivePartIndex.isValid()) {
653 if (myActivePartId != -1)
654 myPartModels[myActivePartId]->setItemsColor(PASSIVE_COLOR);
656 myActivePartIndex = QModelIndex();
657 myModel->setItemsColor(ACTIVE_COLOR);
661 Qt::ItemFlags PartSet_DocumentDataModel::flags(const QModelIndex& theIndex) const
663 if ((theIndex.internalId() >= PartsFolder) && (theIndex.internalId() <= PartResult)) {
664 Qt::ItemFlags aFlags = Qt::ItemIsSelectable;
665 if (object(theIndex)) {
666 aFlags |= Qt::ItemIsEditable;
668 // Disable items which are below of last history row
669 // Do not disable second column
670 if (theIndex.internalId() == HistoryNode) {
671 if (theIndex.row() <= lastHistoryRow() || (theIndex.column() == 1))
672 aFlags |= Qt::ItemIsEnabled;
674 aFlags |= Qt::ItemIsEnabled;
677 QModelIndex* aIndex = toSourceModelIndex(theIndex);
678 const QAbstractItemModel* aModel = aIndex->model();
679 return aModel->flags(*aIndex);
683 QModelIndex PartSet_DocumentDataModel::partIndex(const ResultPartPtr& theObject) const
685 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
686 int aNb = aRootDoc->size(ModelAPI_ResultPart::group());
687 for (int aId = 0; aId < aNb; aId++) {
688 if (theObject == aRootDoc->object(ModelAPI_ResultPart::group(), aId))
689 return createIndex(aId, 0, PartResult);
691 return QModelIndex();
694 QModelIndex PartSet_DocumentDataModel::objectIndex(const ObjectPtr theObject) const
696 // Check that this feature belongs to root document
697 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
698 DocumentPtr aDoc = theObject->document();
699 if (aDoc == aRootDoc) {
700 // This feature belongs to histrory or top model
701 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
704 int aNb = aRootDoc->size(ModelAPI_Feature::group());
705 for (aId = 0; aId < aNb; aId++) {
706 if (theObject == aRootDoc->object(ModelAPI_Feature::group(), aId))
710 return index(aId + historyOffset(), 0, QModelIndex());
712 QModelIndex aIndex = myModel->objectIndex(theObject);
715 createIndex(aIndex.row(), 0, (void*) getModelIndex(aIndex)) :
719 PartSet_PartModel* aPartModel = 0;
720 foreach(PartSet_PartModel* aModel, myPartModels) {
721 if (aModel->hasDocument(aDoc)) {
727 QModelIndex aIndex = aPartModel->objectIndex(theObject);
728 return aIndex.isValid() ?
729 createIndex(aIndex.row(), 0, (void*) getModelIndex(aIndex)) :
733 return QModelIndex();
737 void PartSet_DocumentDataModel::clear()
742 myActivePartIndex = QModelIndex();
743 myModel->setItemsColor(ACTIVE_COLOR);
746 int PartSet_DocumentDataModel::lastHistoryRow() const
748 return rowCount() - 1 - myHistoryBackOffset;
751 void PartSet_DocumentDataModel::setLastHistoryItem(const QModelIndex& theIndex)
753 myHistoryBackOffset = rowCount() - 1 - theIndex.row();
756 QModelIndex PartSet_DocumentDataModel::lastHistoryItem() const
758 return index(lastHistoryRow(), 1);
762 QIcon PartSet_DocumentDataModel::featureIcon(const FeaturePtr& theFeature)
766 std::string aKind = theFeature->getKind();
767 QString aId(aKind.c_str());
768 if (!myIcons.contains(aId))
771 QString anIconString = myIcons[aId];
773 ModelAPI_ExecState aState = theFeature->data()->execState();
775 case ModelAPI_StateDone:
776 case ModelAPI_StateNothing: {
777 anIcon = QIcon(anIconString);
780 case ModelAPI_StateMustBeUpdated: {
781 anIcon = ModuleBase_Tools::lighter(anIconString);
784 case ModelAPI_StateExecFailed: {
785 anIcon = ModuleBase_Tools::composite(":icons/exec_state_failed.png", anIconString);
788 case ModelAPI_StateInvalidArgument: {
789 anIcon = ModuleBase_Tools::composite(":icons/exec_state_invalid_parameters.png",
798 void PartSet_DocumentDataModel::onMouseDoubleClick(const QModelIndex& theIndex)
800 QTreeView* aTreeView = dynamic_cast<QTreeView*>(sender());
801 if ((theIndex.internalId() >= PartsFolder) && (theIndex.internalId() <= PartResult)) {
802 if ((theIndex.column() == 1) && (theIndex.internalId() == HistoryNode)) {
803 int aOldId = lastHistoryRow();
804 setLastHistoryItem(theIndex);
805 int aStartRow = std::min(aOldId, theIndex.row());
806 int aEndRow = std::max(aOldId, theIndex.row());
807 for (int i = aStartRow; i <= aEndRow; i++) {
808 aTreeView->update(createIndex(i, 0, HistoryNode));
809 aTreeView->update(createIndex(i, 1, HistoryNode));
813 QModelIndex* aIndex = toSourceModelIndex(theIndex);
814 const QAbstractItemModel* aModel = aIndex->model();
815 if (isPartSubModel(aModel)) {
816 PartSet_PartDataModel* aPartModel = (PartSet_PartDataModel*)aModel;
817 QModelIndex aOldItem = aPartModel->lastHistoryItem();
818 aPartModel->setLastHistoryItem(*aIndex);
819 QModelIndex aOldIndex = createIndex(aOldItem.row(), aOldItem.column(), (void*) getModelIndex(aOldItem));
820 int aStartRow = std::min(aOldItem.row(), aIndex->row());
821 int aEndRow = std::max(aOldItem.row(), aIndex->row());
822 for (int i = aStartRow; i <= aEndRow; i++) {
823 QModelIndex aInd1 = aPartModel->index(i, 0);
824 QModelIndex aInd2 = createIndex(i, 0, (void*) getModelIndex(aInd1));
825 aTreeView->update(aInd2);
826 aInd1 = aPartModel->index(i, 1);
827 aInd2 = createIndex(i, 1, (void*) getModelIndex(aInd1));
828 aTreeView->update(aInd2);