0029018: Documentation - Provide user guide for Qt browser
[occt.git] / tools / DFBrowserPane / DFBrowserPane_TNamingNamedShape.cxx
1 // Created on: 2017-06-16
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2017 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement. 
15
16 #include <inspector/DFBrowserPane_TNamingNamedShape.hxx>
17
18 #include <inspector/DFBrowserPane_AttributePaneModel.hxx>
19 #include <inspector/DFBrowserPane_ItemDelegateButton.hxx>
20 #include <inspector/DFBrowserPane_ItemRole.hxx>
21 #include <inspector/DFBrowserPane_HelperExport.hxx>
22 #include <inspector/DFBrowserPane_SelectionKind.hxx>
23 #include <inspector/DFBrowserPane_TableView.hxx>
24 #include <inspector/DFBrowserPane_Tools.hxx>
25
26 #include <AIS_InteractiveObject.hxx>
27 #include <AIS_Shape.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRepTools.hxx>
30 #include <TNaming_Builder.hxx>
31 #include <TNaming_Iterator.hxx>
32 #include <TNaming_NamedShape.hxx>
33 #include <TNaming_Tool.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopoDS_Compound.hxx>
36
37 #include <QFileDialog>
38 #include <QGridLayout>
39 #include <QEvent>
40 #include <QHeaderView>
41 #include <QIcon>
42 #include <QMap>
43 #include <QPainter>
44 #include <QStyledItemDelegate>
45 #include <QTableView>
46 #include <QVariant>
47 #include <QWidget>
48
49 const int COLUMN_EXPORT_WIDTH = 20;
50 const int COLUMN_TYPE_WIDTH = 70;
51 const int COLUMN_POINTER_WIDTH = 110;
52 const int COLUMN_REFERENCE_WIDTH = 90;
53 const int COLUMN_EVOLUTION_WIDTH = 90;
54
55 // =======================================================================
56 // function : Constructor
57 // purpose :
58 // =======================================================================
59 DFBrowserPane_TNamingNamedShape::DFBrowserPane_TNamingNamedShape()
60 : DFBrowserPane_AttributePane(), myEvolutionTableView (0), myHelperExport (0)
61 {
62   getPaneModel()->SetColumnCount (5);
63
64   myEvolutionPaneModel = new DFBrowserPane_AttributePaneModel();
65   myEvolutionPaneModel->SetColumnCount (11);
66   QList<int> anItalicColumns;
67   anItalicColumns << 2 << 6;
68   myEvolutionPaneModel->SetItalicColumns (anItalicColumns);
69   QItemSelectionModel* aSelectionModel = new QItemSelectionModel (myEvolutionPaneModel);
70   mySelectionModels.push_back (aSelectionModel);
71 }
72
73 // =======================================================================
74 // function : CreateWidget
75 // purpose :
76 // =======================================================================
77 QWidget* DFBrowserPane_TNamingNamedShape::CreateWidget (QWidget* theParent)
78 {
79   QWidget* aMainWidget = new QWidget (theParent);
80   aMainWidget->setVisible (false);
81
82   myTableView = new DFBrowserPane_TableView (aMainWidget);
83   myTableView->GetTableView()->verticalHeader()->setVisible (false);
84   myTableView->SetModel (myPaneModel);
85   QTableView* aTableView = myTableView->GetTableView();
86   aTableView->setSelectionBehavior (QAbstractItemView::SelectItems);
87   std::list<QItemSelectionModel*>::const_iterator aSelectionModelsIt = mySelectionModels.begin();
88   aTableView->setSelectionModel (*aSelectionModelsIt);
89   aSelectionModelsIt++;
90
91   aTableView->horizontalHeader()->setStretchLastSection (false);
92   aTableView->setColumnWidth (3, COLUMN_EXPORT_WIDTH);
93   aTableView->setColumnWidth (4, COLUMN_EXPORT_WIDTH);
94   DFBrowserPane_ItemDelegateButton* anItemDelegate = new DFBrowserPane_ItemDelegateButton (aTableView,
95                                                                                           ":/icons/export_shape.png");
96   QList<int> aRows;
97   aRows << 0 << 1;
98   anItemDelegate->SetFreeRows (aRows);
99   QObject::connect (anItemDelegate, SIGNAL (buttonPressed (const QModelIndex&)),
100                     &myHelperExport, SLOT (OnButtonPressed (const QModelIndex&)));
101   aTableView->setItemDelegateForColumn (3, anItemDelegate);
102
103   DFBrowserPane_ItemDelegateButton* anItemDelegate2 = new DFBrowserPane_ItemDelegateButton (aTableView,
104                                                                                             ":/icons/folder_export.png");
105   anItemDelegate2->SetFreeRows (aRows);
106   aTableView->setItemDelegateForColumn (4, anItemDelegate2);
107
108   myEvolutionTableView = new DFBrowserPane_TableView (aMainWidget);
109   myEvolutionTableView->SetModel (myEvolutionPaneModel);
110   aTableView = myEvolutionTableView->GetTableView();
111
112   aTableView->setSelectionModel (*aSelectionModelsIt);
113
114   aTableView->horizontalHeader()->setStretchLastSection (false);
115   aTableView->setColumnWidth (5, COLUMN_EXPORT_WIDTH);
116   aTableView->setColumnWidth (10, COLUMN_EXPORT_WIDTH);
117
118   anItemDelegate = new DFBrowserPane_ItemDelegateButton (myEvolutionTableView->GetTableView(), ":/icons/export_shape.png");
119   QObject::connect (anItemDelegate, SIGNAL (buttonPressed (const QModelIndex&)),
120                     &myHelperExport, SLOT (OnButtonPressed (const QModelIndex&)));
121   myEvolutionTableView->GetTableView()->setItemDelegateForColumn (5, anItemDelegate);
122
123   anItemDelegate = new DFBrowserPane_ItemDelegateButton (myEvolutionTableView->GetTableView(), ":/icons/export_shape.png");
124   QObject::connect (anItemDelegate, SIGNAL (buttonPressed (const QModelIndex&)),
125                     &myHelperExport, SLOT (OnButtonPressed (const QModelIndex&)));
126   myEvolutionTableView->GetTableView()->setItemDelegateForColumn (10, anItemDelegate);
127
128   QGridLayout* aLay = new QGridLayout (aMainWidget);
129   aLay->setContentsMargins (0, 0, 0, 0);
130   aLay->addWidget (myTableView, 0, 0);
131   aLay->addWidget (myEvolutionTableView, 1, 0);
132
133   return aMainWidget;
134 }
135
136 // =======================================================================
137 // function : Init
138 // purpose :
139 // =======================================================================
140 void DFBrowserPane_TNamingNamedShape::Init (const Handle(TDF_Attribute)& theAttribute)
141 {
142   Handle(TNaming_NamedShape) aShapeAttr = Handle(TNaming_NamedShape)::DownCast (theAttribute);
143   myHelperExport.Clear();
144
145   QList<QVariant> aValues;
146   aValues << "Version" << QString::number (aShapeAttr->Version()) << "" << "" << "";
147   aValues << "Evolution" << DFBrowserPane_Tools::ToName (DB_NS_TYPE, aShapeAttr->Evolution()).ToCString() << "" << "" << "";
148
149   NCollection_List<TopoDS_Shape> aShapes;
150   QList<int> aFreeRows;
151   aFreeRows << 0 << 1;
152
153   TopoDS_Shape aShape = aShapeAttr->Get();
154   TCollection_AsciiString aShapeInfo = !aShape.IsNull() ? DFBrowserPane_Tools::GetPointerInfo (aShape.TShape()) : "";
155   aValues << "Shape" << aShapeInfo.ToCString() << DFBrowserPane_Tools::ShapeTypeInfo (aShape) << "" << "";
156   aShapes.Append (aShape);
157   if (aShape.IsNull())
158     aFreeRows << 2;
159
160   TopoDS_Shape aCurrentShape = TNaming_Tool::CurrentShape (aShapeAttr);
161   TCollection_AsciiString aCurrentShapeInfo = !aCurrentShape.IsNull() ?
162                                   DFBrowserPane_Tools::GetPointerInfo (aCurrentShape.TShape()) : "";
163   aValues << "CurrentShape" << aCurrentShapeInfo.ToCString()
164           << DFBrowserPane_Tools::ShapeTypeInfo (aCurrentShape) << "" << "";
165   aShapes.Append (aCurrentShape);
166   if (aCurrentShape.IsNull())
167     aFreeRows << 3;
168
169   TopoDS_Shape anOriginalShape = TNaming_Tool::OriginalShape (aShapeAttr);
170   TCollection_AsciiString anOriginalShapeInfo = !anOriginalShape.IsNull() ?
171             DFBrowserPane_Tools::GetPointerInfo (anOriginalShape.TShape()) : "";
172   aValues << "OriginalShape" << anOriginalShapeInfo.ToCString()
173           << DFBrowserPane_Tools::ShapeTypeInfo (anOriginalShape) << "" << "";
174   aShapes.Append (anOriginalShape);
175   if (anOriginalShape.IsNull())
176     aFreeRows << 4;
177
178
179   DFBrowserPane_AttributePaneModel* aModel = getPaneModel();
180   aModel->Init (aValues);
181   if (myTableView)
182   {
183     QTableView* aTableView = myTableView->GetTableView();
184     for (int i = 0; i < aModel->columnCount(); i++)
185     {
186       if (i == 3 || i == 4)
187         dynamic_cast<DFBrowserPane_ItemDelegateButton*>(aTableView->itemDelegateForColumn(3))->SetFreeRows (aFreeRows);
188       else
189         aTableView->resizeColumnToContents (i);
190     }
191   }
192   QModelIndexList anIndices;
193   int aRowId = 2;
194   for (NCollection_List<TopoDS_Shape>::Iterator aShapeIt (aShapes); aShapeIt.More(); aShapeIt.Next(), aRowId++)
195   {
196     if (aShapeIt.Value().IsNull())
197       continue;
198     anIndices.clear();
199     anIndices << aModel->index (aRowId, 1) << aModel->index (aRowId, 2) <<
200                  aModel->index (aRowId, 3) << aModel->index (aRowId, 4);
201     myHelperExport.AddShape (aShapeIt.Value(), anIndices);
202   }
203
204   // evolution table view filling
205   aValues.clear();
206   aRowId = 0;
207   bool aHasModified = false;
208   for (TNaming_Iterator aShapeAttrIt (aShapeAttr); aShapeAttrIt.More(); aShapeAttrIt.Next(), aRowId++)
209   {
210     const TopoDS_Shape& anOldShape = aShapeAttrIt.OldShape();
211     const TopoDS_Shape& aNewShape = aShapeAttrIt.NewShape();
212
213     Handle(TNaming_NamedShape) anOldAttr = TNaming_Tool::NamedShape (anOldShape, aShapeAttr->Label());
214     aValues << DFBrowserPane_Tools::ToName (DB_NS_TYPE, aShapeAttrIt.Evolution()).ToCString()
215             << (aShapeAttrIt.IsModification() ? "modified" : "-");
216     aHasModified = aHasModified | aShapeAttrIt.IsModification();
217
218     aValues << "New:";
219
220     QString aLabelInfo;
221     if (!anOldAttr.IsNull())
222     {
223       TDF_Label anOldLabel = anOldAttr->Label();
224       if (!anOldLabel.IsNull())
225         aLabelInfo = QString (DFBrowserPane_Tools::GetEntry (anOldLabel).ToCString());
226     }
227     if (!aNewShape.IsNull())
228       aValues << DFBrowserPane_Tools::GetPointerInfo (aNewShape.TShape()->This()).ToCString()
229               << DFBrowserPane_Tools::ShapeTypeInfo (aNewShape)
230               << "";
231     else
232       aValues << "-" << "-" << "";
233     aValues << "Old:";
234     if (!anOldShape.IsNull())
235       aValues << DFBrowserPane_Tools::GetPointerInfo (anOldShape.TShape()->This()).ToCString()
236               << DFBrowserPane_Tools::ShapeTypeInfo (anOldShape)
237               << aLabelInfo
238               << "";
239     else
240       aValues << "-" << "-" << "-" << "";
241   }
242
243   if (myEvolutionTableView)
244   {
245     myEvolutionTableView->setVisible (aValues.size() > 0);
246     myEvolutionTableView->GetTableView()->setColumnHidden (1, !aHasModified);
247     myEvolutionPaneModel->Init (aValues);
248
249     aRowId = 0;
250     for (TNaming_Iterator aShapeAttrIt (aShapeAttr); aShapeAttrIt.More(); aShapeAttrIt.Next(), aRowId++)
251     {
252       const TopoDS_Shape& anOldShape = aShapeAttrIt.OldShape();
253       const TopoDS_Shape& aNewShape = aShapeAttrIt.NewShape();
254
255       if (!aNewShape.IsNull())
256       {
257         anIndices.clear();
258         anIndices << myEvolutionPaneModel->index (aRowId, 3) << myEvolutionPaneModel->index (aRowId, 4)
259                   << myEvolutionPaneModel->index (aRowId, 5);
260         myHelperExport.AddShape (aNewShape, anIndices);
261       }
262       if (!anOldShape.IsNull())
263       {
264         anIndices.clear();
265         anIndices << myEvolutionPaneModel->index (aRowId, 7) << myEvolutionPaneModel->index (aRowId, 8)
266                   << myEvolutionPaneModel->index (aRowId, 10);
267         myHelperExport.AddShape (anOldShape, anIndices);
268       }
269     }
270     for (int i = 0; i < myEvolutionPaneModel->columnCount(); i++)
271     {
272       if (i == 5 || i == 10) continue;
273       myEvolutionTableView->GetTableView()->resizeColumnToContents (i);
274     }
275   }
276 }
277
278 // =======================================================================
279 // function : GetValues
280 // purpose :
281 // =======================================================================
282 void DFBrowserPane_TNamingNamedShape::GetValues (const Handle(TDF_Attribute)&, QList<QVariant>&)
283 {
284 }
285
286 // =======================================================================
287 // function : GetAttributeInfo
288 // purpose :
289 // =======================================================================
290 QVariant DFBrowserPane_TNamingNamedShape::GetAttributeInfo (const Handle(TDF_Attribute)& theAttribute, int theRole,
291                                                             int theColumnId)
292 {
293   if (theColumnId != 0)
294     return DFBrowserPane_AttributePane::GetAttributeInfo (theAttribute, theRole, theColumnId);
295
296   switch (theRole)
297   {
298     case Qt::DecorationRole: return QIcon (":/icons/named_shape.png");
299     case DFBrowserPane_ItemRole_Decoration_40x40: return QIcon (":/icons/named_shape_40x40.png");
300     case Qt::ForegroundRole:
301     {
302       TopoDS_Shape aShape;
303       Handle(TNaming_NamedShape) anAttribute = Handle(TNaming_NamedShape)::DownCast (theAttribute);
304       if (!anAttribute.IsNull())
305         aShape = anAttribute->Get();
306       if (aShape.IsNull())
307         return QColor (Qt::black);
308
309       return QColor (aShape.Orientation() == TopAbs_FORWARD ? Qt::darkGray :
310                      aShape.Orientation() == TopAbs_REVERSED ? QColor (Qt::gray) : Qt::black);
311     }
312     default:
313     break;
314   }
315   return DFBrowserPane_AttributePane::GetAttributeInfo (theAttribute, theRole, theColumnId);
316 }
317
318 // =======================================================================
319 // function : GetShortAttributeInfo
320 // purpose :
321 // =======================================================================
322 void DFBrowserPane_TNamingNamedShape::GetShortAttributeInfo (const Handle(TDF_Attribute)& theAttribute,
323                                                              QList<QVariant>& theValues)
324 {
325   Handle(TNaming_NamedShape) aShapeAttribute = Handle(TNaming_NamedShape)::DownCast (theAttribute);
326
327   if (aShapeAttribute->Get().IsNull())
328     theValues.append ("EMPTY SHAPE");
329   else
330   {
331     theValues.append (QString ("%1 : %2").arg (DFBrowserPane_Tools::ToName (DB_SHAPE_TYPE, aShapeAttribute->Get().ShapeType()).ToCString())
332                                          .arg (DFBrowserPane_Tools::ToName (DB_NS_TYPE, aShapeAttribute->Evolution()).ToCString()));
333   }
334 }
335
336 // =======================================================================
337 // function : GetSelectionKind
338 // purpose :
339 // =======================================================================
340 int DFBrowserPane_TNamingNamedShape::GetSelectionKind (QItemSelectionModel* theModel)
341 {
342   int aKind = DFBrowserPane_AttributePaneAPI::GetSelectionKind (theModel);
343
344   QTableView* aTableView = myTableView->GetTableView();
345   if (aTableView->selectionModel() != theModel)
346     return aKind;
347
348   QModelIndexList aSelectedIndices = theModel->selectedIndexes();
349   if (aSelectedIndices.size() != 1)
350     return aKind;
351
352   QModelIndex aSelectedIndex = aSelectedIndices.first();
353   int aRow = aSelectedIndex.row();
354   if (aRow == 0 || aRow == 1)
355     return aKind;
356
357   if (aSelectedIndex.column() == 4)
358     aKind = DFBrowserPane_SelectionKind_ExportToShapeViewer;
359
360   return aKind;
361 }
362
363 // =======================================================================
364 // function : GetSelectionParameters
365 // purpose :
366 // =======================================================================
367 void DFBrowserPane_TNamingNamedShape::GetSelectionParameters (QItemSelectionModel* theModel,
368                                                               NCollection_List<Handle(Standard_Transient)>& theParameters)
369 {
370   QTableView* aTableView = myTableView->GetTableView();
371   if (aTableView->selectionModel() != theModel)
372     return;
373
374   QModelIndexList aSelectedIndices = theModel->selectedIndexes();
375   if (aSelectedIndices.size() != 1)
376     return;
377
378   QModelIndex aSelectedIndex = aSelectedIndices.first();
379   if (aSelectedIndex.column() != 4)
380     return;
381
382   const TopoDS_Shape& aShape = myHelperExport.GetShape (aSelectedIndex);
383   if (aShape.IsNull())
384     return;
385   theParameters.Append (aShape.TShape());
386 }
387
388 // =======================================================================
389 // function : GetReferences
390 // purpose :
391 // =======================================================================
392 void DFBrowserPane_TNamingNamedShape::GetReferences (const Handle(TDF_Attribute)& theAttribute,
393                                                      NCollection_List<TDF_Label>& theRefLabels,
394                                                      Handle(Standard_Transient)& theRefPresentation)
395 {
396   if (!myEvolutionTableView)
397     return;
398   QStringList aSelectedEntries = DFBrowserPane_TableView::GetSelectedColumnValues (
399                                                           myEvolutionTableView->GetTableView(), 9);
400
401   Handle(TNaming_NamedShape) aShapeAttr = Handle(TNaming_NamedShape)::DownCast (theAttribute);
402   for (TNaming_Iterator aShapeAttrIt (aShapeAttr); aShapeAttrIt.More(); aShapeAttrIt.Next())
403   {
404     const TopoDS_Shape& anOldShape = aShapeAttrIt.OldShape();
405
406     Handle(TNaming_NamedShape) anOldAttr = TNaming_Tool::NamedShape (anOldShape, aShapeAttr->Label());
407     QString aLabelInfo;
408     if (!anOldAttr.IsNull())
409     {
410       TDF_Label anOldLabel = anOldAttr->Label();
411       if (!anOldLabel.IsNull())
412       {
413         if (aSelectedEntries.contains (DFBrowserPane_Tools::GetEntry (anOldLabel).ToCString()))
414         theRefLabels.Append (anOldLabel);
415       }
416     }
417   }
418   TopoDS_Shape aShape = getSelectedShapes();
419   if (!aShape.IsNull())
420     theRefPresentation = new AIS_Shape (aShape);
421 }
422
423 // =======================================================================
424 // function : GetPresentation
425 // purpose :
426 // =======================================================================
427 Handle(Standard_Transient) DFBrowserPane_TNamingNamedShape::GetPresentation (const Handle(TDF_Attribute)& theAttribute)
428 {
429   Handle(Standard_Transient) aPresentation;
430   Handle(TNaming_NamedShape) aShapeAttr = Handle(TNaming_NamedShape)::DownCast (theAttribute);
431   if (aShapeAttr.IsNull())
432     return aPresentation;
433
434   TopoDS_Shape aShape = aShapeAttr->Get();
435   if (aShape.IsNull())
436     return aPresentation;
437
438   aPresentation = new AIS_Shape (aShape);
439   return aPresentation;
440 }
441
442 // =======================================================================
443 // function : getSelectedShapes
444 // purpose :
445 // =======================================================================
446 TopoDS_Shape DFBrowserPane_TNamingNamedShape::getSelectedShapes()
447 {
448   TopoDS_Shape aShape;
449
450   if (!myTableView && !myEvolutionTableView)
451     return aShape;
452
453   // table view selected shapes
454   QItemSelectionModel* aTableViewSelModel = myTableView->GetTableView()->selectionModel();
455   QModelIndexList anIndices = aTableViewSelModel->selectedIndexes();
456
457   BRep_Builder aBuilder;
458   TopoDS_Compound aComp;
459   aBuilder.MakeCompound (aComp);
460   bool aHasShapes = false;
461   for (QModelIndexList::const_iterator anIt = anIndices.begin(), aLast = anIndices.end(); anIt != aLast; anIt++)
462   {
463     QModelIndex anIndex = *anIt;
464     if (!myHelperExport.HasShape (anIndex))
465       continue;
466     aBuilder.Add (aComp, myHelperExport.GetShape (anIndex));
467     aHasShapes = true;
468   }
469
470   // evolution table selected shapes
471   aTableViewSelModel = myEvolutionTableView->GetTableView()->selectionModel();
472   anIndices.clear();
473   anIndices = aTableViewSelModel->selectedIndexes();
474   for (QModelIndexList::const_iterator anIt = anIndices.begin(), aLast = anIndices.end(); anIt != aLast; anIt++)
475   {
476     QModelIndex anIndex = *anIt;
477     if (!myHelperExport.HasShape (anIndex))
478       continue;
479     aBuilder.Add (aComp, myHelperExport.GetShape (anIndex));
480     aHasShapes = true;
481   }
482   if (aHasShapes)
483     aShape = aComp;
484   return aShape;
485 }