1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 #include "PartSet_PartDataModel.h"
4 #include "PartSet_Module.h"
5 #include "PartSet_DocumentDataModel.h"
7 #include <ModelAPI_Session.h>
8 #include <ModelAPI_Document.h>
9 #include <ModelAPI_Feature.h>
10 #include <ModelAPI_Result.h>
11 #include <ModelAPI_Data.h>
12 #include <ModelAPI_AttributeDocRef.h>
13 #include <ModelAPI_Object.h>
14 #include <ModelAPI_ResultPart.h>
15 #include <ModelAPI_ResultConstruction.h>
16 #include <ModelAPI_ResultParameter.h>
17 #include <ModelAPI_ResultBody.h>
18 #include <ModelAPI_ResultGroup.h>
19 #include <ModelAPI_AttributeDouble.h>
20 #include <ModelAPI_Events.h>
22 #include <Events_Loop.h>
28 PartSet_TopDataModel::PartSet_TopDataModel(QObject* theParent)
29 : PartSet_FeaturesModel(theParent)
33 PartSet_TopDataModel::~PartSet_TopDataModel()
37 QVariant PartSet_TopDataModel::data(const QModelIndex& theIndex, int theRole) const
39 if (theIndex.column() == 1)
45 switch (theIndex.internalId()) {
47 return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex));
49 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
50 ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
52 ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObject);
53 AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
54 QString aVal = QString::number(aValueAttribute->value());
55 QString aTitle = QString(aObject->data()->name().c_str());
56 return aTitle + " = " + aVal;
61 return tr("Constructions") + QString(" (%1)").arg(rowCount(theIndex));
62 case ConstructObject: {
63 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
64 ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultConstruction::group(),
67 return aObject->data()->name().c_str();
71 // return tr("Groups") + QString(" (%1)").arg(rowCount(theIndex));
73 // DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
74 // ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultGroup::group(),
77 // return aObject->data()->name().c_str();
83 case Qt::DecorationRole:
86 switch (theIndex.internalId()) {
88 return QIcon(":pictures/params_folder.png");
90 return QIcon(":pictures/constr_folder.png");
92 return QIcon(":pictures/constr_object.png");
94 // return QIcon(":pictures/constr_folder.png");
102 case Qt::ForegroundRole:
103 return QBrush(myItemsColor);
109 QVariant PartSet_TopDataModel::headerData(int section, Qt::Orientation orientation, int role) const
114 int PartSet_TopDataModel::rowCount(const QModelIndex& theParent) const
116 if (!theParent.isValid())
117 return 2; // In case of groups using it has to be +1
119 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
120 if (theParent.internalId() == ParamsFolder)
121 return aRootDoc->size(ModelAPI_ResultParameter::group());
123 if (theParent.internalId() == ConstructFolder)
124 return aRootDoc->size(ModelAPI_ResultConstruction::group());
126 //if (theParent.internalId() == GroupsFolder)
127 // return aRootDoc->size(ModelAPI_ResultGroup::group());
132 int PartSet_TopDataModel::columnCount(const QModelIndex &parent) const
137 QModelIndex PartSet_TopDataModel::index(int theRow, int theColumn, const QModelIndex& theParent) const
139 if (!theParent.isValid()) {
142 return createIndex(theRow, theColumn, (qint32) ParamsFolder);
144 return createIndex(theRow, theColumn, (qint32) ConstructFolder);
146 // return createIndex(theRow, theColumn, (qint32) GroupsFolder);
149 if (theParent.internalId() == ParamsFolder)
150 return createIndex(theRow, theColumn, (qint32) ParamObject);
152 if (theParent.internalId() == ConstructFolder)
153 return createIndex(theRow, theColumn, (qint32) ConstructObject);
155 //if (theParent.internalId() == GroupsFolder)
156 // return createIndex(theRow, theColumn, (qint32) GroupObject);
158 return QModelIndex();
161 QModelIndex PartSet_TopDataModel::parent(const QModelIndex& theIndex) const
163 int aId = (int) theIndex.internalId();
166 case ConstructFolder:
168 return QModelIndex();
170 return createIndex(0, 0, (qint32) ParamsFolder);
171 case ConstructObject:
172 return createIndex(1, 0, (qint32) ConstructFolder);
174 // return createIndex(2, 0, (qint32) GroupsFolder);
176 return QModelIndex();
179 bool PartSet_TopDataModel::hasChildren(const QModelIndex& theParent) const
181 return rowCount(theParent) > 0;
184 ObjectPtr PartSet_TopDataModel::object(const QModelIndex& theIndex) const
186 switch (theIndex.internalId()) {
188 case ConstructFolder:
191 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
192 return aRootDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
194 case ConstructObject: {
195 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
196 return aRootDoc->object(ModelAPI_ResultConstruction::group(), theIndex.row());
198 //case GroupObject: {
199 // DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
200 // return aRootDoc->object(ModelAPI_ResultGroup::group(), theIndex.row());
206 QModelIndex PartSet_TopDataModel::findParent(const ObjectPtr& theObject) const
208 return findGroup(theObject->groupName().c_str());
211 QModelIndex PartSet_TopDataModel::findGroup(const std::string& theGroup) const
213 if (theGroup == ModelAPI_ResultParameter::group())
214 return createIndex(0, 0, (qint32) ParamsFolder);
215 if (theGroup == ModelAPI_ResultConstruction::group())
216 return createIndex(1, 0, (qint32) ConstructFolder);
217 //if (theGroup == ModelAPI_ResultGroup::group())
218 // return createIndex(2, 0, (qint32) ConstructFolder);
219 return QModelIndex();
222 QModelIndex PartSet_TopDataModel::objectIndex(const ObjectPtr& theObject) const
226 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
227 std::string aGroup = theObject->groupName();
228 int aNb = aRootDoc->size(aGroup);
230 for (int i = 0; i < aNb; i++) {
231 if (aRootDoc->object(aGroup, i) == theObject) {
237 if (aGroup == ModelAPI_ResultParameter::group())
238 return createIndex(aRow, 0, (qint32) ParamObject);
239 if (aGroup == ModelAPI_ResultConstruction::group())
240 return createIndex(aRow, 0, (qint32) ConstructObject);
241 //if (aGroup == ModelAPI_ResultGroup::group())
242 // return createIndex(aRow, 0, (qint32) GroupObject);
248 //******************************************************************
249 //******************************************************************
250 //******************************************************************
251 PartSet_PartDataModel::PartSet_PartDataModel(QObject* theParent)
252 : PartSet_PartModel(theParent)
256 PartSet_PartDataModel::~PartSet_PartDataModel()
260 QVariant PartSet_PartDataModel::data(const QModelIndex& theIndex, int theRole) const
262 DocumentPtr aPartDoc = partDocument();
263 if (theIndex.column() == 1) {
264 DocumentPtr aActiveDoc = ModelAPI_Session::get()->activeDocument();
265 QModelIndex aParent = theIndex.parent();
266 if (aActiveDoc == aPartDoc) {
267 if (!aParent.isValid()) {
269 case Qt::DecorationRole:
270 if (theIndex.row() == lastHistoryRow())
271 return QIcon(":pictures/arrow.png");
279 case Qt::DisplayRole:
281 switch (theIndex.internalId()) {
283 // DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
284 // ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), myId);
286 // return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
289 return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex));
290 case ConstructFolder:
291 return tr("Constructions") + QString(" (%1)").arg(rowCount(theIndex));
293 return tr("Bodies") + QString(" (%1)").arg(rowCount(theIndex));
295 return tr("Groups") + QString(" (%1)").arg(rowCount(theIndex));
297 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
299 ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObject);
300 AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
301 QString aVal = QString::number(aValueAttribute->value());
302 QString aTitle = QString(aObject->data()->name().c_str());
303 return aTitle + " = " + aVal;
307 case ConstructObject: {
308 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultConstruction::group(), theIndex.row());
310 return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
314 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultBody::group(), theIndex.row());
316 return aObject->data()->name().c_str();
320 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultGroup::group(), theIndex.row());
322 return aObject->data()->name().c_str();
324 case HistoryObject: {
325 ObjectPtr aObject = aPartDoc->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
327 return aObject->data()->name().c_str();
331 case Qt::DecorationRole:
333 switch (theIndex.internalId()) {
335 // return QIcon(":pictures/part_ico.png");
337 return QIcon(":pictures/params_folder.png");
338 case ConstructFolder:
340 return QIcon(":pictures/constr_folder.png");
342 return QIcon(":pictures/constr_folder.png");
343 case ConstructObject:
346 std::string aGroup = theIndex.internalId() == ConstructObject ?
347 ModelAPI_ResultConstruction::group() : ModelAPI_ResultBody::group();
348 ObjectPtr anObject = aPartDoc->object(aGroup, theIndex.row());
349 if (anObject && anObject->data() &&
350 anObject->data()->execState() == ModelAPI_StateMustBeUpdated) {
351 return QIcon(":pictures/constr_object_modified.png");
353 return QIcon(":pictures/constr_object.png");
355 case HistoryObject: {
356 ObjectPtr aObject = aPartDoc->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
357 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
359 return PartSet_DocumentDataModel::featureIcon(aFeature);
363 case Qt::ToolTipRole:
366 case Qt::ForegroundRole:
367 if (theIndex.internalId() == HistoryObject) {
368 if (theIndex.row() > lastHistoryRow())
369 return QBrush(Qt::lightGray);
371 return QBrush(myItemsColor);
376 QVariant PartSet_PartDataModel::headerData(int section, Qt::Orientation orientation, int role) const
381 int PartSet_PartDataModel::rowCount(const QModelIndex& parent) const
383 if (!parent.isValid()) {
384 DocumentPtr aDoc = partDocument();
386 return getRowsNumber() + aDoc->size(ModelAPI_Feature::group());
390 switch (parent.internalId()) {
392 return partDocument()->size(ModelAPI_ResultParameter::group());
393 case ConstructFolder:
394 return partDocument()->size(ModelAPI_ResultConstruction::group());
396 return partDocument()->size(ModelAPI_ResultBody::group());
398 return partDocument()->size(ModelAPI_ResultGroup::group());
403 int PartSet_PartDataModel::columnCount(const QModelIndex &parent) const
408 QModelIndex PartSet_PartDataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
410 if (!theParent.isValid()) {
413 return createIndex(theRow, theColumn, (qint32) ParamsFolder);
415 return createIndex(theRow, theColumn, (qint32) ConstructFolder);
417 return createIndex(theRow, theColumn, (qint32) BodiesFolder);
420 int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
422 return createIndex(theRow, theColumn, (qint32) GroupsFolder);
424 return createIndex(theRow, theColumn, (qint32) HistoryObject);
427 return createIndex(theRow, theColumn, (qint32) HistoryObject);
430 int aId = (int) theParent.internalId();
433 return createIndex(theRow, theColumn, (qint32) ParamObject);
434 case ConstructFolder:
435 return createIndex(theRow, theColumn, (qint32) ConstructObject);
437 return createIndex(theRow, theColumn, (qint32) BodiesObject);
439 return createIndex(theRow, theColumn, (qint32) GroupObject);
442 return QModelIndex();
445 QModelIndex PartSet_PartDataModel::parent(const QModelIndex& theIndex) const
447 switch (theIndex.internalId()) {
449 case ConstructFolder:
453 return QModelIndex();
456 return createIndex(0, 0, (qint32) ParamsFolder);
457 case ConstructObject:
458 return createIndex(1, 0, (qint32) ConstructFolder);
460 return createIndex(2, 0, (qint32) BodiesFolder);
462 return createIndex(3, 0, (qint32) GroupsFolder);
464 return QModelIndex();
467 bool PartSet_PartDataModel::hasChildren(const QModelIndex& theParent) const
469 return rowCount(theParent) > 0;
472 DocumentPtr PartSet_PartDataModel::partDocument() const
474 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(myPart->firstResult());
475 if (aPart.get()) // this may be null is Part feature is disabled
476 return aPart->partDoc();
477 return DocumentPtr();
480 ObjectPtr PartSet_PartDataModel::object(const QModelIndex& theIndex) const
482 switch (theIndex.internalId()) {
484 case ConstructFolder:
490 return partDocument()->object(ModelAPI_ResultParameter::group(), theIndex.row());
491 case ConstructObject:
492 return partDocument()->object(ModelAPI_ResultConstruction::group(), theIndex.row());
494 return partDocument()->object(ModelAPI_ResultBody::group(), theIndex.row());
496 return partDocument()->object(ModelAPI_ResultGroup::group(), theIndex.row());
498 return partDocument()->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
503 bool PartSet_PartDataModel::hasDocument(const DocumentPtr& theDoc) const
505 return (partDocument() == theDoc);
508 QModelIndex PartSet_PartDataModel::findParent(const ObjectPtr& theObject) const
510 return findGroup(theObject->groupName().c_str());
513 QModelIndex PartSet_PartDataModel::findGroup(const std::string& theGroup) const
515 if (theGroup == ModelAPI_ResultParameter::group())
516 return createIndex(0, 0, (qint32) ParamsFolder);
517 if (theGroup == ModelAPI_ResultConstruction::group())
518 return createIndex(1, 0, (qint32) ConstructFolder);
519 if (theGroup == ModelAPI_ResultBody::group())
520 return createIndex(2, 0, (qint32) BodiesFolder);
521 if (theGroup == ModelAPI_ResultGroup::group())
522 return createIndex(3, 0, (qint32) GroupsFolder);
523 return QModelIndex();
526 QModelIndex PartSet_PartDataModel::objectIndex(const ObjectPtr& theObject) const
530 if (part() == theObject)
533 std::string aGroup = theObject->groupName();
534 DocumentPtr aDoc = theObject->document();
535 int aNb = aDoc->size(aGroup);
537 for (int i = 0; i < aNb; i++) {
538 if (aDoc->object(aGroup, i) == theObject) {
545 if (aGroup == ModelAPI_ResultParameter::group())
546 return createIndex(aRow, 0, (qint32) ParamObject);
547 else if (aGroup == ModelAPI_ResultConstruction::group())
548 return createIndex(aRow, 0, (qint32) ConstructObject);
549 else if (aGroup == ModelAPI_ResultBody::group())
550 return createIndex(aRow, 0, (qint32) BodiesObject);
551 else if (aGroup == ModelAPI_ResultGroup::group())
552 return createIndex(aRow, 0, (qint32) GroupObject);
554 return createIndex(aRow + getRowsNumber(), 0, (qint32) HistoryObject);
560 int PartSet_PartDataModel::getRowsNumber() const
562 int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
563 if (aSize == 0) // If there are no groups then do not show group folder
568 int PartSet_PartDataModel::lastHistoryRow() const
570 DocumentPtr aDoc = partDocument();
571 FeaturePtr aFeature = aDoc->currentFeature(true);
573 return getRowsNumber() + aDoc->index(aFeature);
575 return getRowsNumber() - 1;
578 void PartSet_PartDataModel::setLastHistoryItem(const QModelIndex& theIndex)
580 SessionPtr aMgr = ModelAPI_Session::get();
581 DocumentPtr aDoc = partDocument();
582 std::string aOpName = tr("History change").toStdString();
583 if (theIndex.internalId() == HistoryObject) {
584 ObjectPtr aObject = object(theIndex);
585 aMgr->startOperation(aOpName);
586 aDoc->setCurrentFeature(std::dynamic_pointer_cast<ModelAPI_Feature>(aObject), true);
587 aMgr->finishOperation();
589 aMgr->startOperation(aOpName);
590 aDoc->setCurrentFeature(FeaturePtr(), true);
591 aMgr->finishOperation();
595 QModelIndex PartSet_PartDataModel::lastHistoryItem() const
597 return index(lastHistoryRow(), 1);
600 Qt::ItemFlags PartSet_PartDataModel::flags(const QModelIndex& theIndex) const
602 Qt::ItemFlags aFlags = Qt::ItemIsSelectable;
603 if (object(theIndex)) {
604 aFlags |= Qt::ItemIsEditable;
606 if (theIndex.internalId() == HistoryObject) {
607 if (theIndex.row() <= lastHistoryRow() || (theIndex.column() == 1))
608 aFlags |= Qt::ItemIsEnabled;
610 aFlags |= Qt::ItemIsEnabled;