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 // =======================================================================
View_Window(QWidget * theParent,const Handle (AIS_InteractiveContext)& theContext,const bool isUseKeepView,const bool isFitAllActive)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   myActionsToolBar->addAction (myView->ViewAction (View_ViewActionType_DisplayModeId));
73 
74   aViewLayout->addWidget (myActionsToolBar, 1, 0);
75   aViewLayout->addWidget (myView, 1, 1);
76   aViewLayout->setRowStretch (1, 1);
77 
78   Handle(AIS_InteractiveContext) aContext = myView->GetViewer()->GetContext();
79   myViewToolBar->SetContext (View_ContextType_Own, aContext);
80 
81   myDisplayer = new View_Displayer();
82   if (!isUseKeepView)
83     myDisplayer->KeepPresentations (true);
84   myDisplayer->SetFitAllActive (isFitAllActive);
85   connect (myView, SIGNAL (displayModeClicked()), this, SLOT (onDisplayModeChanged()));
86   onViewSelectorActivated();
87 }
88 
89 // =======================================================================
90 // function : SetContext
91 // purpose :
92 // =======================================================================
SetContext(View_ContextType,const Handle (AIS_InteractiveContext)& theContext)93 void View_Window::SetContext (View_ContextType /*theType*/, const Handle(AIS_InteractiveContext)& theContext)
94 {
95   ViewToolBar()->SetContext (View_ContextType_External, theContext);
96 }
97 
98 // =======================================================================
99 // function : SetPredefinedSize
100 // purpose :
101 // =======================================================================
SetPredefinedSize(int theDefaultWidth,int theDefaultHeight)102 void View_Window::SetPredefinedSize (int theDefaultWidth, int theDefaultHeight)
103 {
104   myView->SetPredefinedSize (theDefaultWidth, theDefaultHeight);
105 }
106 
107 // =======================================================================
108 // function : SetInitProj
109 // purpose :
110 // =======================================================================
SetInitProj(const Standard_Real theVx,const Standard_Real theVy,const Standard_Real theVz)111 void View_Window::SetInitProj (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
112 {
113   myView->SetInitProj (theVx, theVy, theVz);
114 }
115 
116 // =======================================================================
117 // function : View
118 // purpose :
119 // =======================================================================
Handle(V3d_View)120 Handle(V3d_View) View_Window::View() const
121 {
122   return myView->GetViewer()->GetView();
123 }
124 
125 // =======================================================================
126 // function : SaveState
127 // purpose :
128 // =======================================================================
SaveState(View_Window * theView,QMap<QString,QString> & theItems,const QString & thePrefix)129 void View_Window::SaveState (View_Window* theView, QMap<QString, QString>& theItems,
130                              const QString& thePrefix)
131 {
132   QStringList aCameraDirection;
133   Standard_Real aVX, aVY, aVZ;
134   Handle(V3d_View) aView = theView->View();
135   if (aView.IsNull())
136     return;
137 
138   aView->Proj (aVX, aVY, aVZ);
139   aCameraDirection << QString::number (aVX) << QString::number (aVY) << QString::number (aVZ);
140 
141   theItems[thePrefix + "view_camera_direction"] = aCameraDirection.join (",");
142 
143   View_PreviewParameters::SaveState (theView->Displayer()->DisplayPreview()->GetPreviewParameters(), theItems, "preview_parameters_");
144   View_ToolBar::SaveState (theView->ViewToolBar(), theItems, "view_toolbar_");
145   View_Widget::SaveState (theView->ViewWidget(), theItems, "view_widget_");
146 }
147 
148 // =======================================================================
149 // function : RestoreState
150 // purpose :
151 // =======================================================================
RestoreState(View_Window * theView,const QString & theKey,const QString & theValue,const QString & thePrefix)152 bool View_Window::RestoreState (View_Window* theView, const QString& theKey, const QString& theValue,
153                                 const QString& thePrefix)
154 {
155   if (theKey == thePrefix + "view_camera_direction")
156   {
157     QStringList aValues = theValue.split (",");
158     if (aValues.size() == 3)
159     {
160       Standard_Real aVX = aValues.at (0).toDouble();
161       Standard_Real aVY = aValues.at (1).toDouble();
162       Standard_Real aVZ = aValues.at (2).toDouble();
163 
164       theView->SetInitProj (aVX, aVY, aVZ);
165     }
166     return true;
167   }
168   else if (View_PreviewParameters::RestoreState (theView->Displayer()->DisplayPreview()->GetPreviewParameters(),
169                                                  theKey, theValue, "preview_parameters_"))
170   {
171     return true;
172   }
173   else if (View_ToolBar::RestoreState (theView->ViewToolBar(), theKey, theValue, "view_toolbar_"))
174   {
175     return true;
176   }
177   else if (View_Widget::RestoreState (theView->ViewWidget(), theKey, theValue, "view_widget_"))
178   {
179     // display mode is restored
180     View_Displayer* aDisplayer = theView->Displayer();
181     if (theView->ViewWidget()->DisplayMode() != aDisplayer->DisplayMode())
182       aDisplayer->SetDisplayMode (theView->ViewWidget()->DisplayMode());
183 
184     bool toFitAll = theView->ViewWidget()->IsActionChecked (View_ViewActionType_FitAllId);
185     if (toFitAll != aDisplayer->IsFitAllActive())
186       aDisplayer->SetFitAllActive (toFitAll);
187 
188     return true;
189   }
190 
191   return false;
192 }
193 
194 // =======================================================================
195 // function : onViewSelectorActivated
196 // purpose :
197 // =======================================================================
onViewSelectorActivated()198 void View_Window::onViewSelectorActivated()
199 {
200   View_ContextType aType = myViewToolBar->CurrentContextType();
201   bool isViewEnabled = aType == View_ContextType_Own;
202 
203   myView->SetEnabledView (isViewEnabled);
204 
205   Handle(AIS_InteractiveContext) aContext = myViewToolBar->CurrentContext();
206   myDisplayer->EraseAllPresentations (true);
207   emit eraseAllPerformed();
208 
209   myDisplayer->SetContext (aContext);
210 }
211 
212 // =======================================================================
213 // function : onToolBarActionClicked
214 // purpose :
215 // =======================================================================
onToolBarActionClicked(const int theActionId)216 void View_Window::onToolBarActionClicked (const int theActionId)
217 {
218   switch (theActionId)
219   {
220     case View_ToolActionType_Trihedron:
221     {
222       myDisplayer->DisplayDefaultTrihedron (myViewToolBar->IsActionChecked (theActionId), Standard_True);
223       break;
224     }
225     case View_ToolActionType_ViewCube:
226     {
227       myDisplayer->DisplayViewCube (myViewToolBar->IsActionChecked (theActionId), Standard_True);
228       break;
229     }
230 
231     case View_ToolActionType_KeepViewId:
232     {
233       myDisplayer->KeepPresentations (myViewToolBar->IsActionChecked (theActionId));
234       break;
235     }
236     case View_ToolActionType_KeepViewOffId:
237     {
238       myDisplayer->KeepPresentations (!myViewToolBar->IsActionChecked (theActionId));
239       break;
240     }
241     case View_ToolActionType_ClearViewId:
242     {
243       myDisplayer->EraseAllPresentations (true);
244       emit eraseAllPerformed();
245       break;
246     }
247     default:
248       break;
249   }
250 }
251 
252 // =======================================================================
253 // function : onCheckedStateChanged
254 // purpose :
255 // =======================================================================
onCheckedStateChanged(int theActionId,bool theState)256 void View_Window::onCheckedStateChanged (int theActionId, bool theState)
257 {
258   if (theActionId == View_ViewActionType_FitAllId)
259     myDisplayer->SetFitAllActive (theState);
260 }
261 
262 // =======================================================================
263 // function : onViewContextMenuRequested
264 // purpose :
265 // =======================================================================
onViewContextMenuRequested(const QPoint & thePosition)266 void View_Window::onViewContextMenuRequested (const QPoint& thePosition)
267 {
268   QMenu* aMenu = new QMenu (this);
269   QMenu* anOrientationSubMenu = aMenu->addMenu ("Set View Orientation");
270 
271   for (int i = 0; i < (int)V3d_XnegYnegZneg; i++)
272   {
273     V3d_TypeOfOrientation anOrientationType = (V3d_TypeOfOrientation)i;
274 
275     QAction* anAction = new QAction (V3d::TypeOfOrientationToString (anOrientationType), this);
276     QObject::connect (anAction, SIGNAL (triggered (bool)), this, SLOT (onSetOrientation()));
277 
278     anOrientationSubMenu->addAction (anAction);
279   }
280   aMenu->addMenu (anOrientationSubMenu);
281 
282   QPoint aPoint = myView->mapToGlobal (thePosition);
283   aMenu->exec (aPoint);
284 }
285 
286 // =======================================================================
287 // function : onSetOrientation
288 // purpose :
289 // =======================================================================
onSetOrientation()290 void View_Window::onSetOrientation()
291 {
292   QAction* anAction = (QAction*)(sender());
293 
294   TCollection_AsciiString anOrientationStr (anAction->text().toStdString().c_str());
295 
296   V3d_TypeOfOrientation anOrientationType;
297   if (!V3d::TypeOfOrientationFromString (anOrientationStr.ToCString(), anOrientationType))
298     return;
299 
300   Handle(V3d_View) aView = myView->GetViewer()->GetView();
301   if (aView.IsNull())
302     return;
303 
304   aView->SetProj (anOrientationType);
305   aView->FitAll();
306   aView->Redraw();
307 }
308 
309 // =======================================================================
310 // function : onDisplayModeChanged
311 // purpose :
312 // =======================================================================
onDisplayModeChanged()313 void View_Window::onDisplayModeChanged()
314 {
315   int aDisplayMode = myView->DisplayMode();
316   for (NCollection_DataMap<View_PresentationType, NCollection_Shared<AIS_ListOfInteractive> >::Iterator
317        anIterator(myDisplayer->GetDisplayed()); anIterator.More(); anIterator.Next())
318     myDisplayer->SetDisplayMode (aDisplayMode, anIterator.Key(), false);
319   myDisplayer->UpdateViewer();
320 }
321