Salome HOME
DCQ : Merge with Ecole_ete_a6.
[modules/kernel.git] / src / OCCViewer / OCCViewer_Viewer3d.cxx
1 //  SALOME OCCViewer : build OCC Viewer into Salome desktop
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : OCCViewer_Viewer3d.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SALOME
27 //  $Header$
28
29 using namespace std;
30 /*!
31   \class OCCViewer_Viewer3d OCCViewer_Viewer3d.h
32   \brief Open CASCADE Viewer 3D with viewport 3D and selection.
33 */
34
35 #include "OCCViewer_Viewer3d.h"
36 #include "QAD.h"
37 #include "QAD_Config.h"
38 #include "QAD_Desktop.h"
39 #include "QAD_Settings.h"
40 #include "QAD_LeftFrame.h"
41 #include "OCCViewer_ViewPort3d.h"
42 #include "QAD_RightFrame.h"
43 #include "QAD_MessageBox.h"
44 #include "QAD_Application.h"
45
46 #include "SALOME_Selection.h"
47 #include "SALOME_InteractiveObject.hxx"
48 #include "SALOME_ListIteratorOfListIO.hxx"
49
50 #include "SALOME_AISShape.hxx"
51 #include "SALOME_AISObject.hxx"
52
53 #include "utilities.h"
54
55 // Open CASCADE Includes
56 #include <Geom_Axis2Placement.hxx>
57 #include <AIS_ListOfInteractive.hxx>
58 #include <AIS_ListIteratorOfListOfInteractive.hxx>
59
60 /*!
61     Constructor
62 */
63 OCCViewer_Viewer3d::OCCViewer_Viewer3d(OCCViewer_ViewFrame* vf) :
64   myAISContext( NULL ),
65   myAISSelector( NULL )
66 {
67   if ( myV3dViewer.IsNull() )
68     createViewer3d();   /* create viewer */
69
70   QString BackgroundColorRed   = QAD_CONFIG->getSetting("OCCViewer:BackgroundColorRed");
71   QString BackgroundColorGreen = QAD_CONFIG->getSetting("OCCViewer:BackgroundColorGreen");
72   QString BackgroundColorBlue  = QAD_CONFIG->getSetting("OCCViewer:BackgroundColorBlue");
73
74   if( !BackgroundColorRed.isEmpty() && !BackgroundColorGreen.isEmpty() && !BackgroundColorBlue.isEmpty() )
75     myBackColor = QColor(BackgroundColorRed.toInt(),
76                          BackgroundColorGreen.toInt(),
77                          BackgroundColorBlue.toInt());
78   else
79     myBackColor = QColor(35, 136, 145);
80
81   myViewFrame = vf;
82   myViewFrame->setViewPort ( new OCCViewer_ViewPort3d( myViewFrame, myV3dViewer ) );
83   myViewFrame->setViewer(this);
84
85   /* properties settings */
86   //    if ( !myIcon.isNull() )
87   //      myStudyFrame->setIcon( myIcon );
88
89   myViewFrame->setCursor( myCursor );
90   myViewFrame->setBackgroundColor( myBackColor );
91
92   if ( myAISContext.IsNull() ) {
93     /* create interactive manager */
94     myAISContext = new AIS_InteractiveContext ( myV3dViewer, myV3dCollector );
95
96     myAISContext->IsoOnPlane(true) ;
97
98     /* create trihedron */
99     Handle(Geom_Axis2Placement) anAxis=new Geom_Axis2Placement(gp::XOY());
100     myTrihedron=new AIS_Trihedron(anAxis);
101     myTrihedron->SetInfiniteState( Standard_True );
102
103     Quantity_Color Col(193/255., 205/255., 193/255., Quantity_TOC_RGB);
104     myTrihedron->SetColor( Col );
105     myTrihedron->SetArrowColor( Col.Name() );
106
107     float dim = 100;
108     QString Size = QAD_CONFIG->getSetting("Viewer:TrihedronSize");
109     if (!Size. isEmpty() ) dim = Size.toFloat(); //get size from preferences
110    
111     myTrihedron->SetSize(dim);
112
113     myAISContext->Display(myTrihedron);
114     myAISContext->Deactivate(myTrihedron);
115
116     /* create selector */
117     myAISSelector = new OCCViewer_AISSelector ( myAISContext );
118     QAD_ASSERT ( connect (myAISSelector, SIGNAL(selSelectionDone(bool)),
119                           this, SLOT(onSelectionDone(bool))) );
120     QAD_ASSERT ( connect (myAISSelector, SIGNAL(selSelectionCancel(bool)),
121                           this, SLOT(onSelectionCancel(bool))) );
122     myEnableSelection = true;
123   }
124
125   QAD_ASSERT ( connect(myViewFrame,
126                        SIGNAL(vfKeyPress(QKeyEvent*)),
127                        this, SLOT(onKeyPress(QKeyEvent*))) );
128
129   /* mouse events of the view */
130   QAD_ASSERT ( QObject::connect(myViewFrame,
131                                 SIGNAL(vfMousePress(QMouseEvent*)),
132                                 this, SLOT(onMousePress(QMouseEvent*))) );
133   QAD_ASSERT ( QObject::connect(myViewFrame,
134                                 SIGNAL(vfMouseRelease(QMouseEvent*)),
135                                 this, SLOT(onMouseRelease (QMouseEvent*))) );
136   QAD_ASSERT ( QObject::connect(myViewFrame,
137                                 SIGNAL(vfMouseMove(QMouseEvent*)),
138                                 this, SLOT(onMouseMove (QMouseEvent*))) );
139   QAD_ASSERT ( QObject::connect(myViewFrame,
140                                 SIGNAL(vfMouseDoubleClick(QMouseEvent*)),
141                                 this, SLOT(onMouseDoubleClick (QMouseEvent*))) );
142
143   /* transformation events */
144   QAD_ASSERT ( QObject::connect(myViewFrame,
145                                 SIGNAL(vfTransformationStarted(OCCViewer_ViewPort::OperationType)),
146                                 this, SLOT(onTransformationStarted (OCCViewer_ViewPort::OperationType))) );
147   QAD_ASSERT ( QObject::connect(myViewFrame,
148                                 SIGNAL(vfTransformationFinished(OCCViewer_ViewPort::OperationType)),
149                                 this, SLOT(onTransformationFinished (OCCViewer_ViewPort::OperationType))) );
150
151   /* set popup manager for the viewport */
152   myViewFrame->getViewPort()->setPopupServer ( this );
153
154 }
155
156
157 /*!
158     Destructor
159 */
160 OCCViewer_Viewer3d::~OCCViewer_Viewer3d()
161 {
162   delete myAISSelector;
163 }
164
165
166 /* trihedron */
167 Handle(AIS_Trihedron) OCCViewer_Viewer3d::getTrihedron() const
168 {
169   return myTrihedron;
170 }
171
172 void OCCViewer_Viewer3d::setTrihedronSize(float size)
173 {
174   myTrihedron->SetSize(size);
175   myAISContext->UpdateCurrentViewer();
176 }
177
178 bool OCCViewer_Viewer3d::isTrihedronDisplayed()
179
180 {
181   return myAISContext->IsDisplayed(myTrihedron);
182 }
183
184 void OCCViewer_Viewer3d::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
185 {
186   AIS_ListOfInteractive List;
187   myAISContext->DisplayedObjects(List);
188   
189   AIS_ListIteratorOfListOfInteractive ite(List);
190   while (ite.More()) {
191     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
192       Handle(SALOME_AISShape) aSh =
193         Handle(SALOME_AISShape)::DownCast(ite.Value());
194       
195       if ( aSh->hasIO() ) {
196         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
197         if ( IO->isSame( IObject ) ) {
198           aSh->setName( strdup(newName.latin1()) );
199           break;
200         }
201       }
202     } else if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
203       Handle(SALOME_AISObject) aSh =
204         Handle(SALOME_AISObject)::DownCast(ite.Value());
205
206       // Add code here, if someone create a MODULE_AISObject.
207     }
208     ite.Next();
209   }
210 }
211
212 void OCCViewer_Viewer3d::SetColor(const Handle(SALOME_InteractiveObject)& IObject,
213                                   QColor thecolor)
214 {
215   AIS_ListOfInteractive List;
216   myAISContext->DisplayedObjects(List);
217   
218   AIS_ListIteratorOfListOfInteractive ite(List);
219   while (ite.More()) {
220     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
221       Handle(SALOME_AISShape) aSh =
222         Handle(SALOME_AISShape)::DownCast(ite.Value());
223       
224       if ( aSh->hasIO() ) {
225         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
226         if ( IO->isSame( IObject ) ) {
227           Quantity_Color CSFColor = Quantity_Color ( thecolor.red()/255., thecolor.green()/255., thecolor.blue()/255., Quantity_TOC_RGB );
228           aSh->SetColor ( CSFColor );
229           //      aSh->SetShadingColor ( CSFColor );
230           break;
231         }
232       }
233     } else if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
234       Handle(SALOME_AISObject) aSh =
235         Handle(SALOME_AISObject)::DownCast(ite.Value());
236       
237       // Add code here, if someone create a MODULE_AISObject.
238     }
239     ite.Next();
240   }
241   myV3dViewer->Update();
242 }
243
244 void OCCViewer_Viewer3d::SwitchRepresentation(const Handle(SALOME_InteractiveObject)& IObject,
245                                               int mode)
246 {  
247   AIS_ListOfInteractive List;
248   myAISContext->DisplayedObjects(List);
249   
250   AIS_ListIteratorOfListOfInteractive ite(List);
251   while (ite.More()) {
252     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
253       Handle(SALOME_AISShape) aSh =
254         Handle(SALOME_AISShape)::DownCast(ite.Value());
255       
256       if ( aSh->hasIO() ) {
257         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
258         if ( IO->isSame( IObject ) ) {
259           myAISContext->SetDisplayMode(aSh,Standard_Integer(mode),true);
260         }
261       }
262     } else if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
263       Handle(SALOME_AISObject) aSh =
264         Handle(SALOME_AISObject)::DownCast(ite.Value());
265       
266       // Add code here, if someone create a MODULE_AISObject.
267     }
268     ite.Next();
269   }
270   myV3dViewer->Update();
271 }
272
273 void OCCViewer_Viewer3d::SetTransparency(const Handle(SALOME_InteractiveObject)& IObject,
274                                          float transp)
275 {
276   AIS_ListOfInteractive List;
277   myAISContext->DisplayedObjects(List);
278   
279   AIS_ListIteratorOfListOfInteractive ite(List);
280   while (ite.More()) {
281     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
282       Handle(SALOME_AISShape) aSh =
283         Handle(SALOME_AISShape)::DownCast(ite.Value());
284       
285       if ( aSh->hasIO() ) {
286         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
287         if ( IO->isSame( IObject ) ) {
288           myAISContext->SetTransparency( aSh, transp, false );
289           myAISContext->Redisplay( aSh, Standard_False, Standard_True );
290         }
291       }
292     } else if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
293       Handle(SALOME_AISObject) aSh =
294         Handle(SALOME_AISObject)::DownCast(ite.Value());
295       
296       // Add code here, if someone create a MODULE_AISObject.
297     }
298     ite.Next();
299   }
300   myV3dViewer->Update();  
301 }
302
303 /*!
304     Highlights 'obj' in viewer, returns 'true' when selected successfully
305 */
306 bool OCCViewer_Viewer3d::highlight( const Handle(SALOME_InteractiveObject)& IObject, bool highlight, bool update )
307 {
308   AIS_ListOfInteractive List;
309   myAISContext->DisplayedObjects(List);
310   
311   AIS_ListIteratorOfListOfInteractive ite(List);
312   while (ite.More()) {
313     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
314       Handle(SALOME_AISShape) aSh =
315         Handle(SALOME_AISShape)::DownCast(ite.Value());
316       
317       if ( aSh->hasIO() ) {
318         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
319         if ( IO->isSame( IObject ) ) {
320           if ( highlight ) {
321             if ( !myAISContext->IsSelected(aSh) ) 
322               myAISContext->AddOrRemoveCurrentObject(aSh, false);
323           } else {
324             if ( myAISContext->IsSelected(aSh) ) 
325               myAISContext->AddOrRemoveCurrentObject(aSh, false);       
326           }      
327           break;
328         }
329       }
330     } else if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
331       Handle(SALOME_AISObject) aSh =
332         Handle(SALOME_AISObject)::DownCast(ite.Value());
333       
334       // Add code here, if someone create a MODULE_AISObject.
335     }
336     ite.Next();
337   }
338   if (update)
339     myV3dViewer->Update();
340   return false;
341 }
342
343 /*!
344     Unhighlight all selected objects
345 */
346 bool OCCViewer_Viewer3d::unHighlightAll()
347 {
348   myAISContext->ClearCurrents();
349   return false;
350 }
351
352 /*!
353   Returns true if the IObject has a Graphical Object in this viewer. Returns FALSE otherwise.
354 */
355 bool OCCViewer_Viewer3d::isInViewer( const Handle(SALOME_InteractiveObject)& IObject, bool onlyInViewer)
356 {
357   AIS_ListOfInteractive List;
358   myAISContext->DisplayedObjects(List);
359
360   if ( onlyInViewer ) {
361     AIS_ListOfInteractive List1;
362     myAISContext->ObjectsInCollector(List1);
363     List.Append(List1);
364   }
365
366   AIS_ListIteratorOfListOfInteractive ite(List);
367   while (ite.More()) {
368     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
369       Handle(SALOME_AISShape) aSh =
370         Handle(SALOME_AISShape)::DownCast(ite.Value());
371       
372       if ( aSh->hasIO() ) {
373         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
374         if ( IObject->isSame( IO ) ) {
375           return true;
376         }
377       }
378     } else if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
379       Handle(SALOME_AISObject) aSh =
380         Handle(SALOME_AISObject)::DownCast(ite.Value());
381
382       // Add code here, if someone create a MODULE_AISObject.
383     }
384     ite.Next();
385   }
386   return false;
387 }
388
389 bool OCCViewer_Viewer3d::isVisible( const Handle(SALOME_InteractiveObject)& IObject )
390 {
391   AIS_ListOfInteractive List;
392   myAISContext->DisplayedObjects(List);
393
394   AIS_ListIteratorOfListOfInteractive ite(List);
395   while (ite.More()) {
396     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
397       Handle(SALOME_AISShape) aSh =
398         Handle(SALOME_AISShape)::DownCast(ite.Value());
399       
400       if ( aSh->hasIO() ) {
401         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
402         if ( IObject->isSame( IO ) ) {
403           return myAISContext->IsDisplayed(aSh);
404         }
405       }
406     } else if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
407       Handle(SALOME_AISObject) aSh =
408         Handle(SALOME_AISObject)::DownCast(ite.Value());
409
410       // Add code here, if someone create a MODULE_AISObject.
411     }
412     ite.Next();
413   }
414   return false;
415 }
416
417 /*!
418     Returns the interactive context
419 */
420 Handle (AIS_InteractiveContext) OCCViewer_Viewer3d::getAISContext() const
421 {
422   return myAISContext;
423 }
424
425 OCCViewer_AISSelector* OCCViewer_Viewer3d::getAISSelector() const
426 {
427   return myAISSelector;
428 }
429
430 /*!
431     Returns 'true' if selection is enabled in this viewer,
432     'false' otherwise.
433 */
434 bool OCCViewer_Viewer3d::enabledSelection() const
435 {
436   return myEnableSelection;
437 }
438
439 /*!
440     Enables/disables selection in the viewer
441 */
442 void OCCViewer_Viewer3d::enableSelection( bool enable )
443 {
444   myEnableSelection = enable;
445   myAISSelector->enableSelection( enable );
446
447   /* send notification */
448   emit vw3dSelectionEnabled( enable );
449 }
450
451 /*!
452     Enables/disables ordinary and multiple selection
453     ( by 'Shift' key or with a rectangle ) in this viewer.
454 */
455 void OCCViewer_Viewer3d::enableMultipleSelection( bool enable )
456 {
457   /*  Enable/disable rectangle skectching which
458       is used for multiple selection */
459   myAISSelector->enableMultipleSelection( enable );
460
461   myViewFrame->getViewPort()->enableDrawMode( enable );
462
463   /* Enable non-multiple selection as well */
464   if ( !myEnableSelection && enable )
465     enableSelection( enable );
466 }
467
468 /*!
469     Key handler
470 */
471 void OCCViewer_Viewer3d::onKeyPress( QKeyEvent* pe )
472 {
473   if (!QAD_Application::getDesktop()->getActiveComponent().isEmpty()) {
474     QAD_Application::getDesktop()->onKeyPress( pe );
475   }
476 }
477
478 /*!
479     Mouse handler
480 */
481 void OCCViewer_Viewer3d::onMousePress( QMouseEvent* pe )
482 {
483   if ( pe->button() == Qt::LeftButton ) {
484     if ( !QAD_Application::getDesktop()->onMousePress( pe ) ) {
485
486       QAD_ASSERT_DEBUG_ONLY ( myAISSelector );
487       if ( pe->state() & Qt::ShiftButton )
488         myAISSelector->shiftSelect();  /* append selection */
489       else
490         myAISSelector->select();       /* new selection */
491     }
492   }
493 }
494
495 /*!
496     Mouse handler
497 */
498 void OCCViewer_Viewer3d::onMouseMove( QMouseEvent* pe )
499 {
500   /* activate hilighting only if no MB pressed */
501   if ( pe->state() == Qt::NoButton ) 
502     {
503       QAD_Application::getDesktop()->onMouseMove( pe );
504       
505       OCCViewer_ViewPort* vp = myViewFrame->getViewPort();
506       myAISSelector->moveTo ( pe->x(), pe->y(), ((OCCViewer_ViewPort3d*)vp)->getView() );
507     }
508 }
509
510 /*!
511     Mouse handler
512 */
513 void OCCViewer_Viewer3d::onMouseRelease( QMouseEvent* pe )
514 {
515   /* Selection with a rectangle ( multiple ) */
516   OCCViewer_ViewPort* vp = myViewFrame->getViewPort();
517   QAD_ASSERT_DEBUG_ONLY ( vp );
518   QRect selRect = vp->getSelectionRect ();
519   if ( selRect.isValid() ) {
520     QAD_ASSERT_DEBUG_ONLY ( myAISSelector );
521     QAD_ASSERT_DEBUG_ONLY ( vp->inherits("OCCViewer_ViewPort3d") );
522     if ( pe->state() & Qt::ShiftButton )
523       myAISSelector->shiftSelect ( selRect.left(), selRect.top(),
524                                    selRect.right(), selRect.bottom(),
525                                    ((OCCViewer_ViewPort3d*)vp)->getView() );
526     else
527       myAISSelector->select ( selRect.left(), selRect.top(),
528                               selRect.right(), selRect.bottom(),
529                               ((OCCViewer_ViewPort3d*)vp)->getView() );
530   }
531 }
532
533 /*!
534     Mouse handler
535 */
536 void OCCViewer_Viewer3d::onMouseDoubleClick( QMouseEvent* pe )
537 {
538 }
539
540 /*!
541     Called when a transformation in viewport is started
542 */
543 void OCCViewer_Viewer3d::onTransformationStarted( OCCViewer_ViewPort::OperationType type )
544 {
545   QAD_ASSERT_DEBUG_ONLY ( myAISSelector );
546   if ( myEnableSelection )
547     myAISSelector->enableSelection ( false );   // lock until the end of transform
548
549   if ( type == OCCViewer_ViewPort::PANGLOBAL ||
550        type == OCCViewer_ViewPort::WINDOWFIT )
551     {
552       /*  Start watching 'global panning' and 'window fit'.
553           These operations require additional user's actions
554           in viewport and we have to reset the operations if
555           instead of these actions a user does something else.
556       */
557       qApp->installEventFilter( this );
558     }
559 }
560
561 /*!
562     Called when a transformation in viewport is finished
563 */
564 void OCCViewer_Viewer3d::onTransformationFinished( OCCViewer_ViewPort::OperationType type )
565 {
566   QAD_ASSERT_DEBUG_ONLY ( myAISSelector );
567   if ( myEnableSelection )
568     myAISSelector->enableSelection ( true );    // unlock
569
570   if ( type == OCCViewer_ViewPort::PANGLOBAL ||
571        type == OCCViewer_ViewPort::WINDOWFIT )
572     {
573       /* stop watching 'global panning' and 'window fit'*/
574       qApp->removeEventFilter( this );
575     }
576 }
577
578 /*!
579     Called when an object is selected
580 */
581 void OCCViewer_Viewer3d::onSelectionDone( bool bAdded )
582 {
583   emit vw3dSelectionDone( bAdded );
584
585   QAD_Study*      myActiveStudy  = QAD_Application::getDesktop()->getActiveStudy();
586   QAD_StudyFrame* myActiveSFrame = myActiveStudy->getActiveStudyFrame();
587   SALOME_Selection*         Sel  = SALOME_Selection::Selection( myActiveStudy->getSelection() );
588   MESSAGE ( "OCCViewer_Viewer3d - NB SELECTED INTERACTIVE OBJECT : " << Sel->IObjectCount() )
589
590     QString             ActiveComp = QAD_Application::getDesktop()->getActiveComponent();
591
592   if ( ActiveComp.isEmpty() ) {
593     unHighlightAll();
594     return;
595   }
596
597   SALOME_ListIO DeltaPos;
598   DeltaPos.Clear();
599   SALOME_ListIO DeltaNeg;
600   DeltaNeg.Clear();
601
602   if ( !bAdded ) { /* select */
603     myAISContext->InitCurrent();
604     while (myAISContext->MoreCurrent()) {
605       if (myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
606         Handle(SALOME_AISShape) aSh =
607           Handle(SALOME_AISShape)::DownCast(myAISContext->Current());
608         
609         if ( aSh->hasIO() ) {
610           Handle( SALOME_InteractiveObject) IO = aSh->getIO();
611         
612           bool itemAllreadySelected = false;
613           int nbSel = Sel->IObjectCount();
614           if ( nbSel == 0 ) {
615             DeltaPos.Append( IO );
616           } else {
617             SALOME_ListIteratorOfListIO It( Sel->StoredIObjects() );
618             for(;It.More();It.Next()) {
619               Handle( SALOME_InteractiveObject) IO1 = It.Value();
620               if ( IO->isSame( IO1 ) ) {
621                 itemAllreadySelected = true;
622                 break;
623               }
624             }
625             if (!itemAllreadySelected) 
626               DeltaPos.Append( IO );
627           }
628         }
629       } else if (myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
630         Handle(SALOME_AISObject) aSh =
631           Handle(SALOME_AISObject)::DownCast(myAISContext->Current());
632         
633         // Add code here, if someone create a MODULE_AISObject.
634       }
635       myAISContext->NextCurrent();
636     }
637
638     if ( DeltaPos.Extent() > 0 )
639       Sel->ClearIObjects();
640     
641   } else { /* shift select */
642     SALOME_ListIteratorOfListIO It( Sel->StoredIObjects() );
643     for(;It.More();It.Next()) {
644       Handle( SALOME_InteractiveObject) IO1 = It.Value();
645
646       bool itemAllreadySelected = false;
647       myAISContext->InitCurrent();
648       while (myAISContext->MoreCurrent()) {
649         if (myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
650           Handle(SALOME_AISShape) aSh =
651             Handle(SALOME_AISShape)::DownCast(myAISContext->Current());
652           if ( aSh->hasIO() ) {
653             Handle( SALOME_InteractiveObject) IO = aSh->getIO();
654         
655             if ( IO->isSame( IO1 ) ) {
656               itemAllreadySelected = true;
657               break;
658             }
659           }
660         } else if (myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
661           Handle(SALOME_AISObject) aSh =
662             Handle(SALOME_AISObject)::DownCast(myAISContext->Current());
663           
664           // Add code here, if someone create a MODULE_AISObject.
665         }
666         myAISContext->NextCurrent();
667       }
668
669       if (!itemAllreadySelected)
670         DeltaNeg.Append( IO1 );
671     }
672
673     myAISContext->InitCurrent();
674     while (myAISContext->MoreCurrent()) {
675       if (myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
676         Handle(SALOME_AISShape) aSh =
677           Handle(SALOME_AISShape)::DownCast(myAISContext->Current());
678         if ( aSh->hasIO() ) {
679           Handle( SALOME_InteractiveObject) IO = aSh->getIO();  
680         
681           bool itemAllreadySelected = false;
682           SALOME_ListIteratorOfListIO It( Sel->StoredIObjects() );
683           for(;It.More();It.Next()) {
684             Handle( SALOME_InteractiveObject) IO1 = It.Value();
685             
686             if ( IO->isSame( IO1 ) ) {
687               itemAllreadySelected = true;
688               break;
689             }
690           }
691         
692           if (!itemAllreadySelected )
693             DeltaPos.Append( IO );
694         }
695       } else if ( myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
696         Handle(SALOME_AISObject) aSh =
697           Handle(SALOME_AISObject)::DownCast(myAISContext->Current());
698
699         // Add code here, if someone create a MODULE_AISObject.
700       }
701       myAISContext->NextCurrent();
702     }
703   }
704   
705   //  MESSAGE ( "VIEWER onSelectionDone DeltaNeg.count() == " << DeltaNeg.count() )
706   SALOME_ListIteratorOfListIO ItNeg( DeltaNeg );
707   for(;ItNeg.More();ItNeg.Next()) {
708     Sel->RemoveIObject( ItNeg.Value(), false );
709   }
710   
711   //  MESSAGE ( "VIEWER onSelectionDone DeltaPos.count() == " << DeltaPos.Extent() )
712   SALOME_ListIteratorOfListIO ItPos( DeltaPos );
713   for(;ItPos.More();ItPos.Next()) {
714     Sel->AddIObject( ItPos.Value(), false );
715   }  
716   myV3dViewer->Update();
717 }
718
719 /*!
720     Called when an object is unselected
721 */
722 void OCCViewer_Viewer3d::onSelectionCancel( bool bAdded )
723 {
724   emit vw3dSelectionCancel();
725
726   QAD_Study*      myActiveStudy  = QAD_Application::getDesktop()->getActiveStudy();
727   QAD_StudyFrame* myActiveSFrame = myActiveStudy->getActiveStudyFrame();
728   SALOME_Selection*         Sel  = SALOME_Selection::Selection( myActiveStudy->getSelection() );
729
730   //  MESSAGE ( "OCCViewer_Viewer3d - NB SELECTED INTERACTIVE OBJECT : " << Sel->IObjectCount() )
731
732   SALOME_ListIO DeltaPos;
733   DeltaPos.Clear();
734   SALOME_ListIO DeltaNeg;
735   DeltaNeg.Clear();
736   if (!bAdded) { /* select */
737     Sel->ClearIObjects();
738   } else { /* shiftselect */
739     SALOME_ListIteratorOfListIO It( Sel->StoredIObjects() );
740     for(;It.More();It.Next()) {
741       Handle( SALOME_InteractiveObject) IO1 = It.Value();
742
743       bool itemAllreadySelected = false;
744       myAISContext->InitCurrent();
745       while (myAISContext->MoreCurrent()) {
746         if (myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
747           Handle(SALOME_AISShape) aSh =
748             Handle(SALOME_AISShape)::DownCast(myAISContext->Current());
749           if ( aSh->hasIO() ) {
750             Handle( SALOME_InteractiveObject) IO = aSh->getIO();        
751             if ( IO->isSame(IO1) ) {
752               itemAllreadySelected = true;
753               break;
754             }
755           }
756         } else if (myAISContext->Current()->IsKind(STANDARD_TYPE(SALOME_AISObject))) {
757           Handle(SALOME_AISObject) aSh =
758             Handle(SALOME_AISObject)::DownCast(myAISContext->Current());
759           
760           // Add code here, if someone create a MODULE_AISObject.
761         }
762         myAISContext->NextCurrent();
763       }
764       
765       // only if isknown
766       if (!itemAllreadySelected)
767         DeltaNeg.Append( IO1 );
768     }
769   }
770
771   //  MESSAGE ( "VIEWER onSelectionCancel DeltaNeg.count() == " << DeltaNeg.Extent() )
772   SALOME_ListIteratorOfListIO ItNeg( DeltaNeg );
773   for(;ItNeg.More();ItNeg.Next()) {
774     Sel->RemoveIObject( ItNeg.Value(), false);
775   }
776   myV3dViewer->Update();
777 }
778
779 /*!
780     Installed while 'fit area' and 'global panning'
781     operations are active
782 */
783 bool OCCViewer_Viewer3d::eventFilter( QObject * po, QEvent * pe)
784 {
785   if ( ( pe->type() == QEvent::MouseButtonPress &&
786          po != myViewFrame->getViewPort() ) ||
787        pe->type() == QEvent::KeyPress ) {
788     /* user press any key or a MB outside the viewport */
789     myViewFrame->getViewPort()->resetState();
790   }
791   return QObject::eventFilter( po, pe );
792 }
793
794 /*!
795   Creates CasCade viewer 3D
796 */
797 void OCCViewer_Viewer3d::createViewer3d()
798 {
799   myV3dViewer = OCCViewer_VService::Viewer ( "", (short*) "Viewer3d", "", 1000.,
800                                              V3d_XposYnegZpos, true, true);
801   myV3dViewer->Init();
802
803   myV3dCollector = OCCViewer_VService::Viewer ( "", (short*) "Collector3d", "", 1000.,
804                                                 V3d_XposYnegZpos, true, true);
805   myV3dCollector->Init();
806 }
807
808 /*!
809   Returns CasCade viewer 3D
810 */
811 Handle(V3d_Viewer) OCCViewer_Viewer3d::getViewer3d() const
812 {
813   return myV3dViewer;
814 }
815
816 /*!
817     Sets a new cursor on all its studyframes
818 */
819 void OCCViewer_Viewer3d::setCursor( const QCursor& cursor)
820 {
821   myCursor = cursor;
822 }
823
824 /*!
825     Returns the current cursor
826 */
827 inline const QCursor& OCCViewer_Viewer3d::cursor() const
828 {
829   return myCursor;
830 }
831
832 /*!
833     Sets default background color on all its studyframes
834 */
835 void OCCViewer_Viewer3d::setBackgroundColor( const QColor& aColor )
836 {
837   myBackColor = aColor;
838 }
839
840 /*!
841     Returns the current background
842 */
843 inline const QColor& OCCViewer_Viewer3d::backgroundColor() const
844 {
845   return myBackColor;
846 }
847
848 /*!
849     Sets a new icon to all its studyframes
850 */
851 void OCCViewer_Viewer3d::setIcon( const QPixmap& icon )
852 {
853   myIcon = icon;
854 }
855
856 /*!
857   Returns current icon
858 */
859 inline const QPixmap& OCCViewer_Viewer3d::icon() const
860 {
861   return myIcon;
862 }
863
864 /*!
865     Builds popup menu
866 */
867 void OCCViewer_Viewer3d::onCreatePopup()
868 {
869 }
870