]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_Viewer.cpp
Salome HOME
Prevent crash when viewer opened
[modules/shaper.git] / src / XGUI / XGUI_Viewer.cpp
1 #include "XGUI_Viewer.h"
2 #include "XGUI_MainWindow.h"
3 #include "XGUI_ViewWindow.h"
4 #include "XGUI_ViewPort.h"
5
6 #include <QMdiArea>
7 #include <QMdiSubWindow>
8 #include <QApplication>
9 #include <QMouseEvent>
10 #include <QMenu>
11
12 #include <V3d_View.hxx>
13
14 #include <Aspect_DisplayConnection.hxx>
15 #include <Graphic3d.hxx>
16 #include <Graphic3d_GraphicDriver.hxx>
17 #include <Geom_Axis2Placement.hxx>
18 #include <AIS_Drawer.hxx>
19 #include <Prs3d_DatumAspect.hxx>
20 #include <Prs3d_LineAspect.hxx>
21 #include <V3d_View.hxx>
22 #include <Visual3d_View.hxx>
23 #include <AIS_ListOfInteractive.hxx>
24 #include <AIS_ListIteratorOfListOfInteractive.hxx>
25 #include <AIS_Shape.hxx>
26
27
28 #ifdef WIN32
29 #include <WNT_Window.hxx>
30 #else
31 #include <Xw_Window.hxx>
32 #endif
33
34 XGUI_Viewer::InteractionStyle2StatesMap XGUI_Viewer::myStateMap;
35 XGUI_Viewer::InteractionStyle2ButtonsMap XGUI_Viewer::myButtonMap;
36 static bool isInitialized = false;
37
38 /*!
39  Creates viewer 3d [ static ]
40  */
41 Handle(V3d_Viewer) CreateViewer(const Standard_ExtString name, const Standard_CString displayName,
42                                 const Standard_CString domain, const Standard_Real viewSize,
43                                 const V3d_TypeOfOrientation viewProjection,
44                                 const Standard_Boolean computedMode,
45                                 const Standard_Boolean defaultComputedMode)
46 {
47   static Handle(Graphic3d_GraphicDriver) aGraphicDriver;
48   if (aGraphicDriver.IsNull()) {
49     Handle(Aspect_DisplayConnection) aDisplayConnection;
50 #ifndef WIN32
51     aDisplayConnection = new Aspect_DisplayConnection( displayName );
52 #else
53     aDisplayConnection = new Aspect_DisplayConnection();
54 #endif
55     aGraphicDriver = Graphic3d::InitGraphicDriver(aDisplayConnection);
56   }
57
58   return new V3d_Viewer(aGraphicDriver, name, domain, viewSize, viewProjection, Quantity_NOC_GRAY30,
59                         V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT, computedMode, defaultComputedMode,
60                         V3d_TEX_NONE);
61 }
62
63 // VSR: Uncomment below line to allow texture background support in OCC viewer
64 #define OCC_ENABLE_TEXTURED_BACKGROUND
65
66 /*!
67  Get data for supported background modes: gradient types, identifiers and supported image formats
68  */
69 QString XGUI_Viewer::backgroundData(QStringList& gradList, QIntList& idList, QIntList& txtList)
70 {
71   gradList << tr("Horizontal gradient") << tr("Vertical gradient")
72       << tr("First diagonal gradient") << tr("Second diagonal gradient")
73       << tr("First corner gradient") << tr("Second corner gradient")
74       << tr("Third corner gradient") << tr("Fourth corner gradient");
75   idList << XGUI::HorizontalGradient << XGUI::VerticalGradient << XGUI::Diagonal1Gradient
76       << XGUI::Diagonal2Gradient << XGUI::Corner1Gradient << XGUI::Corner2Gradient
77       << XGUI::Corner3Gradient << XGUI::Corner4Gradient;
78 #ifdef OCC_ENABLE_TEXTURED_BACKGROUND
79   txtList << XGUI::CenterTexture << XGUI::TileTexture << XGUI::StretchTexture;
80 #endif
81   return tr("Image files (*.bmp *.gif *.pix *.xwd *.rgb *.rs)");
82 }
83
84 XGUI_Viewer::XGUI_Viewer(XGUI_MainWindow* theParent, bool DisplayTrihedron)
85     : QObject(theParent), 
86     myMainWindow(theParent), 
87     myPreselectionEnabled(true), 
88     mySelectionEnabled(true), 
89     myMultiSelectionEnabled(true), 
90     myIsRelative(true), 
91     myInteractionStyle(XGUI::STANDARD), 
92     myTrihedronSize(100),
93     myActiveView(0),
94     myWndIdCount(0)
95 {
96   if (!isInitialized) {
97     isInitialized = true;
98
99     // standard interaction style
100     XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::ZOOM] = Qt::ControlModifier;
101     XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::ZOOM] = Qt::LeftButton;
102
103     XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::PAN] = Qt::ControlModifier;
104     XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::PAN] = Qt::MidButton;
105
106     XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::ROTATE] = Qt::ControlModifier;
107     XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::ROTATE] = Qt::RightButton;
108
109     XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::FIT_AREA] = Qt::ControlModifier;
110     XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::FIT_AREA] = Qt::RightButton;
111
112     // "key free" interaction style
113     XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::ZOOM] = Qt::NoModifier;
114     XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::ZOOM] = Qt::RightButton;
115
116     XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::PAN] = Qt::NoModifier;
117     XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::PAN] = Qt::MidButton;
118
119     XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::ROTATE] = Qt::NoModifier;
120     XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::ROTATE] = Qt::LeftButton;
121
122     XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::FIT_AREA] = Qt::NoModifier; // unused
123     XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::FIT_AREA] = Qt::NoButton; // unused
124   }
125
126   // init CasCade viewers
127   myV3dViewer = CreateViewer(TCollection_ExtendedString("Viewer3d").ToExtString(), "", "", 1000.0,
128                              V3d_XposYnegZpos, Standard_True, Standard_True);
129   myV3dViewer->SetDefaultLights();
130
131   // init selector
132   myAISContext = new AIS_InteractiveContext(myV3dViewer);
133   myAISContext->SelectionColor(Quantity_NOC_WHITE);
134
135   // display isoline on planar faces (box for ex.)
136   myAISContext->IsoOnPlane(true);
137
138   if (DisplayTrihedron) {
139     Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(gp::XOY());
140     myTrihedron = new AIS_Trihedron(anAxis);
141     myTrihedron->SetInfiniteState( Standard_True);
142
143     Quantity_Color Col(193 / 255., 205 / 255., 193 / 255., Quantity_TOC_RGB);
144     myTrihedron->SetArrowColor(Col.Name());
145     myTrihedron->SetSize(myTrihedronSize);
146     Handle(AIS_Drawer) drawer = myTrihedron->Attributes();
147     if (drawer->HasDatumAspect()) {
148       Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect();
149       daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB));
150       daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB));
151       daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB));
152     }
153   }
154   // set zooming style to standard
155   //myZoomingStyle = 0;
156
157   QMdiArea* aMDI = myMainWindow->mdiArea();
158   connect(aMDI, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(onWindowActivated(QMdiSubWindow*)));
159
160 }
161
162 XGUI_Viewer::~XGUI_Viewer(void)
163 {
164   myAISContext.Nullify();
165   myV3dViewer.Nullify();
166 }
167
168 QMdiSubWindow* XGUI_Viewer::createView(V3d_TypeOfView theType)
169 {
170   // create view frame
171   XGUI_ViewWindow* view = new XGUI_ViewWindow(this, theType);
172   // get main view window (created by view frame)
173   //OCCViewer_ViewWindow* vw = view->getView(OCCViewer_ViewFrame::MAIN_VIEW);
174   // initialize main view window
175   //initView( vw );
176   // set default background for view window
177   //vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here)
178   // connect signal from viewport
179   //connect(view->viewPort(), SIGNAL(vpClosed()), this, SLOT(onViewClosed()));
180     //connect(view->viewPort(), SIGNAL(vpMapped()), this, SLOT(onViewMapped()));
181   if (myViews.size() == 0) 
182     setTrihedronShown(true);
183
184   view->setBackground(XGUI_ViewBackground(XGUI::VerticalGradient, Qt::white, QColor(Qt::blue).lighter()));
185   //view->setBackground(XGUI_ViewBackground(Qt::black));
186   view->updateEnabledDrawMode();
187
188   QMdiArea* aMDI = myMainWindow->mdiArea();
189   QMdiSubWindow* aWnd = aMDI->addSubWindow(view, Qt::FramelessWindowHint);
190   addView(aWnd);
191   aWnd->setGeometry(0, 0, aMDI->width() / 2, aMDI->height() / 2);
192   aWnd->show();
193   aWnd->setWindowTitle(QString("Viewer #%1").arg(++myWndIdCount));
194   emit viewCreated(view);
195   return aWnd;
196 }
197
198 XGUI_ViewWindow* XGUI_Viewer::activeViewWindow() const
199 {
200   if (myActiveView)
201     return dynamic_cast<XGUI_ViewWindow*>(myActiveView->widget());
202   return 0;
203 }
204
205 void XGUI_Viewer::getSelectedObjects(AIS_ListOfInteractive& theList)
206 {
207   theList.Clear();
208   for (myAISContext->InitSelected(); myAISContext->MoreSelected(); myAISContext->NextSelected())
209     theList.Append(myAISContext->SelectedInteractive());
210 }
211
212 void XGUI_Viewer::getSelectedShapes(NCollection_List<TopoDS_Shape>& theList)
213 {
214   Handle(AIS_InteractiveContext) ic = AISContext();
215
216   for (ic->InitSelected(); ic->MoreSelected(); ic->NextSelected()) {
217     TopoDS_Shape aShape = ic->SelectedShape();
218     if (!aShape.IsNull())
219       theList.Append(aShape);
220   }
221 }
222
223 void XGUI_Viewer::setObjectsSelected(const AIS_ListOfInteractive& theList)
224 {
225   AIS_ListIteratorOfListOfInteractive aIt;
226   for (aIt.Initialize(theList); aIt.More(); aIt.Next())
227     myAISContext->AddOrRemoveSelected(aIt.Value(), false);
228   myAISContext->UpdateCurrentViewer();
229 }
230
231 /*! Sets hot button
232  *\param theOper - hot operation
233  *\param theState - adding state to state map operations.
234  *\param theButton - adding state to button map operations.
235  */
236 void XGUI_Viewer::setHotButton(XGUI::InteractionStyle theInteractionStyle,
237                                XGUI::HotOperation theOper, Qt::KeyboardModifiers theState,
238                                Qt::MouseButtons theButton)
239 {
240   myStateMap[theInteractionStyle][theOper] = theState;
241   myButtonMap[theInteractionStyle][theOper] = theButton;
242 }
243
244 /*! Gets hot button for operation \a theOper.
245  *\param theOper - input hot operation
246  *\param theState - output state from state map operations.
247  *\param theButton - output state from button map operations.
248  */
249 void XGUI_Viewer::getHotButton(XGUI::InteractionStyle theInteractionStyle,
250                                XGUI::HotOperation theOper, Qt::KeyboardModifiers& theState,
251                                Qt::MouseButtons& theButton)
252 {
253   theState = myStateMap[theInteractionStyle][theOper];
254   theButton = myButtonMap[theInteractionStyle][theOper];
255 }
256
257 /*!
258  Changes visibility of trihedron to opposite
259  */
260 void XGUI_Viewer::toggleTrihedron()
261 {
262   setTrihedronShown(!isTrihedronVisible());
263 }
264
265 /*!
266  \return true if trihedron is visible
267  */
268 bool XGUI_Viewer::isTrihedronVisible() const
269 {
270   return !myTrihedron.IsNull() && !myAISContext.IsNull() && myAISContext->IsDisplayed(myTrihedron);
271 }
272
273 /*!
274  Sets visibility state of trihedron
275  \param on - new state
276  */
277
278 void XGUI_Viewer::setTrihedronShown(bool on)
279 {
280   if (myTrihedron.IsNull())
281     return;
282
283   if (on) {
284     myAISContext->Display(myTrihedron);
285     myAISContext->Deactivate(myTrihedron);
286   } else {
287     myAISContext->Erase(myTrihedron);
288   }
289 }
290
291 /*!
292  \return trihedron size
293  */
294 double XGUI_Viewer::trihedronSize() const
295 {
296   double sz = 0;
297   if (!myTrihedron.IsNull())
298     sz = myTrihedron->Size();
299   return sz;
300 }
301
302 /*!
303  Changes trihedron size
304  \param sz - new size
305  */
306 void XGUI_Viewer::setTrihedronSize(const double sz, bool isRelative)
307 {
308   if (myTrihedronSize != sz || isRelative != myIsRelative) {
309     myTrihedronSize = sz;
310     myIsRelative = isRelative;
311     updateTrihedron();
312   }
313 }
314
315 /*! 
316  * Update the size of the trihedron
317  */
318 void XGUI_Viewer::updateTrihedron()
319 {
320   if (myTrihedron.IsNull())
321     return;
322
323   if (myIsRelative) {
324     double newSz, oldSz;
325
326     if (computeTrihedronSize(newSz, oldSz))
327       myTrihedron->SetSize(newSz);
328
329   } else if (myTrihedron->Size() != myTrihedronSize) {
330     myTrihedron->SetSize(myTrihedronSize);
331   }
332 }
333
334 /*!
335  Get new and current trihedron size corresponding to the current model size
336  */
337 bool XGUI_Viewer::computeTrihedronSize(double& theNewSize, double& theSize)
338 {
339   theNewSize = 100;
340   theSize = 100;
341
342   //SRN: BUG IPAL8996, a usage of method ActiveView without an initialization
343   Handle(V3d_Viewer) viewer = v3dViewer();
344   viewer->InitActiveViews();
345   if (!viewer->MoreActiveViews())
346     return false;
347
348   Handle(V3d_View) view3d = viewer->ActiveView();
349   //SRN: END of fix
350
351   if (view3d.IsNull())
352     return false;
353
354   double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
355   double aMaxSide;
356
357   view3d->View()->MinMaxValues(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
358
359   if (Xmin == RealFirst() || Ymin == RealFirst() || Zmin == RealFirst() || Xmax == RealLast()
360       || Ymax == RealLast() || Zmax == RealLast())
361     return false;
362
363   aMaxSide = Xmax - Xmin;
364   if (aMaxSide < Ymax - Ymin)
365     aMaxSide = Ymax - Ymin;
366   if (aMaxSide < Zmax - Zmin)
367     aMaxSide = Zmax - Zmin;
368
369   // IPAL21687
370   // The boundary box of the view may be initialized but nullified
371   // (case of infinite objects)
372   if (aMaxSide < Precision::Confusion())
373     return false;
374
375   static float EPS = (float)5.0E-3;
376   theSize = trihedron()->Size();
377   //theNewSize = aMaxSide*aSizeInPercents / 100.0;
378
379   return fabs(theNewSize - theSize) > theSize * EPS || fabs(theNewSize - theSize) > theNewSize * EPS;
380 }
381
382 void XGUI_Viewer::onViewClosed(QMdiSubWindow* theView)
383 {
384   if ( !theView )
385     return;
386
387   emit deleteView( static_cast<XGUI_ViewWindow*>(theView->widget()) );
388   removeView( theView );
389
390   // if this is last view
391   if (myViews.size() == 0) {
392     Standard_Integer aViewsNb = 0;
393     for ( myV3dViewer->InitActiveViews(); myV3dViewer->MoreActiveViews(); myV3dViewer->NextActiveViews())
394       ++aViewsNb;
395     if ( aViewsNb < 2 ) {
396       //clean up presentations before last view is closed
397       myAISContext->RemoveAll(Standard_False);
398     }
399   }
400 }
401
402 /*!Remove view window \a theView from view manager.
403  *And close the last view, if it has \a theView.
404 */
405 void XGUI_Viewer::removeView( QMdiSubWindow* theView )
406 {
407     XGUI_ViewWindow* aWindow = static_cast<XGUI_ViewWindow*>(theView->widget());
408
409     aWindow->disconnect( this );
410     myViews.removeAt( myViews.indexOf( theView ) );
411     if ( myActiveView == theView )
412         myActiveView = 0;
413     if ( myViews.size() == 0 )
414         emit lastViewClosed();
415 }
416
417
418 /*void XGUI_Viewer::onViewMapped()
419 {
420   setTrihedronShown(true);
421 }*/
422
423
424 void XGUI_Viewer::addView(QMdiSubWindow* theView)
425 {
426     XGUI_ViewWindow* aWindow = dynamic_cast<XGUI_ViewWindow*>(theView->widget());
427
428     connect(aWindow, SIGNAL(closed(QMdiSubWindow*)),
429             this,    SLOT(onViewClosed(QMdiSubWindow*)));
430
431     connect(aWindow, SIGNAL(tryClosing(XGUI_ViewWindow*)),
432             this,    SIGNAL(tryCloseView(XGUI_ViewWindow*)));
433
434     connect(aWindow, SIGNAL(mousePressed(XGUI_ViewWindow*, QMouseEvent*)),
435             this,    SLOT(onMousePressed(XGUI_ViewWindow*, QMouseEvent*)));
436
437     connect(aWindow, SIGNAL(mouseDoubleClicked(XGUI_ViewWindow*, QMouseEvent*)),
438             this,    SIGNAL(mouseDoubleClick(XGUI_ViewWindow*, QMouseEvent*)));
439
440     connect(aWindow, SIGNAL(mouseMoving(XGUI_ViewWindow*, QMouseEvent*)),
441             this,    SIGNAL(mouseMove(XGUI_ViewWindow*, QMouseEvent*)));
442
443     connect(aWindow, SIGNAL(keyPressed(XGUI_ViewWindow*, QKeyEvent*)),
444             this,    SIGNAL(keyPress(XGUI_ViewWindow*, QKeyEvent*)));
445
446     connect(aWindow, SIGNAL(keyReleased(XGUI_ViewWindow*, QKeyEvent*)),
447             this,    SIGNAL(keyRelease(XGUI_ViewWindow*, QKeyEvent*)));
448
449     //connect(aWindow, SIGNAL(contextMenuRequested( QContextMenuEvent* )),
450     //        this,    SLOT  (onContextMenuRequested( QContextMenuEvent* )));
451     connect(aWindow, SIGNAL( contextMenuRequested(QContextMenuEvent*) ), 
452             this, SIGNAL( contextMenuRequested(QContextMenuEvent*) ) );
453
454     connect(aWindow, SIGNAL(mouseMoving(XGUI_ViewWindow*, QMouseEvent*)),
455             this, SLOT(onMouseMove(XGUI_ViewWindow*, QMouseEvent*)));
456
457     connect(aWindow, SIGNAL(mouseReleased(XGUI_ViewWindow*, QMouseEvent*)),
458             this, SLOT(onMouseReleased(XGUI_ViewWindow*, QMouseEvent*)));
459
460     myViews.append(theView);
461 }
462
463 /*!
464     Emit activated for view \a view.
465 */
466 void XGUI_Viewer::onWindowActivated(QMdiSubWindow* view)
467 {
468   if (view && (view != myActiveView) && (!view->isMinimized())) {
469     myActiveView = view;
470     ((XGUI_ViewWindow*)myActiveView->widget())->windowActivated();
471     QList<QMdiSubWindow*>::iterator aIt;
472     for (aIt = myViews.begin(); aIt != myViews.end(); ++aIt) {
473       if ((*aIt) != myActiveView) {
474         ((XGUI_ViewWindow*)(*aIt)->widget())->windowDeactivated();
475       }
476     }
477   }
478 }
479
480
481 void XGUI_Viewer::onWindowMinimized(QMdiSubWindow* theWnd)
482 {
483   if (myActiveView == theWnd) {
484     myActiveView = 0;
485     QList<QMdiSubWindow*>::iterator aIt;
486     for (aIt = myViews.begin(); aIt != myViews.end(); ++aIt) {
487       if (!(*aIt)->widget()->isMinimized()) {
488         (*aIt)->raise();
489         onWindowActivated(*aIt);
490         break;
491       }
492     }
493   }
494 }
495
496 /*!
497   SLOT: called on mouse button press, stores current mouse position as start point for transformations
498 */
499 void XGUI_Viewer::onMousePressed(XGUI_ViewWindow* theWindow, QMouseEvent* theEvent)
500 {
501   myStartPnt.setX(theEvent->x()); myStartPnt.setY(theEvent->y());
502   emit mousePress(theWindow, theEvent);
503 }
504
505 /*!
506   SLOT: called on mouse move, processes hilighting
507 */
508 void XGUI_Viewer::onMouseMove(XGUI_ViewWindow* theWindow, QMouseEvent* theEvent)
509 {
510   myCurPnt.setX(theEvent->x()); myCurPnt.setY(theEvent->y());
511   if (!mySelectionEnabled) return;
512
513   Handle(V3d_View) aView3d = theWindow->viewPort()->getView();
514   if ( !aView3d.IsNull() ) {
515     myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView3d);
516   }
517 }
518
519 /*!
520   SLOT: called on mouse button release, finishes selection
521 */
522 void XGUI_Viewer::onMouseReleased(XGUI_ViewWindow* theWindow, QMouseEvent* theEvent)
523 {
524   if (!mySelectionEnabled || theEvent->button() != Qt::LeftButton) {
525     emit mouseRelease(theWindow, theEvent);
526     return;
527   }
528
529   myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y());
530   bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
531   
532   //if (!aHasShift) 
533   //  emit deselection();
534
535   if (myStartPnt == myEndPnt) {
536     // the MoveTo is necessary for the second click in the same point. Otherwise the selection is lost.
537     Handle(V3d_View) aView3d = theWindow->viewPort()->getView();
538     if ( !aView3d.IsNull() ) {
539       myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView3d);
540     }
541     if (aHasShift && myMultiSelectionEnabled)
542       myAISContext->ShiftSelect();
543     else
544       myAISContext->Select();
545   } else {
546     if (aHasShift && myMultiSelectionEnabled)
547       myAISContext->ShiftSelect(myStartPnt.x(), myStartPnt.y(),
548                                 myEndPnt.x(), myEndPnt.y(),
549                                 theWindow->viewPort()->getView(), false );
550     else
551       myAISContext->Select(myStartPnt.x(), myStartPnt.y(),
552                            myEndPnt.x(), myEndPnt.y(),
553                            theWindow->viewPort()->getView(), false );
554
555     int Nb = myAISContext->NbSelected();
556     if( Nb>1 && !myMultiSelectionEnabled ) {
557       myAISContext->InitSelected();
558       Handle( SelectMgr_EntityOwner ) anOwner = myAISContext->SelectedOwner();
559       if( !anOwner.IsNull() ) {
560         myAISContext->ClearSelected( Standard_False );
561         myAISContext->AddOrRemoveSelected( anOwner, Standard_False );
562       }
563     }
564
565     myAISContext->UpdateCurrentViewer();
566   }
567   emit mouseRelease(theWindow, theEvent);
568   emit selectionChanged();
569 }
570
571 //******************************************************
572 void XGUI_Viewer::setMultiSelectionEnabled(bool toEnable) 
573
574   myMultiSelectionEnabled = toEnable; 
575   updateViewsDrawMode();
576 }
577
578 //******************************************************
579 void XGUI_Viewer::setSelectionEnabled(bool toEnable) 
580
581   mySelectionEnabled = toEnable; 
582   updateViewsDrawMode();
583 }
584
585 //******************************************************
586 void XGUI_Viewer::updateViewsDrawMode() const
587 {
588   foreach(QMdiSubWindow* aWnd, myViews){
589     XGUI_ViewWindow* aView = static_cast<XGUI_ViewWindow*>(aWnd->widget());
590     aView->updateEnabledDrawMode();
591   }
592 }
593
594 //******************************************************
595 //void XGUI_Viewer::onContextMenuRequested(QContextMenuEvent* theEvent)
596 //{
597 //  XGUI_ViewWindow* aWnd = dynamic_cast<XGUI_ViewWindow*>(sender());
598 //  if (!aWnd) return;
599 //
600 //  QMenu aMenu;
601 //
602 //  // Include Viewer actions
603 //  if (myActions.size() > 0) {
604 //    aMenu.addActions(myActions);
605 //    aMenu.addSeparator();
606 //  }
607 //  if (aWnd->actions().size() > 0) {
608 //    aMenu.addActions(aWnd->actions());
609 //    aMenu.addSeparator();
610 //  }
611 //
612 //  QMdiArea* aMDI = myMainWindow->mdiArea();
613 //  if (aMenu.actions().size() > 0) {
614 //    QMenu* aSubMenu = aMenu.addMenu(tr("Windows"));
615 //    aSubMenu->addActions(aMDI->actions());
616 //  } else {
617 //    aMenu.addActions(aMDI->actions());
618 //  }
619 //  aMenu.exec(theEvent->globalPos());
620 //}