Salome HOME
Currently active feature pointer in Object Browser is created
[modules/shaper.git] / src / PartSet / PartSet_PartDataModel.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 #include "PartSet_PartDataModel.h"
4 #include "PartSet_Module.h"
5 #include "PartSet_DocumentDataModel.h"
6
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
21 #include <QIcon>
22 #include <QBrush>
23
24
25 PartSet_TopDataModel::PartSet_TopDataModel(QObject* theParent)
26     : PartSet_FeaturesModel(theParent)
27 {
28 }
29
30 PartSet_TopDataModel::~PartSet_TopDataModel()
31 {
32 }
33
34 QVariant PartSet_TopDataModel::data(const QModelIndex& theIndex, int theRole) const
35 {
36   if (theIndex.column() == 1)
37     return QVariant();
38
39   switch (theRole) {
40     case Qt::DisplayRole:
41       // return a name
42       switch (theIndex.internalId()) {
43         case ParamsFolder:
44           return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex));
45         case ParamObject: {
46           DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
47           ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
48           if (aObject) {
49             ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObject);
50             AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
51             QString aVal = QString::number(aValueAttribute->value());
52             QString aTitle = QString(aObject->data()->name().c_str());
53             return aTitle + " = " + aVal;
54           }
55         }
56           break;
57         case ConstructFolder:
58           return tr("Constructions") + QString(" (%1)").arg(rowCount(theIndex));
59         case ConstructObject: {
60           DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
61           ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultConstruction::group(),
62                                                theIndex.row());
63           if (aObject)
64             return aObject->data()->name().c_str();
65         }
66           break;
67         //case GroupsFolder:
68         //  return tr("Groups") + QString(" (%1)").arg(rowCount(theIndex));
69         //case GroupObject: {
70         //  DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
71         //  ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultGroup::group(),
72         //                                       theIndex.row());
73         //  if (aObject)
74         //    return aObject->data()->name().c_str();
75         //}
76         //  break;
77       }
78       break;
79
80     case Qt::DecorationRole:
81       {
82       // return an Icon
83       switch (theIndex.internalId()) {
84         case ParamsFolder:
85           return QIcon(":pictures/params_folder.png");
86         case ConstructFolder:
87           return QIcon(":pictures/constr_folder.png");
88         case ConstructObject:
89           return QIcon(":pictures/constr_object.png");
90         //case GroupsFolder:
91         //  return QIcon(":pictures/constr_folder.png");
92         }
93       }
94       break;
95
96     case Qt::ToolTipRole:
97       // return Tooltip
98       break;
99     case Qt::ForegroundRole:
100       return QBrush(myItemsColor);
101       break;
102   }
103   return QVariant();
104 }
105
106 QVariant PartSet_TopDataModel::headerData(int section, Qt::Orientation orientation, int role) const
107 {
108   return QVariant();
109 }
110
111 int PartSet_TopDataModel::rowCount(const QModelIndex& theParent) const
112 {
113   if (!theParent.isValid())
114     return 2;  // In case of groups using it has to be +1
115
116   DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
117   if (theParent.internalId() == ParamsFolder)
118     return aRootDoc->size(ModelAPI_ResultParameter::group());
119
120   if (theParent.internalId() == ConstructFolder)
121     return aRootDoc->size(ModelAPI_ResultConstruction::group());
122
123   //if (theParent.internalId() == GroupsFolder)
124   //  return aRootDoc->size(ModelAPI_ResultGroup::group());
125
126   return 0;
127 }
128
129 int PartSet_TopDataModel::columnCount(const QModelIndex &parent) const
130 {
131   return 1;
132 }
133
134 QModelIndex PartSet_TopDataModel::index(int theRow, int theColumn, const QModelIndex& theParent) const
135 {
136   if (!theParent.isValid()) {
137     switch (theRow) {
138       case 0:
139         return createIndex(theRow, theColumn, (qint32) ParamsFolder);
140       case 1:
141         return createIndex(theRow, theColumn, (qint32) ConstructFolder);
142       //case 2:
143       //  return createIndex(theRow, theColumn, (qint32) GroupsFolder);
144     }
145   } else {
146     if (theParent.internalId() == ParamsFolder)
147       return createIndex(theRow, theColumn, (qint32) ParamObject);
148
149     if (theParent.internalId() == ConstructFolder)
150       return createIndex(theRow, theColumn, (qint32) ConstructObject);
151
152     //if (theParent.internalId() == GroupsFolder)
153     //  return createIndex(theRow, theColumn, (qint32) GroupObject);
154   }
155   return QModelIndex();
156 }
157
158 QModelIndex PartSet_TopDataModel::parent(const QModelIndex& theIndex) const
159 {
160   int aId = (int) theIndex.internalId();
161   switch (aId) {
162     case ParamsFolder:
163     case ConstructFolder:
164     //case GroupsFolder:
165       return QModelIndex();
166     case ParamObject:
167       return createIndex(0, 0, (qint32) ParamsFolder);
168     case ConstructObject:
169       return createIndex(1, 0, (qint32) ConstructFolder);
170     //case GroupObject:
171     //  return createIndex(2, 0, (qint32) GroupsFolder);
172   }
173   return QModelIndex();
174 }
175
176 bool PartSet_TopDataModel::hasChildren(const QModelIndex& theParent) const
177 {
178   return rowCount(theParent) > 0;
179 }
180
181 ObjectPtr PartSet_TopDataModel::object(const QModelIndex& theIndex) const
182 {
183   switch (theIndex.internalId()) {
184     case ParamsFolder:
185     case ConstructFolder:
186       return ObjectPtr();
187     case ParamObject: {
188       DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
189       return aRootDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
190     }
191     case ConstructObject: {
192       DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
193       return aRootDoc->object(ModelAPI_ResultConstruction::group(), theIndex.row());
194     }
195     //case GroupObject: {
196     //  DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
197     //  return aRootDoc->object(ModelAPI_ResultGroup::group(), theIndex.row());
198     //}
199   }
200   return ObjectPtr();
201 }
202
203 QModelIndex PartSet_TopDataModel::findParent(const ObjectPtr& theObject) const
204 {
205   return findGroup(theObject->groupName().c_str());
206 }
207
208 QModelIndex PartSet_TopDataModel::findGroup(const std::string& theGroup) const
209 {
210   if (theGroup == ModelAPI_ResultParameter::group())
211     return createIndex(0, 0, (qint32) ParamsFolder);
212   if (theGroup == ModelAPI_ResultConstruction::group())
213     return createIndex(1, 0, (qint32) ConstructFolder);
214   //if (theGroup == ModelAPI_ResultGroup::group())
215   //  return createIndex(2, 0, (qint32) ConstructFolder);
216   return QModelIndex();
217 }
218
219 QModelIndex PartSet_TopDataModel::objectIndex(const ObjectPtr& theObject) const
220 {
221   QModelIndex aIndex;
222   if (theObject) {
223     DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
224     std::string aGroup = theObject->groupName();
225     int aNb = aRootDoc->size(aGroup);
226     int aRow = -1;
227     for (int i = 0; i < aNb; i++) {
228       if (aRootDoc->object(aGroup, i) == theObject) {
229         aRow = i;
230         break;
231       }
232     }
233     if (aRow != -1) {
234       if (aGroup == ModelAPI_ResultParameter::group())
235         return createIndex(aRow, 0, (qint32) ParamObject);
236       if (aGroup == ModelAPI_ResultConstruction::group())
237         return createIndex(aRow, 0, (qint32) ConstructObject);
238       //if (aGroup == ModelAPI_ResultGroup::group())
239       //  return createIndex(aRow, 0, (qint32) GroupObject);
240     }
241   }
242   return aIndex;
243 }
244
245 //******************************************************************
246 //******************************************************************
247 //******************************************************************
248 PartSet_PartDataModel::PartSet_PartDataModel(QObject* theParent)
249     : PartSet_PartModel(theParent), myHistoryBackOffset(0)
250 {
251 }
252
253 PartSet_PartDataModel::~PartSet_PartDataModel()
254 {
255 }
256
257 QVariant PartSet_PartDataModel::data(const QModelIndex& theIndex, int theRole) const
258 {
259   DocumentPtr aPartDoc = partDocument();
260   if (theIndex.column() == 1) {
261     DocumentPtr aActiveDoc = ModelAPI_Session::get()->activeDocument();
262     QModelIndex aParent = theIndex.parent();
263     if (aActiveDoc == aPartDoc) {
264       if ((theIndex.internalId() == HistoryObject) && (!aParent.isValid())) {
265         switch (theRole) {
266         case Qt::DecorationRole:
267           if (theIndex.row() == lastHistoryRow())
268             return QIcon(":pictures/arrow.png");
269         }
270       }
271     }
272     return QVariant();
273   }
274
275   switch (theRole) {
276     case Qt::DisplayRole:
277       // return a name
278       switch (theIndex.internalId()) {
279         //case MyRoot: {
280         //  DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
281         //  ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), myId);
282         //  if (aObject)
283         //    return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
284         //}
285         case ParamsFolder:
286           return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex));
287         case ConstructFolder:
288           return tr("Constructions") + QString(" (%1)").arg(rowCount(theIndex));
289         case BodiesFolder:
290           return tr("Bodies") + QString(" (%1)").arg(rowCount(theIndex));
291         case GroupsFolder:
292           return tr("Groups") + QString(" (%1)").arg(rowCount(theIndex));
293         case ParamObject: {
294           ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
295           if (aObject) {
296             ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObject);
297             AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
298             QString aVal = QString::number(aValueAttribute->value());
299             QString aTitle = QString(aObject->data()->name().c_str());
300             return aTitle + " = " + aVal;
301           }
302         }
303           break;
304         case ConstructObject: {
305           ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultConstruction::group(), theIndex.row());
306           if (aObject)
307             return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
308         }
309           break;
310         case BodiesObject: {
311           ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultBody::group(), theIndex.row());
312           if (aObject)
313             return aObject->data()->name().c_str();
314         }
315           break;
316         case GroupObject: {
317           ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultGroup::group(), theIndex.row());
318           if (aObject)
319             return aObject->data()->name().c_str();
320         }
321         case HistoryObject: {
322           ObjectPtr aObject = aPartDoc->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
323           if (aObject)
324             return aObject->data()->name().c_str();
325         }
326       }
327       break;
328     case Qt::DecorationRole:
329       // return an Icon
330       switch (theIndex.internalId()) {
331         //case MyRoot:
332         //  return QIcon(":pictures/part_ico.png");
333         case ParamsFolder:
334           return QIcon(":pictures/params_folder.png");
335         case ConstructFolder:
336         case BodiesFolder:
337           return QIcon(":pictures/constr_folder.png");
338         case GroupsFolder:
339           return QIcon(":pictures/constr_folder.png");
340         case ConstructObject:
341         case GroupObject:
342         case BodiesObject: {
343           std::string aGroup = theIndex.internalId() == ConstructObject ?
344             ModelAPI_ResultConstruction::group() : ModelAPI_ResultBody::group();
345           ObjectPtr anObject = aPartDoc->object(aGroup, theIndex.row());
346           if (anObject && anObject->data() && 
347               anObject->data()->execState() == ModelAPI_StateMustBeUpdated) {
348             return QIcon(":pictures/constr_object_modified.png");
349           }
350           return QIcon(":pictures/constr_object.png");
351         }
352         case HistoryObject: {
353           ObjectPtr aObject = aPartDoc->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
354           FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
355           if (aFeature)
356             return PartSet_DocumentDataModel::featureIcon(aFeature);
357         }
358       }
359       break;
360     case Qt::ToolTipRole:
361       // return Tooltip
362       break;
363     case Qt::ForegroundRole:
364       return QBrush(myItemsColor);
365       break;
366   }
367   return QVariant();
368 }
369
370 QVariant PartSet_PartDataModel::headerData(int section, Qt::Orientation orientation, int role) const
371 {
372   return QVariant();
373 }
374
375 int PartSet_PartDataModel::rowCount(const QModelIndex& parent) const
376 {
377   if (!parent.isValid()) {
378     DocumentPtr aDoc = partDocument();
379     if (aDoc.get()) {
380       return getRowsNumber() + aDoc->size(ModelAPI_Feature::group());
381     } else 
382       return 0;
383   }
384   switch (parent.internalId()) {
385     case ParamsFolder:
386       return partDocument()->size(ModelAPI_ResultParameter::group());
387     case ConstructFolder:
388       return partDocument()->size(ModelAPI_ResultConstruction::group());
389     case BodiesFolder:
390       return partDocument()->size(ModelAPI_ResultBody::group());
391     case GroupsFolder:
392       return partDocument()->size(ModelAPI_ResultGroup::group());
393   }
394   return 0;
395 }
396
397 int PartSet_PartDataModel::columnCount(const QModelIndex &parent) const
398 {
399   return 2;
400 }
401
402 QModelIndex PartSet_PartDataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
403 {
404   if (!theParent.isValid()) {
405     switch (theRow) {
406       case 0:
407         return createIndex(theRow, theColumn, (qint32) ParamsFolder);
408       case 1:
409         return createIndex(theRow, theColumn, (qint32) ConstructFolder);
410       case 2:
411         return createIndex(theRow, theColumn, (qint32) BodiesFolder);
412       case 3:
413         {
414         int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
415         if (aSize > 0)
416           return createIndex(theRow, theColumn, (qint32) GroupsFolder);
417         else
418           return createIndex(theRow, theColumn, (qint32) HistoryObject);
419         }
420       default:
421         return createIndex(theRow, theColumn, (qint32) HistoryObject);
422     }
423   } else {
424     int aId = (int) theParent.internalId();
425     switch (aId) {
426       case ParamsFolder:
427         return createIndex(theRow, theColumn, (qint32) ParamObject);
428       case ConstructFolder:
429         return createIndex(theRow, theColumn, (qint32) ConstructObject);
430       case BodiesFolder:
431         return createIndex(theRow, theColumn, (qint32) BodiesObject);
432       case GroupsFolder:
433         return createIndex(theRow, theColumn, (qint32) GroupObject);
434     }
435   }
436   return QModelIndex();
437 }
438
439 QModelIndex PartSet_PartDataModel::parent(const QModelIndex& theIndex) const
440 {
441   switch (theIndex.internalId()) {
442     case ParamsFolder:
443     case ConstructFolder:
444     case BodiesFolder:
445     case GroupsFolder:
446     case HistoryObject:
447       return QModelIndex();
448
449     case ParamObject:
450       return createIndex(0, 0, (qint32) ParamsFolder);
451     case ConstructObject:
452       return createIndex(1, 0, (qint32) ConstructFolder);
453     case BodiesObject:
454       return createIndex(2, 0, (qint32) BodiesFolder);
455     case GroupObject:
456       return createIndex(3, 0, (qint32) GroupsFolder);
457   }
458   return QModelIndex();
459 }
460
461 bool PartSet_PartDataModel::hasChildren(const QModelIndex& theParent) const
462 {
463   return rowCount(theParent) > 0;
464 }
465
466 DocumentPtr PartSet_PartDataModel::partDocument() const
467 {
468   DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
469   ObjectPtr aObject = aRootDoc->object(ModelAPI_Feature::group(), myId);
470   FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
471   ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aFeature->firstResult()); 
472   return aPart->partDoc();
473 }
474
475 ObjectPtr PartSet_PartDataModel::object(const QModelIndex& theIndex) const
476 {
477   switch (theIndex.internalId()) {
478     case ParamsFolder:
479     case ConstructFolder:
480     case BodiesFolder:
481     case GroupsFolder:
482       return ObjectPtr();
483
484     case ParamObject:
485       return partDocument()->object(ModelAPI_ResultParameter::group(), theIndex.row());
486     case ConstructObject:
487       return partDocument()->object(ModelAPI_ResultConstruction::group(), theIndex.row());
488     case BodiesObject:
489       return partDocument()->object(ModelAPI_ResultBody::group(), theIndex.row());
490     case GroupObject:
491       return partDocument()->object(ModelAPI_ResultGroup::group(), theIndex.row());
492     case HistoryObject:
493       return partDocument()->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
494   }
495   return ObjectPtr();
496 }
497
498 bool PartSet_PartDataModel::hasDocument(const DocumentPtr& theDoc) const
499 {
500   return (partDocument() == theDoc);
501 }
502
503 QModelIndex PartSet_PartDataModel::findParent(const ObjectPtr& theObject) const
504 {
505   return findGroup(theObject->groupName().c_str());
506 }
507
508 QModelIndex PartSet_PartDataModel::findGroup(const std::string& theGroup) const
509 {
510   if (theGroup == ModelAPI_ResultParameter::group())
511     return createIndex(0, 0, (qint32) ParamsFolder);
512   if (theGroup == ModelAPI_ResultConstruction::group())
513     return createIndex(1, 0, (qint32) ConstructFolder);
514   if (theGroup == ModelAPI_ResultBody::group())
515     return createIndex(2, 0, (qint32) BodiesFolder);
516   if (theGroup == ModelAPI_ResultGroup::group())
517     return createIndex(3, 0, (qint32) GroupsFolder);
518   return QModelIndex();
519 }
520
521 ResultPartPtr PartSet_PartDataModel::part() const
522 {
523   DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
524   ObjectPtr aObj = aRootDoc->object(ModelAPI_ResultPart::group(), myId);
525   return std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
526 }
527
528 QModelIndex PartSet_PartDataModel::objectIndex(const ObjectPtr& theObject) const
529 {
530   QModelIndex aIndex;
531   if (theObject) {
532     if (part() == theObject)
533       return aIndex;
534
535     std::string aGroup = theObject->groupName();
536     DocumentPtr aDoc = theObject->document();
537     int aNb = aDoc->size(aGroup);
538     int aRow = -1;
539     for (int i = 0; i < aNb; i++) {
540       if (aDoc->object(aGroup, i) == theObject) {
541         aRow = i;
542         break;
543       }
544     }
545     if (aRow == -1)
546       return aIndex;
547     if (aGroup == ModelAPI_ResultParameter::group())
548       return createIndex(aRow, 0, (qint32) ParamObject);
549     else if (aGroup == ModelAPI_ResultConstruction::group())
550       return createIndex(aRow, 0, (qint32) ConstructObject);
551     else if (aGroup == ModelAPI_ResultBody::group())
552       return createIndex(aRow, 0, (qint32) BodiesObject);
553     else if (aGroup == ModelAPI_ResultGroup::group())
554       return createIndex(aRow, 0, (qint32) GroupObject);
555     else
556       return createIndex(aRow + getRowsNumber(), 0, (qint32) HistoryObject);
557   }
558   return aIndex;
559 }
560
561
562 int PartSet_PartDataModel::getRowsNumber() const
563 {
564   int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
565   if (aSize == 0) // If there are no groups then do not show group folder
566     return 3;
567   return 4;
568 }
569
570 int PartSet_PartDataModel::lastHistoryRow() const
571 {
572   return rowCount() - 1 - myHistoryBackOffset;
573 }