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>
21 #include <ModelAPI_Tools.h>
23 #include <Events_Loop.h>
29 PartSet_PartDataModel::PartSet_PartDataModel(QObject* theParent)
30 : PartSet_PartModel(theParent)
34 PartSet_PartDataModel::~PartSet_PartDataModel()
38 QVariant PartSet_PartDataModel::data(const QModelIndex& theIndex, int theRole) const
40 DocumentPtr aPartDoc = partDocument();
41 if (theIndex.column() == 1) {
42 DocumentPtr aActiveDoc = ModelAPI_Session::get()->activeDocument();
43 QModelIndex aParent = theIndex.parent();
44 if (aActiveDoc == aPartDoc) {
45 if (!aParent.isValid()) {
47 case Qt::DecorationRole:
48 if (theIndex.row() == lastHistoryRow())
49 return QIcon(":pictures/arrow.png");
56 if (theIndex.internalId() >= 0) {
57 ObjectPtr aObj = object(theIndex);
60 return aObj->data()->name().c_str();
61 case Qt::DecorationRole:
63 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
65 return PartSet_DocumentDataModel::featureIcon(aFeature);
68 case Qt::ForegroundRole:
69 if (theIndex.internalId() > lastHistoryRow())
70 return QBrush(Qt::lightGray);
71 return QBrush(myItemsColor);
78 switch (theIndex.internalId()) {
80 // DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
81 // ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), myId);
83 // return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
86 return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex));
88 return tr("Constructions") + QString(" (%1)").arg(rowCount(theIndex));
90 return tr("Bodies") + QString(" (%1)").arg(rowCount(theIndex));
92 return tr("Groups") + QString(" (%1)").arg(rowCount(theIndex));
94 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
96 ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObject);
97 AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
98 QString aVal = QString::number(aValueAttribute->value());
99 QString aTitle = QString(aObject->data()->name().c_str());
100 return aTitle + " = " + aVal;
104 case ConstructObject: {
105 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultConstruction::group(), theIndex.row());
107 return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
111 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultBody::group(), theIndex.row());
113 return aObject->data()->name().c_str();
117 ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultGroup::group(), theIndex.row());
119 return aObject->data()->name().c_str();
121 case HistoryObject: {
122 ObjectPtr aObject = aPartDoc->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
124 return aObject->data()->name().c_str();
128 case Qt::DecorationRole:
130 switch (theIndex.internalId()) {
132 // return QIcon(":pictures/part_ico.png");
134 return QIcon(":pictures/params_folder.png");
135 case ConstructFolder:
137 return QIcon(":pictures/constr_folder.png");
139 return QIcon(":pictures/constr_folder.png");
140 case ConstructObject:
144 if (theIndex.internalId() == ConstructObject)
145 aGroup = ModelAPI_ResultConstruction::group();
146 else if (theIndex.internalId() == BodiesObject)
147 aGroup = ModelAPI_ResultBody::group();
148 else if (theIndex.internalId() == GroupObject)
149 aGroup = ModelAPI_ResultGroup::group();
150 if (aGroup.length() > 0) {
151 ObjectPtr anObject = aPartDoc->object(aGroup, theIndex.row());
152 if (anObject && anObject->data() &&
153 anObject->data()->execState() == ModelAPI_StateMustBeUpdated) {
154 return QIcon(":pictures/constr_object_modified.png");
157 return QIcon(":pictures/constr_object.png");
159 case HistoryObject: {
160 ObjectPtr aObject = aPartDoc->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
161 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
163 return PartSet_DocumentDataModel::featureIcon(aFeature);
167 case Qt::ToolTipRole:
170 case Qt::ForegroundRole:
171 if (theIndex.internalId() == HistoryObject) {
172 if (theIndex.row() > lastHistoryRow())
173 return QBrush(Qt::lightGray);
175 return QBrush(myItemsColor);
180 QVariant PartSet_PartDataModel::headerData(int section, Qt::Orientation orientation, int role) const
185 int PartSet_PartDataModel::rowCount(const QModelIndex& parent) const
187 if (!parent.isValid()) {
188 DocumentPtr aDoc = partDocument();
190 return getRowsNumber() + aDoc->size(ModelAPI_Feature::group());
194 switch (parent.internalId()) {
196 return partDocument()->size(ModelAPI_ResultParameter::group());
197 case ConstructFolder:
198 return partDocument()->size(ModelAPI_ResultConstruction::group());
200 return partDocument()->size(ModelAPI_ResultBody::group());
202 return partDocument()->size(ModelAPI_ResultGroup::group());
205 ObjectPtr aObj = object(parent);
206 CompositeFeaturePtr aCompFeature =
207 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aObj);
208 if (aCompFeature.get()) {
209 return aCompFeature->numberOfSubs(true);
216 int PartSet_PartDataModel::columnCount(const QModelIndex &parent) const
221 QModelIndex PartSet_PartDataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
223 if (!theParent.isValid()) {
226 return createIndex(theRow, theColumn, (qint32) ParamsFolder);
228 return createIndex(theRow, theColumn, (qint32) ConstructFolder);
230 return createIndex(theRow, theColumn, (qint32) BodiesFolder);
233 int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
235 return createIndex(theRow, theColumn, (qint32) GroupsFolder);
237 return createIndex(theRow, theColumn, (qint32) HistoryObject);
240 return createIndex(theRow, theColumn, (qint32) HistoryObject);
243 int aId = (int) theParent.internalId();
246 return createIndex(theRow, theColumn, (qint32) ParamObject);
247 case ConstructFolder:
248 return createIndex(theRow, theColumn, (qint32) ConstructObject);
250 return createIndex(theRow, theColumn, (qint32) BodiesObject);
252 return createIndex(theRow, theColumn, (qint32) GroupObject);
255 return createIndex(theRow, theColumn, (qint32) theParent.row());
259 return QModelIndex();
262 QModelIndex PartSet_PartDataModel::parent(const QModelIndex& theIndex) const
264 if (theIndex.internalId() >= 0) {
265 int aPRow = theIndex.internalId();
266 return createIndex(aPRow, 0, (qint32) HistoryObject);
268 switch (theIndex.internalId()) {
270 case ConstructFolder:
274 return QModelIndex();
277 return createIndex(0, 0, (qint32) ParamsFolder);
278 case ConstructObject:
279 return createIndex(1, 0, (qint32) ConstructFolder);
281 return createIndex(2, 0, (qint32) BodiesFolder);
283 return createIndex(3, 0, (qint32) GroupsFolder);
285 return QModelIndex();
288 bool PartSet_PartDataModel::hasChildren(const QModelIndex& theParent) const
290 return rowCount(theParent) > 0;
293 DocumentPtr PartSet_PartDataModel::partDocument() const
295 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(myPart->firstResult());
296 if (aPart.get()) // this may be null is Part feature is disabled
297 return aPart->partDoc();
298 return DocumentPtr();
301 ObjectPtr PartSet_PartDataModel::object(const QModelIndex& theIndex) const
303 if (theIndex.internalId() >= 0) {
304 int aPRow = theIndex.internalId();
306 partDocument()->object(ModelAPI_Feature::group(), aPRow - getRowsNumber());
307 CompositeFeaturePtr aCompFeature =
308 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aObj);
309 if (aCompFeature.get()) {
310 return aCompFeature->subFeature(theIndex.row(), true);
314 switch (theIndex.internalId()) {
316 case ConstructFolder:
322 return partDocument()->object(ModelAPI_ResultParameter::group(), theIndex.row());
323 case ConstructObject:
324 return partDocument()->object(ModelAPI_ResultConstruction::group(), theIndex.row());
326 return partDocument()->object(ModelAPI_ResultBody::group(), theIndex.row());
328 return partDocument()->object(ModelAPI_ResultGroup::group(), theIndex.row());
330 return partDocument()->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
335 bool PartSet_PartDataModel::hasDocument(const DocumentPtr& theDoc) const
337 return (partDocument() == theDoc);
340 QModelIndex PartSet_PartDataModel::findParent(const ObjectPtr& theObject) const
342 return findGroup(theObject->groupName().c_str());
345 QModelIndex PartSet_PartDataModel::findGroup(const std::string& theGroup) const
347 if (theGroup == ModelAPI_ResultParameter::group())
348 return createIndex(0, 0, (qint32) ParamsFolder);
349 if (theGroup == ModelAPI_ResultConstruction::group())
350 return createIndex(1, 0, (qint32) ConstructFolder);
351 if (theGroup == ModelAPI_ResultBody::group())
352 return createIndex(2, 0, (qint32) BodiesFolder);
353 if (theGroup == ModelAPI_ResultGroup::group())
354 return createIndex(3, 0, (qint32) GroupsFolder);
355 return QModelIndex();
358 QModelIndex PartSet_PartDataModel::objectIndex(const ObjectPtr& theObject) const
362 if (part() == theObject)
365 std::string aGroup = theObject->groupName();
366 DocumentPtr aDoc = theObject->document();
367 int aNb = aDoc->size(aGroup);
369 for (int i = 0; i < aNb; i++) {
370 if (aDoc->object(aGroup, i) == theObject) {
377 if (aGroup == ModelAPI_ResultParameter::group())
378 return createIndex(aRow, 0, (qint32) ParamObject);
379 else if (aGroup == ModelAPI_ResultConstruction::group())
380 return createIndex(aRow, 0, (qint32) ConstructObject);
381 else if (aGroup == ModelAPI_ResultBody::group())
382 return createIndex(aRow, 0, (qint32) BodiesObject);
383 else if (aGroup == ModelAPI_ResultGroup::group())
384 return createIndex(aRow, 0, (qint32) GroupObject);
386 return createIndex(aRow + getRowsNumber(), 0, (qint32) HistoryObject);
392 int PartSet_PartDataModel::getRowsNumber() const
394 int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
395 if (aSize == 0) // If there are no groups then do not show group folder
400 int PartSet_PartDataModel::lastHistoryRow() const
402 DocumentPtr aDoc = partDocument();
403 FeaturePtr aFeature = aDoc->currentFeature(true);
405 return getRowsNumber() + aDoc->index(aFeature);
407 return getRowsNumber() - 1;
410 void PartSet_PartDataModel::setLastHistoryItem(const QModelIndex& theIndex)
412 SessionPtr aMgr = ModelAPI_Session::get();
413 DocumentPtr aDoc = partDocument();
414 std::string aOpName = tr("History change").toStdString();
415 if (theIndex.internalId() == HistoryObject) {
416 ObjectPtr aObject = object(theIndex);
417 aMgr->startOperation(aOpName);
418 aDoc->setCurrentFeature(std::dynamic_pointer_cast<ModelAPI_Feature>(aObject), true);
419 aMgr->finishOperation();
421 aMgr->startOperation(aOpName);
422 aDoc->setCurrentFeature(FeaturePtr(), true);
423 aMgr->finishOperation();
427 QModelIndex PartSet_PartDataModel::lastHistoryItem() const
429 return index(lastHistoryRow(), 1);
432 Qt::ItemFlags PartSet_PartDataModel::flags(const QModelIndex& theIndex) const
434 // Disable sub-features at column 1
435 if ((theIndex.column() == 1) && (theIndex.internalId() >= 0))
438 Qt::ItemFlags aFlags = Qt::ItemIsSelectable;
439 if (object(theIndex)) {
440 aFlags |= Qt::ItemIsEditable;
443 if (theIndex.internalId() == HistoryObject) {
444 if (theIndex.row() <= lastHistoryRow() || (theIndex.column() == 1))
445 aFlags |= Qt::ItemIsEnabled;
447 aFlags |= Qt::ItemIsEnabled;