0030268: Inspectors - improvements in VInspector plugin
[occt.git] / tools / View / View_Window.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 #if !defined _WIN32
17 #define QT_CLEAN_NAMESPACE         /* avoid definition of INT32 and INT8 */
18 #endif
19
20 #include <inspector/View_Window.hxx>
21
22 #include <inspector/View_Displayer.hxx>
23 #include <inspector/View_DisplayPreview.hxx>
24 #include <inspector/View_PreviewParameters.hxx>
25 #include <inspector/View_ToolBar.hxx>
26 #include <inspector/View_Viewer.hxx>
27 #include <inspector/View_Widget.hxx>
28
29 #include <V3d.hxx>
30
31 #include <Standard_WarningsDisable.hxx>
32 #include <QComboBox>
33 #include <QDockWidget>
34 #include <QGridLayout>
35 #include <QMenu>
36 #include <QToolBar>
37 #include <Standard_WarningsRestore.hxx>
38
39 const int DEFAULT_SPACING = 3;
40
41 // =======================================================================
42 // function : Constructor
43 // purpose :
44 // =======================================================================
45 View_Window::View_Window (QWidget* theParent,
46                           const Handle(AIS_InteractiveContext)& theContext,
47                           const bool isUseKeepView, const bool isFitAllActive)
48 : QWidget (theParent)
49 {
50   QGridLayout* aViewLayout = new QGridLayout (this);
51   aViewLayout->setContentsMargins (0, 0, 0, 0);
52   aViewLayout->setSpacing (DEFAULT_SPACING);
53
54   myView = new View_Widget (this, theContext, isFitAllActive);
55   myViewToolBar = new View_ToolBar (this, isUseKeepView);
56   aViewLayout->addWidget (myViewToolBar->GetControl(), 0, 0, 1, 2);
57   connect (myViewToolBar, SIGNAL (contextChanged()), this, SLOT (onViewSelectorActivated()));
58   connect (myViewToolBar, SIGNAL (actionClicked (int)),
59           this, SLOT (onToolBarActionClicked (int)));
60
61   connect (myView, SIGNAL (checkedStateChanged(int, bool)), this, SLOT (onCheckedStateChanged (int, bool)));
62
63   myView->setContextMenuPolicy (Qt::CustomContextMenu);
64   connect (myView, SIGNAL (customContextMenuRequested (const QPoint&)),
65            this, SLOT (onViewContextMenuRequested (const QPoint&)));
66
67   myActionsToolBar = new QToolBar (this);
68   myActionsToolBar->layout()->setContentsMargins (0, 0, 0, 0);
69   myActionsToolBar->setOrientation (Qt::Vertical);
70
71   myActionsToolBar->addWidget (myView-> GetWidget (View_ViewActionType_FitAllId));
72   for (int anActionId = View_ViewActionType_FitAreaId; anActionId <= View_ViewActionType_DisplayModeId; anActionId++)
73     myActionsToolBar->addAction (myView->ViewAction ((View_ViewActionType)anActionId));
74
75   aViewLayout->addWidget (myActionsToolBar, 1, 0);
76   aViewLayout->addWidget (myView, 1, 1);
77   aViewLayout->setRowStretch (1, 1);
78
79   Handle(AIS_InteractiveContext) aContext = myView->GetViewer()->GetContext();
80   myViewToolBar->SetContext (View_ContextType_Own, aContext);
81
82   myDisplayer = new View_Displayer();
83   if (!isUseKeepView)
84     myDisplayer->KeepPresentations (true);
85   myDisplayer->SetFitAllActive (isFitAllActive);
86   connect (myView, SIGNAL (displayModeClicked()), this, SLOT (onDisplayModeChanged()));
87   onViewSelectorActivated();
88 }
89
90 // =======================================================================
91 // function : SetContext
92 // purpose :
93 // =======================================================================
94 void View_Window::SetContext (View_ContextType /*theType*/, const Handle(AIS_InteractiveContext)& theContext)
95 {
96   ViewToolBar()->SetContext (View_ContextType_External, theContext);
97 }
98
99 // =======================================================================
100 // function : SaveState
101 // purpose :
102 // =======================================================================
103 void View_Window::SaveState (View_Window* theView, QMap<QString, QString>& theItems,
104                              const QString& thePrefix)
105 {
106   QStringList aCameraDirection;
107   Standard_Real aVX, aVY, aVZ;
108   Handle(V3d_View) aView = theView->ViewWidget()->GetViewer()->GetView();
109   if (aView.IsNull())
110     return;
111
112   aView->Proj (aVX, aVY, aVZ);
113   aCameraDirection << QString::number (aVX) << QString::number (aVY) << QString::number (aVZ);
114
115   theItems[thePrefix + "view_camera_direction"] = aCameraDirection.join (",");
116
117   View_PreviewParameters::SaveState (theView->Displayer()->DisplayPreview()->GetPreviewParameters(), theItems, "preview_parameters_");
118   View_ToolBar::SaveState (theView->ViewToolBar(), theItems, "view_toolbar_");
119   View_Widget::SaveState (theView->ViewWidget(), theItems, "view_widget_");
120 }
121
122 // =======================================================================
123 // function : RestoreState
124 // purpose :
125 // =======================================================================
126 bool View_Window::RestoreState (View_Window* theView, const QString& theKey, const QString& theValue,
127                                 const QString& thePrefix)
128 {
129   if (theKey == thePrefix + "view_camera_direction")
130   {
131     QStringList aValues = theValue.split (",");
132     if (aValues.size() == 3)
133     {
134       Standard_Real aVX = aValues.at (0).toDouble();
135       Standard_Real aVY = aValues.at (1).toDouble();
136       Standard_Real aVZ = aValues.at (2).toDouble();
137
138       theView->ViewWidget()->SetInitProj (aVX, aVY, aVZ);
139     }
140     return true;
141   }
142   else if (View_PreviewParameters::RestoreState (theView->Displayer()->DisplayPreview()->GetPreviewParameters(),
143                                                  theKey, theValue, "preview_parameters_"))
144   {
145     return true;
146   }
147   else if (View_ToolBar::RestoreState (theView->ViewToolBar(), theKey, theValue, "view_toolbar_"))
148   {
149     return true;
150   }
151   else if (View_Widget::RestoreState (theView->ViewWidget(), theKey, theValue, "view_widget_"))
152   {
153     // display mode is restored
154     View_Displayer* aDisplayer = theView->Displayer();
155     if (theView->ViewWidget()->DisplayMode() != aDisplayer->DisplayMode())
156       aDisplayer->SetDisplayMode (theView->ViewWidget()->DisplayMode());
157
158     bool toFitAll = theView->ViewWidget()->IsActionChecked (View_ViewActionType_FitAllId);
159     if (toFitAll != aDisplayer->IsFitAllActive())
160       aDisplayer->SetFitAllActive (toFitAll);
161
162     return true;
163   }
164
165   return false;
166 }
167
168 // =======================================================================
169 // function : onViewSelectorActivated
170 // purpose :
171 // =======================================================================
172 void View_Window::onViewSelectorActivated()
173 {
174   View_ContextType aType = myViewToolBar->CurrentContextType();
175   bool isViewEnabled = aType == View_ContextType_Own;
176
177   myView->SetEnabledView (isViewEnabled);
178
179   Handle(AIS_InteractiveContext) aContext = myViewToolBar->CurrentContext();
180   myDisplayer->EraseAllPresentations (true);
181   emit eraseAllPerformed();
182
183   myDisplayer->SetContext (aContext);
184 }
185
186 // =======================================================================
187 // function : onToolBarActionClicked
188 // purpose :
189 // =======================================================================
190 void View_Window::onToolBarActionClicked (const int theActionId)
191 {
192   switch (theActionId)
193   {
194     case View_ToolActionType_Trihedron:
195     {
196       myDisplayer->DisplayDefaultTrihedron (myViewToolBar->IsActionChecked (theActionId), Standard_True);
197       break;
198     }
199     case View_ToolActionType_KeepViewId:
200     {
201       myDisplayer->KeepPresentations (myViewToolBar->IsActionChecked (theActionId));
202       break;
203     }
204     case View_ToolActionType_KeepViewOffId:
205     {
206       myDisplayer->KeepPresentations (!myViewToolBar->IsActionChecked (theActionId));
207       break;
208     }
209     case View_ToolActionType_ClearViewId:
210     {
211       myDisplayer->EraseAllPresentations (true);
212       emit eraseAllPerformed();
213       break;
214     }
215     default:
216       break;
217   }
218 }
219
220 // =======================================================================
221 // function : onCheckedStateChanged
222 // purpose :
223 // =======================================================================
224 void View_Window::onCheckedStateChanged (int theActionId, bool theState)
225 {
226   if (theActionId == View_ViewActionType_FitAllId)
227     myDisplayer->SetFitAllActive (theState);
228 }
229
230 // =======================================================================
231 // function : onViewContextMenuRequested
232 // purpose :
233 // =======================================================================
234 void View_Window::onViewContextMenuRequested (const QPoint& thePosition)
235 {
236   QMenu* aMenu = new QMenu (this);
237   QMenu* anOrientationSubMenu = aMenu->addMenu ("Set View Orientation");
238
239   for (int i = 0; i < (int)V3d_XnegYnegZneg; i++)
240   {
241     V3d_TypeOfOrientation anOrientationType = (V3d_TypeOfOrientation)i;
242
243     QAction* anAction = new QAction (V3d::TypeOfOrientationToString (anOrientationType), this);
244     QObject::connect (anAction, SIGNAL (triggered (bool)), this, SLOT (onSetOrientation()));
245
246     anOrientationSubMenu->addAction (anAction);
247   }
248   aMenu->addMenu (anOrientationSubMenu);
249
250   QPoint aPoint = myView->mapToGlobal (thePosition);
251   aMenu->exec (aPoint);
252 }
253
254 // =======================================================================
255 // function : onSetOrientation
256 // purpose :
257 // =======================================================================
258 void View_Window::onSetOrientation()
259 {
260   QAction* anAction = (QAction*)(sender());
261
262   TCollection_AsciiString anOrientationStr (anAction->text().toStdString().c_str());
263
264   V3d_TypeOfOrientation anOrientationType;
265   if (!V3d::TypeOfOrientationFromString (anOrientationStr.ToCString(), anOrientationType))
266     return;
267
268   Handle(V3d_View) aView = myView->GetViewer()->GetView();
269   if (aView.IsNull())
270     return;
271
272   aView->SetProj (anOrientationType);
273   aView->FitAll();
274   aView->Redraw();
275 }
276
277 // =======================================================================
278 // function : onDisplayModeChanged
279 // purpose :
280 // =======================================================================
281 void View_Window::onDisplayModeChanged()
282 {
283   int aDisplayMode = myView->DisplayMode();
284   for (NCollection_DataMap<View_PresentationType, NCollection_Shared<AIS_ListOfInteractive> >::Iterator
285        anIterator(myDisplayer->GetDisplayed()); anIterator.More(); anIterator.Next())
286     myDisplayer->SetDisplayMode (aDisplayMode, anIterator.Key(), false);
287   myDisplayer->UpdateViewer();
288 }