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