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