Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom.git into Dev_1.1.0
[modules/shaper.git] / src / XGUI / XGUI_PartDataModel.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 #include "XGUI_PartDataModel.h"
4 #include "XGUI_Workshop.h"
5
6 #include <ModelAPI_Session.h>
7 #include <ModelAPI_Document.h>
8 #include <ModelAPI_Feature.h>
9 #include <ModelAPI_Result.h>
10 #include <ModelAPI_Data.h>
11 #include <ModelAPI_AttributeDocRef.h>
12 #include <ModelAPI_Object.h>
13 #include <ModelAPI_ResultPart.h>
14 #include <ModelAPI_ResultConstruction.h>
15 #include <ModelAPI_ResultParameter.h>
16 #include <ModelAPI_ResultBody.h>
17 #include <ModelAPI_ResultGroup.h>
18
19 #include <QIcon>
20 #include <QBrush>
21
22 //ObjectPtr featureObj(const ObjectPtr& theFeature)
23 //{
24 //  ObjectPtr aObject = std::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
25 //  if (aObject)
26 //    return aObject->featureRef();
27 //  return theFeature;
28 //}
29
30 XGUI_TopDataModel::XGUI_TopDataModel(QObject* theParent)
31     : XGUI_FeaturesModel(theParent)
32 {
33 }
34
35 XGUI_TopDataModel::~XGUI_TopDataModel()
36 {
37 }
38
39 QVariant XGUI_TopDataModel::data(const QModelIndex& theIndex, int theRole) const
40 {
41   switch (theRole) {
42     case Qt::DisplayRole:
43       // return a name
44       switch (theIndex.internalId()) {
45         case ParamsFolder:
46           return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex));
47         case ParamObject: {
48           DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
49           ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultParameter::group(), theIndex.row());
50           if (aObject)
51             return aObject->data()->name().c_str();
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 XGUI_TopDataModel::headerData(int section, Qt::Orientation orientation, int role) const
104 {
105   return QVariant();
106 }
107
108 int XGUI_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 XGUI_TopDataModel::columnCount(const QModelIndex &parent) const
127 {
128   return 1;
129 }
130
131 QModelIndex XGUI_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 XGUI_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 XGUI_TopDataModel::hasChildren(const QModelIndex& theParent) const
174 {
175   return rowCount(theParent) > 0;
176 }
177
178 ObjectPtr XGUI_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 XGUI_TopDataModel::findParent(const ObjectPtr& theObject) const
201 {
202   return findGroup(theObject->groupName().c_str());
203 }
204
205 QModelIndex XGUI_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 XGUI_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 XGUI_PartDataModel::XGUI_PartDataModel(QObject* theParent)
246     : XGUI_PartModel(theParent)
247 {
248 }
249
250 XGUI_PartDataModel::~XGUI_PartDataModel()
251 {
252 }
253
254 QVariant XGUI_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             return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
279         }
280           break;
281         case ConstructObject: {
282           ObjectPtr aObject = partDocument()->object(ModelAPI_ResultConstruction::group(),
283                                                      theIndex.row());
284           if (aObject)
285             return std::dynamic_pointer_cast<ModelAPI_Object>(aObject)->data()->name().c_str();
286         }
287           break;
288         case BodiesObject: {
289           ObjectPtr aObject = partDocument()->object(ModelAPI_ResultBody::group(), theIndex.row());
290           if (aObject)
291             return aObject->data()->name().c_str();
292         }
293           break;
294         case GroupObject: {
295           ObjectPtr aObject = partDocument()->object(ModelAPI_ResultGroup::group(), theIndex.row());
296           if (aObject)
297             return aObject->data()->name().c_str();
298         }
299         case HistoryObject: {
300           ObjectPtr aObject = partDocument()->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
301           if (aObject)
302             return aObject->data()->name().c_str();
303         }
304       }
305       break;
306     case Qt::DecorationRole:
307       // return an Icon
308       switch (theIndex.internalId()) {
309         case MyRoot:
310           return QIcon(":pictures/part_ico.png");
311         case ParamsFolder:
312           return QIcon(":pictures/params_folder.png");
313         case ConstructFolder:
314         case BodiesFolder:
315           return QIcon(":pictures/constr_folder.png");
316         case GroupsFolder:
317           return QIcon(":pictures/constr_folder.png");
318         case ConstructObject:
319         case GroupObject:
320         case BodiesObject: {
321           std::string aGroup = theIndex.internalId() == ConstructObject ?
322             ModelAPI_ResultConstruction::group() : ModelAPI_ResultBody::group();
323           ObjectPtr anObject = partDocument()->object(aGroup, theIndex.row());
324           if (anObject && anObject->data() && 
325               anObject->data()->execState() == ModelAPI_StateMustBeUpdated) {
326             return QIcon(":pictures/constr_object_modified.png");
327           }
328           return QIcon(":pictures/constr_object.png");
329         }
330         case HistoryObject: {
331           ObjectPtr aObject = partDocument()->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
332           FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
333           if (aFeature)
334             return XGUI_Workshop::featureIcon(aFeature);
335         }
336       }
337       break;
338     case Qt::ToolTipRole:
339       // return Tooltip
340       break;
341     case Qt::ForegroundRole:
342       return QBrush(myItemsColor);
343       break;
344   }
345   return QVariant();
346 }
347
348 QVariant XGUI_PartDataModel::headerData(int section, Qt::Orientation orientation, int role) const
349 {
350   return QVariant();
351 }
352
353 int XGUI_PartDataModel::rowCount(const QModelIndex& parent) const
354 {
355   if (!parent.isValid()) {
356     DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
357     if (aRootDoc->object(ModelAPI_ResultPart::group(), myId))
358       return 1;
359     else
360       return 0;
361   }
362   switch (parent.internalId()) {
363     case MyRoot:
364       {
365         DocumentPtr aDoc = partDocument();
366         if (aDoc) {
367           return getRowsNumber() + aDoc->size(ModelAPI_Feature::group());
368         } else 
369           return 0;
370       }
371     case ParamsFolder:
372       return partDocument()->size(ModelAPI_ResultParameter::group());
373     case ConstructFolder:
374       return partDocument()->size(ModelAPI_ResultConstruction::group());
375     case BodiesFolder:
376       return partDocument()->size(ModelAPI_ResultBody::group());
377     case GroupsFolder:
378       return partDocument()->size(ModelAPI_ResultGroup::group());
379   }
380   return 0;
381 }
382
383 int XGUI_PartDataModel::columnCount(const QModelIndex &parent) const
384 {
385   return 1;
386 }
387
388 QModelIndex XGUI_PartDataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
389 {
390   if (!theParent.isValid())
391     return createIndex(theRow, 0, (qint32) MyRoot);
392
393   int aId = (int) theParent.internalId();
394   switch (aId) {
395     case MyRoot:
396       switch (theRow) {
397         case 0:
398           return createIndex(theRow, 0, (qint32) ParamsFolder);
399         case 1:
400           return createIndex(theRow, 0, (qint32) ConstructFolder);
401         case 2:
402           return createIndex(theRow, 0, (qint32) BodiesFolder);
403         case 3:
404           {
405           int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
406           if (aSize > 0)
407             return createIndex(theRow, 0, (qint32) GroupsFolder);
408           else
409             return createIndex(theRow, theColumn, (qint32) HistoryObject);
410           }
411         default:
412           return createIndex(theRow, theColumn, (qint32) HistoryObject);
413       }
414     case ParamsFolder:
415       return createIndex(theRow, 0, (qint32) ParamObject);
416     case ConstructFolder:
417       return createIndex(theRow, 0, (qint32) ConstructObject);
418     case BodiesFolder:
419       return createIndex(theRow, 0, (qint32) BodiesObject);
420     case GroupsFolder:
421       return createIndex(theRow, 0, (qint32) GroupObject);
422   }
423   return QModelIndex();
424 }
425
426 QModelIndex XGUI_PartDataModel::parent(const QModelIndex& theIndex) const
427 {
428   switch (theIndex.internalId()) {
429     case MyRoot:
430       return QModelIndex();
431     case ParamsFolder:
432     case ConstructFolder:
433     case BodiesFolder:
434     case GroupsFolder:
435     case HistoryObject:
436       return createIndex(0, 0, (qint32) MyRoot);
437
438     case ParamObject:
439       return createIndex(0, 0, (qint32) ParamsFolder);
440     case ConstructObject:
441       return createIndex(1, 0, (qint32) ConstructFolder);
442     case BodiesObject:
443       return createIndex(2, 0, (qint32) BodiesFolder);
444     case GroupObject:
445       return createIndex(3, 0, (qint32) GroupsFolder);
446   }
447   return QModelIndex();
448 }
449
450 bool XGUI_PartDataModel::hasChildren(const QModelIndex& theParent) const
451 {
452   return rowCount(theParent) > 0;
453 }
454
455 DocumentPtr XGUI_PartDataModel::partDocument() const
456 {
457   DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
458   ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), myId);
459   ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
460   if (aPart)
461     return aPart->partDoc();
462   return DocumentPtr(); // null if not found
463 }
464
465 ObjectPtr XGUI_PartDataModel::object(const QModelIndex& theIndex) const
466 {
467   switch (theIndex.internalId()) {
468     case MyRoot: {
469       DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
470       return aRootDoc->object(ModelAPI_ResultPart::group(), myId);
471     }
472     case ParamsFolder:
473     case ConstructFolder:
474     case BodiesFolder:
475     case GroupsFolder:
476       return ObjectPtr();
477
478     case ParamObject:
479       return partDocument()->object(ModelAPI_ResultParameter::group(), theIndex.row());
480     case ConstructObject:
481       return partDocument()->object(ModelAPI_ResultConstruction::group(), theIndex.row());
482     case BodiesObject:
483       return partDocument()->object(ModelAPI_ResultBody::group(), theIndex.row());
484     case GroupObject:
485       return partDocument()->object(ModelAPI_ResultGroup::group(), theIndex.row());
486     case HistoryObject:
487       return partDocument()->object(ModelAPI_Feature::group(), theIndex.row() - getRowsNumber());
488   }
489   return ObjectPtr();
490 }
491
492 bool XGUI_PartDataModel::hasDocument(const DocumentPtr& theDoc) const
493 {
494   return (partDocument() == theDoc);
495 }
496
497 QModelIndex XGUI_PartDataModel::findParent(const ObjectPtr& theObject) const
498 {
499   return findGroup(theObject->groupName().c_str());
500 }
501
502 QModelIndex XGUI_PartDataModel::findGroup(const std::string& theGroup) const
503 {
504   if (theGroup == ModelAPI_ResultParameter::group())
505     return createIndex(0, 0, (qint32) ParamsFolder);
506   if (theGroup == ModelAPI_ResultConstruction::group())
507     return createIndex(1, 0, (qint32) ConstructFolder);
508   if (theGroup == ModelAPI_ResultBody::group())
509     return createIndex(2, 0, (qint32) BodiesFolder);
510   if (theGroup == ModelAPI_ResultGroup::group())
511     return createIndex(3, 0, (qint32) GroupsFolder);
512   return QModelIndex();
513 }
514
515 ResultPartPtr XGUI_PartDataModel::part() const
516 {
517   DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
518   ObjectPtr aObj = aRootDoc->object(ModelAPI_ResultPart::group(), myId);
519   return std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
520 }
521
522 QModelIndex XGUI_PartDataModel::objectIndex(const ObjectPtr& theObject) const
523 {
524   QModelIndex aIndex;
525   if (theObject) {
526     if (part() == theObject)
527       return aIndex;
528
529     std::string aGroup = theObject->groupName();
530     DocumentPtr aDoc = theObject->document();
531     int aNb = aDoc->size(aGroup);
532     int aRow = -1;
533     for (int i = 0; i < aNb; i++) {
534       if (aDoc->object(aGroup, i) == theObject) {
535         aRow = i;
536         break;
537       }
538     }
539     if (aRow == -1)
540       return aIndex;
541     if (aGroup == ModelAPI_ResultParameter::group())
542       return createIndex(aRow, 0, (qint32) ParamObject);
543     else if (aGroup == ModelAPI_ResultConstruction::group())
544       return createIndex(aRow, 0, (qint32) ConstructObject);
545     else if (aGroup == ModelAPI_ResultBody::group())
546       return createIndex(aRow, 0, (qint32) BodiesObject);
547     else if (aGroup == ModelAPI_ResultGroup::group())
548       return createIndex(aRow, 0, (qint32) GroupObject);
549     else
550       return createIndex(aRow + getRowsNumber(), 0, (qint32) HistoryObject);
551   }
552   return aIndex;
553 }
554
555
556 int XGUI_PartDataModel::getRowsNumber() const
557 {
558   int aSize = partDocument()->size(ModelAPI_ResultGroup::group());
559   if (aSize == 0) // If there are no groups then do not show group folder
560     return 3;
561   return 4;
562 }