Salome HOME
b6f418979ca2c07f067cb87eda78fb895f805811
[modules/shaper.git] / src / XGUI / XGUI_InspectionPanel.cpp
1 // Copyright (C) 2014-2023  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "XGUI_InspectionPanel.h"
21 #include "XGUI_Workshop.h"
22 #include "XGUI_SelectionMgr.h"
23 #include "XGUI_Selection.h"
24 #include "XGUI_Tools.h"
25 #include "XGUI_ModuleConnector.h"
26
27 #include <ModuleBase_ViewerPrs.h>
28 #include <ModuleBase_Tools.h>
29 #include <ModuleBase_OperationDescription.h>
30 #include <ModuleBase_WidgetFactory.h>
31 #include <ModuleBase_IModule.h>
32 #include <ModuleBase_PageWidget.h>
33
34 #include <ModelAPI_ResultField.h>
35
36 #include <ModelAPI_Result.h>
37
38 #include <QLayout>
39 #include <QScrollArea>
40 #include <QLabel>
41 #include <QLineEdit>
42 #include <QTableWidget>
43 #include <QHeaderView>
44 #include <QTextBrowser>
45 #include <QResizeEvent>
46 #include <QSplitter>
47 #include <QStackedWidget>
48
49 #include <TopTools_MapOfShape.hxx>
50 #include <TopTools_ListOfShape.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic
53
54
55 // ================     XGUI_InspectionPanel    ================
56 XGUI_InspectionPanel::XGUI_InspectionPanel(QWidget* theParent, XGUI_Workshop* theWorkshop)
57   : QDockWidget(theParent),
58   myWorkshop(theWorkshop)
59 {
60   setWindowTitle(tr("Inspection Panel"));
61   setObjectName(INSPECTION_PANEL);
62   setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }");
63
64   myStackWgt = new QStackedWidget(this);
65
66   // Create shape selection page
67   QSplitter* aSplitter = new QSplitter(Qt::Vertical, myStackWgt);
68
69   // Create an internal widget
70   QWidget* aNameWgt = new QWidget(aSplitter);
71   QHBoxLayout* aNameLayout = new QHBoxLayout(aNameWgt);
72   aNameLayout->setContentsMargins(3, 0, 3, 0);
73   aNameLayout->addWidget(new QLabel(tr("Object"), aNameWgt));
74   myNameEdt = new QLineEdit(aNameWgt);
75   myNameEdt->setReadOnly(true);
76   aNameLayout->addWidget(myNameEdt);
77
78   aSplitter->addWidget(aNameWgt);
79
80   // Table with sub-shapes
81   mySubShapesTab = new QTableWidget(9, 2, aSplitter);
82   mySubShapesTab->setFocusPolicy(Qt::NoFocus);
83   mySubShapesTab->verticalHeader()->hide();
84   QStringList aTitles;
85   aTitles << tr("Sub-shapes") << tr("Number");
86   mySubShapesTab->setHorizontalHeaderLabels(aTitles);
87
88   QStringList aSubShapes;
89   aSubShapes << tr("SHAPE") << tr("COMPOUND") << tr("COMPSOLID") <<
90     tr("SOLID") << tr("SHELL") << tr("FACE") << tr("WIRE") << tr("EDGE") << tr("VERTEX");
91   int i = 0;
92   foreach(QString aType, aSubShapes) {
93     QTableWidgetItem* aItem = new QTableWidgetItem(aType);
94     aItem->setFlags(Qt::ItemIsEnabled);
95     mySubShapesTab->setItem(i++, 0, aItem);
96   }
97   for (i = 0; i < 9; i++) {
98     QTableWidgetItem* aItem = new QTableWidgetItem("");
99     aItem->setFlags(Qt::ItemIsEnabled);
100     aItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
101     mySubShapesTab->setItem(i, 1, aItem);
102   }
103   mySubShapesTab->setColumnWidth(0, 90);
104   mySubShapesTab->setColumnWidth(1, 70);
105
106   aSplitter->addWidget(mySubShapesTab);
107
108   // Type of object
109   QWidget* aTypeWgt = new QWidget(aSplitter);
110   QHBoxLayout* aTypeLayout = new QHBoxLayout(aTypeWgt);
111   aTypeLayout->setContentsMargins(3, 0, 3, 0);
112
113   aTypeLayout->addWidget(new QLabel(tr("Type:"), aTypeWgt));
114   myTypeLbl = new QLabel("", aTypeWgt);
115   aTypeLayout->addWidget(myTypeLbl);
116
117   aSplitter->addWidget(aTypeWgt);
118
119   myTypeParams = new QTextBrowser(aSplitter);
120   myTypeParams->setReadOnly(true);
121   myTypeParams->setFocusPolicy(Qt::NoFocus);
122   myTypeParams->viewport()->setBackgroundRole(QPalette::Window);
123
124   aSplitter->addWidget(myTypeParams);
125
126   aSplitter->setCollapsible(0, false);
127   aSplitter->setCollapsible(1, false);
128   aSplitter->setCollapsible(2, false);
129   aSplitter->setCollapsible(3, false);
130
131   QList<int> aSizes;
132   aSizes << 10 << 140 << 10;
133   aSplitter->setSizes(aSizes);
134
135   myShapePanelId = myStackWgt->addWidget(aSplitter);
136
137   // Create feature selection page
138   QScrollArea* aScroll = new QScrollArea(myStackWgt);
139   aScroll->setWidgetResizable(true);
140   aScroll->setFrameStyle(QFrame::NoFrame);
141
142   myFeaturePane = new ModuleBase_PageWidget(aScroll);
143   myFeatureLayout = new QGridLayout(myFeaturePane);
144   myFeatureLayout->setContentsMargins(3, 3, 3, 3);
145   aScroll->setWidget(myFeaturePane);
146   //myFeaturePane->setEnabled(false);
147
148   myFeaturePanelId = myStackWgt->addWidget(aScroll);
149
150   setWidget(myStackWgt);
151   connect(myWorkshop->selector(), SIGNAL(selectionChanged()), SLOT(onSelectionChanged()));
152 }
153
154 //********************************************************************
155 XGUI_InspectionPanel::~XGUI_InspectionPanel()
156 {
157 }
158
159 //********************************************************************
160 void XGUI_InspectionPanel::setSubShapeValue(SudShape theId, int theVal)
161 {
162   mySubShapesTab->item(theId, 1)->setText(QString::number(theVal));
163 }
164
165 //********************************************************************
166 void XGUI_InspectionPanel::clearContent()
167 {
168   myStackWgt->setCurrentIndex(myFeaturePanelId);
169   setName("");
170   for (int i = 0; i <= VertexId; i++) {
171     mySubShapesTab->item((SudShape)i, 1)->setText("");
172   }
173   myTypeLbl->setText("");
174   setParamsText("");
175
176   myFeaturePane->clearPage();
177 }
178
179 //********************************************************************
180 void XGUI_InspectionPanel::onSelectionChanged()
181 {
182   if (!isVisible())
183     return;
184
185   clearContent();
186
187   XGUI_Selection* aSelection = myWorkshop->selector()->selection();
188   QList<ModuleBase_ViewerPrsPtr> aSelectedList =
189     aSelection->getSelected(myWorkshop->selector()->placeOfSelection());
190
191   if (aSelectedList.count() > 0) {
192     ModuleBase_ViewerPrsPtr aPrs = aSelectedList.first();
193     FieldStepPtr aStep =
194       std::dynamic_pointer_cast<ModelAPI_ResultField::ModelAPI_FieldStep>(aPrs->object());
195     if (aStep)
196       return;
197     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aPrs->object());
198     if (aFeature.get()) {
199       myStackWgt->setCurrentIndex(myFeaturePanelId);
200       buildFeaturePane(aFeature);
201     }
202     else {
203       TopoDS_Shape aShape = ModuleBase_Tools::getSelectedShape(aPrs);
204       if (aShape.IsNull()) {
205         ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aPrs->object());
206         if (aRes.get()) {
207           GeomShapePtr aShpPtr = aRes->shape();
208           if (aShpPtr.get()) {
209             aShape = aShpPtr->impl<TopoDS_Shape>();
210           }
211         }
212       }
213       if (aShape.IsNull()) {
214         myStackWgt->setCurrentIndex(myFeaturePanelId);
215         return;
216       }
217       myStackWgt->setCurrentIndex(myShapePanelId);
218       GeomShapePtr aShapePtr(new GeomAPI_Shape());
219       aShapePtr->setImpl(new TopoDS_Shape(aShape));
220
221       ModuleBase_ViewerPrsPtr aPrsCopy(new ModuleBase_ViewerPrs(aPrs->object(), aShapePtr));
222       setName(XGUI_Tools::generateName(aPrsCopy));
223       setShapeContent(aShape);
224
225       GeomShapePtr aGShape(new GeomAPI_Shape);
226       aGShape->setImpl(new TopoDS_Shape(aShape));
227       GeomAlgoAPI_ShapeInfo aShapeInfo(aGShape);
228       QString aParams = QString::fromStdString(aShapeInfo.html(this));
229       setParamsText(aParams);
230       myTypeLbl->setText(tr(aShapeInfo.shapeType().c_str()));
231     }
232   }
233 }
234
235 //********************************************************************
236 void XGUI_InspectionPanel::setName(const QString& theName)
237 {
238   myNameEdt->setText(theName);
239 }
240
241 //********************************************************************
242 void XGUI_InspectionPanel::setShapeContent(const TopoDS_Shape& theShape)
243 {
244   try {
245     OCC_CATCH_SIGNALS;
246     int iType, nbTypes[TopAbs_SHAPE];
247     for (iType = 0; iType < TopAbs_SHAPE; ++iType) {
248       nbTypes[iType] = 0;
249     }
250     nbTypes[theShape.ShapeType()]++;
251
252     TopTools_MapOfShape aMapOfShape;
253     aMapOfShape.Add(theShape);
254     TopTools_ListOfShape aListOfShape;
255     aListOfShape.Append(theShape);
256
257     TopTools_ListIteratorOfListOfShape itL(aListOfShape);
258     for (; itL.More(); itL.Next()) {
259       TopoDS_Shape sp = itL.Value();
260       TopoDS_Iterator it(sp);
261       for (; it.More(); it.Next()) {
262         TopoDS_Shape s = it.Value();
263         if (aMapOfShape.Add(s)) {
264           aListOfShape.Append(s);
265           nbTypes[s.ShapeType()]++;
266         }
267       }
268     }
269     setSubShapeValue(VertexId, nbTypes[TopAbs_VERTEX]);
270     setSubShapeValue(EdgeId, nbTypes[TopAbs_EDGE]);
271     setSubShapeValue(WireId, nbTypes[TopAbs_WIRE]);
272     setSubShapeValue(FaceId, nbTypes[TopAbs_FACE]);
273     setSubShapeValue(ShellId, nbTypes[TopAbs_SHELL]);
274     setSubShapeValue(SolidId, nbTypes[TopAbs_SOLID]);
275     setSubShapeValue(CompsolidId, nbTypes[TopAbs_COMPSOLID]);
276     setSubShapeValue(CompoundId, nbTypes[TopAbs_COMPOUND]);
277     setSubShapeValue(ShapeId, aMapOfShape.Extent());
278   }
279   catch (Standard_Failure) {
280   }
281 }
282
283 std::string XGUI_InspectionPanel::translate(const char* theSource)
284 {
285   return std::string(tr(theSource).toStdString());
286 }
287
288 //********************************************************************
289 void XGUI_InspectionPanel::setParamsText(const QString& theText)
290 {
291   myTypeParams->setText(theText);
292 }
293
294 //********************************************************************
295 void XGUI_InspectionPanel::buildFeaturePane(const FeaturePtr& theFeature)
296 {
297   std::string aXmlCfg, aDescription;
298   myWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
299   if (!aXmlCfg.empty()) {
300     QList<ModuleBase_ModelWidget*> aWidgets;
301     if (!myWorkshop->module()->createWidgets(theFeature, aXmlCfg.c_str(), aWidgets)) {
302       ModuleBase_WidgetFactory aFactory(aXmlCfg, myWorkshop->moduleConnector());
303       aFactory.createWidget(myFeaturePane);
304       aWidgets = aFactory.getModelWidgets();
305     }
306     foreach(ModuleBase_ModelWidget* aWgt, aWidgets) {
307       if (aWgt->isInformative()) {
308         aWgt->setFeature(theFeature, false, false);
309         aWgt->setReadOnly(true);
310         aWgt->setEditingMode(true);
311         aWgt->restoreValue();
312         aWgt->showInformativePage();
313       }
314       else {
315         aWgt->setFeature(theFeature, false, false);
316         aWgt->setEditingMode(true);
317         aWgt->hide();
318       }
319     }
320   }
321 }
322
323 void XGUI_InspectionPanel::showEvent(QShowEvent* theEvent)
324 {
325   QDockWidget::showEvent(theEvent);
326   onSelectionChanged();
327 }