Salome HOME
6c09a2a47f40d9d31ef959689e602173d296f83d
[modules/gui.git] / src / GLViewer / GLViewer_ViewPort2d.cxx
1 // File:      GLViewer_ViewPort2d.cxx
2 // Created:   November, 2004
3 // Author:    OCC team
4 // Copyright (C) CEA 2004
5
6 /* GLViewer_ViewPort2d Source File */
7
8 #include "GLViewer_ViewPort2d.h"
9 #include "GLViewer_Viewer2d.h"
10 #include "GLViewer_ViewFrame.h"
11 #include "GLViewer_Context.h"
12 #include "GLViewer_Object.h"
13 #include "QtxToolTip.h"
14
15 //#include "QAD_Desktop.h"
16
17 #include <Precision.hxx>
18
19 #include <cmath>
20 using namespace std;
21 //#include <math.h>
22 //#include <stdlib.h>
23 //#include <iostream.h>
24
25 #include <qevent.h>
26 #include <qrect.h>
27 #include <qlayout.h>
28 #include <qpopupmenu.h>
29 #include <qimage.h>
30 #include <qtooltip.h>
31 #include <qapplication.h>
32 #include <qclipboard.h>
33 #include <qpainter.h>
34 #include <qbitmap.h>
35
36 /***************************************************************************
37 **  Class:   GLViewer_RectangularGrid
38 **  Descr:   OpenGL Grid for GLViewer_ViewPort2d
39 **  Module:  GLViewer
40 **  Created: UI team, 16.09.02
41 ****************************************************************************/
42
43 #define SEGMENTS   20
44 #define STEP       2*PI/SEGMENTS
45 #define XSIZE      100
46 #define YSIZE      100
47 #define MIN_SIZE   1
48
49 GLViewer_RectangularGrid::GLViewer_RectangularGrid() :
50        myGridList( -1 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
51        myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
52        myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
53        myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLint)5.0 ), 
54        myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
55 {
56   myGridColor[0] = 0.5;
57   myGridColor[1] = 0.5;
58   myGridColor[2] = 0.5;
59   myAxisColor[0] = 0.75;
60   myAxisColor[1] = 0.75;
61   myAxisColor[2] = 0.75;
62 }
63
64 GLViewer_RectangularGrid::GLViewer_RectangularGrid( GLfloat width, GLfloat height,
65                           GLfloat winW, GLfloat winH,
66                           GLfloat xSize, GLfloat ySize,
67                           GLfloat xPan, GLfloat yPan,
68                           GLfloat xScale, GLfloat yScale ) :
69        myGridList( -1 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
70        myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
71        myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
72        myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLint)5.0 ), 
73        myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
74 {
75   myGridColor[0] = 0.5;
76   myGridColor[1] = 0.5;
77   myGridColor[2] = 0.5;
78   myAxisColor[0] = 0.75;
79   myAxisColor[1] = 0.75;
80   myAxisColor[2] = 0.75;
81 }
82
83 GLViewer_RectangularGrid::~GLViewer_RectangularGrid()
84 {
85 }
86
87 void GLViewer_RectangularGrid::draw()
88 {
89   if ( myGridList == -1 || myIsUpdate )
90     initList();
91
92   glCallList( myGridList );
93 }
94
95 void GLViewer_RectangularGrid::setGridColor( GLfloat r, GLfloat g, GLfloat b )
96 {
97   if( myGridColor[0] == r && myGridColor[1] == g && myGridColor[2] == b )
98     return;
99
100   myGridColor[0] = r;
101   myGridColor[1] = g;
102   myGridColor[2] = b;
103   myIsUpdate = GL_TRUE;
104 }
105
106 void GLViewer_RectangularGrid::setAxisColor( GLfloat r, GLfloat g, GLfloat b )
107 {
108   if( myAxisColor[0] == r && myAxisColor[1] == g && myAxisColor[2] == b )
109     return;
110
111   myAxisColor[0] = r;
112   myAxisColor[1] = g;
113   myAxisColor[2] = b;
114   myIsUpdate = GL_TRUE;
115 }
116
117 void GLViewer_RectangularGrid::setGridWidth( float w )
118 {
119   if( myGridWidth == w )
120     return;
121
122   myGridWidth = w;
123   myIsUpdate = GL_TRUE;
124 }
125
126 void GLViewer_RectangularGrid::setCenterRadius( int r )
127 {
128   if( myCenterRadius == r )
129     return;
130
131   myCenterRadius = r;
132   myIsUpdate = GL_TRUE;
133 }
134
135 void GLViewer_RectangularGrid::setSize( float xSize, float ySize )
136 {
137   if( myXSize == xSize && myYSize == ySize )
138     return;
139   
140   myXSize = xSize;
141   myYSize = ySize;
142   myIsUpdate = GL_TRUE;
143 }
144
145 void GLViewer_RectangularGrid::setPan( float xPan, float yPan )
146 {
147   if( myXPan == xPan && myYPan == yPan )
148     return;
149  
150   myXPan = xPan;
151   myYPan = yPan;
152   myIsUpdate = GL_TRUE; 
153 }
154
155 bool GLViewer_RectangularGrid::setZoom( float zoom )
156 {
157   if( zoom == 1.0 )
158     return true;
159   
160   //backup values
161   float bXScale = myXScale;
162   float bYScale = myYScale;
163
164   myXScale /= zoom; 
165   myYScale /= zoom;
166
167   if( fabs(myXScale) < Precision::Confusion() || fabs(myYScale) < Precision::Confusion() )
168   { //undo
169     myXScale = bXScale;
170     myYScale = bYScale;
171     return false;
172   }
173   
174   myGridWidth /= zoom; 
175   myGridHeight /= zoom;  
176   myIsUpdate = GL_TRUE;
177   return true;
178 }
179
180 void GLViewer_RectangularGrid::setResize( float WinW, float WinH, float zoom )
181 {
182   if( myWinW == WinW && myWinH == WinH && zoom == 1.0 )
183     return;
184
185   myGridWidth = myGridWidth + ( WinW - myWinW ) * myXScale; 
186   myGridHeight = myGridHeight + ( WinH - myWinH ) * myYScale;
187   myWinW = WinW;
188   myWinH = WinH;
189   setZoom( zoom );
190   myIsUpdate = GL_TRUE;
191 }
192
193 void GLViewer_RectangularGrid::getSize( float& xSize, float& ySize ) const
194 {
195   xSize = myXSize;
196   ySize = myYSize;
197 }
198
199 void GLViewer_RectangularGrid::getPan( float& xPan, float& yPan ) const
200 {
201   xPan = myXPan;
202   yPan = myYPan;
203 }
204
205 void GLViewer_RectangularGrid::getScale( float& xScale, float& yScale ) const
206 {
207   xScale = myXScale;
208   yScale = myYScale;
209 }
210
211 bool GLViewer_RectangularGrid::initList()
212 {
213   myIsUpdate = GL_FALSE;
214   int n, m; 
215   float xLoc, yLoc; 
216   int xLoc1, yLoc1; 
217    
218     if( myXSize == (GLfloat)0.0 )
219         myXSize = (GLfloat)0.1;
220     if( myYSize == (GLfloat)0.0 )
221         myYSize = (GLfloat)0.1;
222
223 label:
224   if( ( myXSize >= myGridWidth/5 ) && ( myYSize >= myGridHeight/5 ) )
225   { //zoom in
226     myXSize /= myScaleFactor;
227     myYSize /= myScaleFactor;
228     goto label;
229   }
230   else if( ( myXSize * myScaleFactor < myGridWidth/5 ) 
231         || ( myYSize * myScaleFactor < myGridHeight/5 ) )
232   { //zoom out
233     myXSize *= myScaleFactor;
234     myYSize *= myScaleFactor;
235     goto label;
236   }
237
238   n = ( int )( myGridWidth / myXSize );
239   m = ( int )( myGridHeight / myYSize );
240         
241   if( ( n != 0 ) || ( m != 0 ) ) 
242   { 
243     if ( myGridList != -1 )  
244     { 
245       glDeleteLists( myGridList, 1 ); 
246       if ( glGetError() != GL_NO_ERROR ) 
247     return FALSE;
248     } 
249          
250     xLoc1 = ( int )( myXPan / myXSize ); 
251     yLoc1 = ( int )( myYPan / myYSize ); 
252
253     xLoc = xLoc1 * myXSize; 
254     yLoc = yLoc1 * myYSize; 
255  
256     myGridList = glGenLists( 1 ); 
257     glNewList( myGridList, GL_COMPILE ); 
258
259     glColor3f( myGridColor[0], myGridColor[1], myGridColor[2] );  
260     glLineWidth( myLineWidth ); 
261     
262     glBegin( GL_LINES ); 
263     for( int j = 0; ( j-1 ) * myXSize <= myGridWidth / 2 ; j++ )
264     { 
265       glVertex2d( -myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
266       glVertex2d( -myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc ); 
267       glVertex2d(  myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
268       glVertex2d(  myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc );
269     }
270     for( int i = 0; ( i-1 ) * myYSize <= myGridHeight / 2 ; i++)  
271     {
272       glVertex2d( -myGridWidth / 2 - myXSize - xLoc, -myYSize * i - yLoc ); 
273       glVertex2d(  myGridWidth / 2 + myXSize - xLoc, -myYSize * i - yLoc ); 
274       glVertex2d( -myGridWidth / 2 - myXSize - xLoc,  myYSize * i - yLoc ); 
275       glVertex2d(  myGridWidth / 2 + myXSize - xLoc,  myYSize * i - yLoc ); 
276     } 
277     glEnd();
278
279     glColor3f( myAxisColor[0], myAxisColor[1], myAxisColor[2] );
280     glLineWidth( myCenterWidth );
281
282     glBegin( GL_LINES );
283     glVertex2d(  myGridWidth / 2 + myXSize - xLoc, 0); 
284     glVertex2d( -myGridWidth / 2 - myXSize - xLoc, 0); 
285     glVertex2d( 0,  myGridHeight / 2 + myYSize - yLoc );
286     glVertex2d( 0, -myGridHeight / 2 - myYSize - yLoc );    
287     glEnd();
288
289     glBegin( GL_LINE_LOOP ); 
290     double angle = 0.0;
291     for ( int k = 0; k < SEGMENTS; k++ )     
292     { 
293       glVertex2f( cos(angle) * myCenterRadius * myXScale,
294           sin(angle) * myCenterRadius * myYScale ); 
295       angle += STEP; 
296     } 
297     glEnd();
298
299     glEndList();
300   }
301   return TRUE;
302 }
303 /***************************************************************************
304 **  Class:   GLViewer_Compass
305 **  Descr:   OpenGL Compass for ViewPort 2D
306 **  Module:  GLViewer
307 **  Created: UI team, 29.03.04
308 ****************************************************************************/
309 GLViewer_Compass::GLViewer_Compass ( const QColor& color, const int size, const Position pos,
310                                const int WidthTop, const int WidthBottom, const int HeightTop,
311                                const int HeightBottom ){
312     myCol = color;
313     mySize = size;
314     myPos = pos;
315     myArrowWidthTop = WidthTop;
316     myArrowWidthBottom = WidthBottom;
317     myArrowHeightTop = HeightTop;
318     myArrowHeightBottom = HeightBottom;
319     myIsVisible = true;
320     QFont* aFont = new QFont("Times",16);
321     myFont = new GLViewer_TexFont( aFont );
322     isGenereted = false;
323     //myFont->generateTexture();
324 }
325
326 GLViewer_TexFont* GLViewer_Compass::getFont()
327
328     if(!isGenereted) 
329     {
330         myFont->generateTexture();
331         isGenereted = true;
332     }    
333     return myFont;
334 }
335
336
337 /***************************************************************************
338 **  Class:   GLViewer_ViewPort2d
339 **  Descr:   OpenGL ViewPort 2D
340 **  Module:  GLViewer
341 **  Created: UI team, 02.09.02
342 ****************************************************************************/
343
344 #define WIDTH    640
345 #define HEIGHT   480
346 #define MARGIN   10
347
348 int static aLastViewPostId = 0;
349
350 void rotate_point( float& theX, float& theY, float theAngle )
351 {
352     float aTempX = theX * cos(theAngle) - theY * sin(theAngle);
353     float aTempY = theX * sin(theAngle) + theY * cos(theAngle);
354     theX = aTempX;
355     theY = aTempY;
356 }
357
358 GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame ) :
359        GLViewer_ViewPort( parent ),
360        myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ),
361        myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
362        myXPan( 0.0 ), myYPan( 0.0 )
363 {
364     if( theViewFrame == NULL )
365         myViewFrame = ( GLViewer_ViewFrame* )parent;
366     else
367         myViewFrame = theViewFrame;
368
369     myBorder = new QRect(0,0,0,0);
370     myGrid = NULL;
371     QBoxLayout* qbl = new QHBoxLayout( this );
372     myGLWidget = new GLViewer_Widget( this, 0 ) ;
373     qbl->addWidget( myGLWidget );
374     myGLWidget->setFocusProxy( this );
375     setMouseTracking( TRUE );
376
377     myIsDragProcess = noDrag;
378     //myCurDragMousePos = QPoint();
379     myCurDragPosX = NULL;
380     myCurDragPosY = NULL;
381
382     myCompass = 0;
383     //myCompass = new GLViewer_Compass();
384     //myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
385
386     myIsPulling = false;
387
388     myViewPortId = aLastViewPostId;
389     aLastViewPostId++;
390
391     mypFirstPoint = NULL;
392     mypLastPoint = NULL;
393
394     myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
395     connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ),
396              this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );
397 //    myGLWidget->installEventFilter( myObjectTip );
398 }
399
400 GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
401 {
402     if( myCompass )
403         delete myCompass;
404
405     if( myGrid )
406         delete myGrid;
407
408     delete myBorder;
409     delete myGLWidget;
410 }
411
412 void GLViewer_ViewPort2d::onCreatePopup()
413 {
414     //cout << "GLViewer_ViewPort2d::onCreatePopup" << endl;
415
416     //QAD_Desktop* desktop = (QAD_Desktop*) QAD_Application::getDesktop();
417     
418     QString theContext;
419     QString theParent("Viewer");
420     QString theObject;
421     
422     //desktop->definePopup( theContext, theParent, theObject );
423     //desktop->createPopup( myPopup, theContext, theParent, theObject);
424     //desktop->customPopup( myPopup, theContext, theParent, theObject );
425
426     /*
427     if ( myPopup->count() > 0 )
428       myIDs.append ( myPopup->insertSeparator() );  
429     int id;
430     myIDs.append ( id = myPopup->insertItem (tr ("MEN_VP3D_CHANGEBGR")) );  
431     QAD_ASSERT ( myPopup->connectItem ( id, this, SLOT(onChangeBackgroundColor())) );
432     */
433     
434     /*
435     if ( myPopup )
436     {
437         GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
438
439         QAD_ASSERT( myPopupActions.isEmpty() );
440
441         QAction* a = new QAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
442         a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
443         connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor() ) );
444         myPopupActions.append( a );
445         a->addTo( myPopup );        
446
447         myPopup->insertSeparator();
448
449         a = new QAction( "", tr( "MEN_VP_CREATE_GLMARKERS" ), 0, this );
450         a->setStatusTip( tr( "PRP_VP_CREATE_GLMARKERS" ) );
451         connect( a, SIGNAL( activated() ), aViewer, SLOT( onCreateGLMarkers() ) );
452         myPopupActions.append( a );
453         a->addTo( myPopup );        
454
455         a = new QAction( "", tr( "MEN_VP_CREATE_GLPOLYLINE" ), 0, this );
456         a->setStatusTip( tr( "PRP_VP_CREATE_GLPOLYLINE" ) );
457         connect( a, SIGNAL( activated() ), aViewer, SLOT( onCreateGLPolyline() ) );
458         myPopupActions.append( a );
459         a->addTo( myPopup );        
460
461         a = new QAction( "", tr( "MEN_VP_CREATE_GLTEXT" ), 0, this );
462         a->setStatusTip( tr( "PRP_VP_CREATE_GLTEXT" ) );
463         connect( a, SIGNAL( activated() ), aViewer, SLOT( onCreateGLText() ) );
464         myPopupActions.append( a );
465         a->addTo( myPopup );        
466
467         myPopup->insertSeparator();
468
469         //GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
470         int aSelObjects = aViewer->getGLContext()->NbSelected();
471         if( aSelObjects > 0 )
472         {
473             a = new QAction( "", tr( "MEN_VP_CUTOBJ" ), 0, this );
474             a->setStatusTip( tr( "PRP_VP_CUTOBJ" ) );
475             connect( a, SIGNAL( activated() ), SLOT( onCutObject() ) );
476             myPopupActions.append( a );
477             a->addTo( myPopup );
478
479             a = new QAction( "", tr( "MEN_VP_COPYOBJ" ), 0, this );
480             a->setStatusTip( tr( "PRP_VP_COPYOBJ" ) );
481             connect( a, SIGNAL( activated() ), SLOT( onCopyObject() ) );
482             myPopupActions.append( a );
483             a->addTo( myPopup );
484         }
485
486         a = new QAction( "", tr( "MEN_VP_PASTEOBJ" ), 0, this );
487         a->setStatusTip( tr( "PRP_VP_PASTEOBJ" ) );
488         connect( a, SIGNAL( activated() ), SLOT( onPasteObject() ) );
489         myPopupActions.append( a );
490         a->addTo( myPopup );
491
492         QClipboard *aClipboard = QApplication::clipboard();
493         QMimeSource* aMimeSource = aClipboard->data();
494         if( !aMimeSource->provides( "GLViewer_Objects" ) )
495             a->setEnabled( false );
496         
497     
498         if( aSelObjects > 0 )
499         {
500             myPopup->insertSeparator();
501             a = new QAction( "", tr( "MEN_VP_DRAGOBJ" ), 0, this );
502             a->setStatusTip( tr( "PRP_VP_DRAGOBJ" ) );
503             connect( a, SIGNAL( activated() ), SLOT( onStartDragObject() ) );
504             myPopupActions.append( a );
505             a->addTo( myPopup );
506             myCurDragPosX = new float((float)QCursor::pos().x());
507             myCurDragPosY = new float((float)QCursor::pos().y());
508             //myCurDragMousePos = QCursor::pos();            
509         }
510     }
511     */
512 }
513
514 void GLViewer_ViewPort2d::onCreatePopup( QPopupMenu* popup )
515 {
516 /*
517     if ( popup )
518     {
519         GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
520         if( !aViewer->isSketchingActive() )
521         {
522             if( !myPopupActions.isEmpty() )
523                 return;
524             QAction* a = new QAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
525             a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
526             connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor() ) );
527             myPopupActions.append( a );
528             a->addTo( popup );        
529
530             popup->insertSeparator();
531
532             //GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
533             int aSelObjects = aViewer->getGLContext()->NbSelected();
534             if( aSelObjects > 0 )
535             {
536                 a = new QAction( "", tr( "MEN_VP_CUTOBJ" ), 0, this );
537                 a->setStatusTip( tr( "PRP_VP_CUTOBJ" ) );
538                 connect( a, SIGNAL( activated() ), SLOT( onCutObject() ) );
539                 myPopupActions.append( a );
540                 a->addTo( popup );
541
542                 a = new QAction( "", tr( "MEN_VP_COPYOBJ" ), 0, this );
543                 a->setStatusTip( tr( "PRP_VP_COPYOBJ" ) );
544                 connect( a, SIGNAL( activated() ), SLOT( onCopyObject() ) );
545                 myPopupActions.append( a );
546                 a->addTo( popup );
547             }
548
549             a = new QAction( "", tr( "MEN_VP_PASTEOBJ" ), 0, this );
550             a->setStatusTip( tr( "PRP_VP_PASTEOBJ" ) );
551             connect( a, SIGNAL( activated() ), SLOT( onPasteObject() ) );
552             myPopupActions.append( a );
553             a->addTo( popup );
554
555             QClipboard *aClipboard = QApplication::clipboard();
556             QMimeSource* aMimeSource = aClipboard->data();
557             if( !aMimeSource->provides( "GLViewer_Objects" ) )
558                 a->setEnabled( false );
559             
560         
561             if( aSelObjects > 0 )
562             {
563                 popup->insertSeparator();
564                 a = new QAction( "", tr( "MEN_VP_DRAGOBJ" ), 0, this );
565                 a->setStatusTip( tr( "PRP_VP_DRAGOBJ" ) );
566                 connect( a, SIGNAL( activated() ), SLOT( onStartDragObject() ) );
567                 myPopupActions.append( a );
568                 a->addTo( popup );
569                 myCurDragPosX = new float((float)QCursor::pos().x());
570                 myCurDragPosY = new float((float)QCursor::pos().y());
571                 //myCurDragMousePos = QCursor::pos();            
572             }
573         }
574         else
575         {//sketching mode
576             QAD_ASSERT( myPopupActions.isEmpty() );
577             QAction* a = new QAction( "", tr( "MEN_VP_SKETCH_DEL_OBJECT" ), 0, this );
578             a->setStatusTip( tr( "PRP_VP_SKETCH_DEL_OBJECT" ) );
579             connect( a, SIGNAL( activated() ), aViewer, SLOT( onSketchDelObject() ) );
580             myPopupActions.append( a );
581             a->addTo( popup );        
582
583             popup->insertSeparator();
584
585             a = new QAction( "", tr( "MEN_VP_SKETCH_UNDO_LAST" ), 0, this );
586             a->setStatusTip( tr( "PRP_VP_SKETCH_UNDO_LAST" ) );
587             connect( a, SIGNAL( activated() ), aViewer, SLOT( onSketchUndoLast() ) );
588             myPopupActions.append( a );
589             a->addTo( popup );
590
591             int aSkType = aViewer->getSketchingType();
592             if( ( aSkType == GLViewer_Viewer2d::Polyline ) || 
593                 ( aSkType == GLViewer_Viewer2d::Curve) ||
594                 ( aSkType == GLViewer_Viewer2d::Scribble ) )
595             {
596                 a = new QAction( "", tr( "MEN_VP_SKETCH_FINISH" ), 0, this );
597                 a->setStatusTip( tr( "PRP_VP_SKETCH_FINISH" ) );
598                 connect( a, SIGNAL( activated() ), aViewer, SLOT( onSketchFinish() ) );
599                 myPopupActions.append( a );
600                 a->addTo( popup );
601             }
602         }
603     }
604 */
605 }
606     
607 void GLViewer_ViewPort2d::onDestroyPopup( QPopupMenu* popup )
608 {
609 /*
610     if ( popup )
611     {
612         for ( QAction* a = myPopupActions.first(); a; a = myPopupActions.next() )
613             a->removeFrom( popup );
614         myPopupActions.clear();
615         popup->clear();
616     }
617 */
618 }
619
620
621 void GLViewer_ViewPort2d::onStartDragObject( )
622 {
623     if( myIsDragProcess == noDrag )
624     {
625         myIsDragProcess = initDrag;
626         QCursor::setPos( ( int )( *myCurDragPosX ), ( int )( *myCurDragPosY ) );
627         //myCurDragMousePos = QPoint( 0, 0 );
628         delete myCurDragPosX;
629         delete myCurDragPosY;
630         myCurDragPosX = NULL;
631         myCurDragPosY = NULL;
632         return;
633     } 
634 }
635
636 void GLViewer_ViewPort2d::onCutObject()
637
638     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
639     if( aMovingObject )    
640     {        
641         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
642         aMimeSource->setObject( aMovingObject );
643         
644         QClipboard *aClipboard = QApplication::clipboard();
645         aClipboard->clear();
646         aClipboard->setData( aMimeSource );
647
648         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->deleteObject( aMovingObject );
649     }*/
650     GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
651     int aObjNum = aContext->NbSelected();
652     if( aObjNum > 0 )
653     {
654         QValueList<GLViewer_Object*> aObjects;
655         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
656         aContext->InitSelected();
657         for( ; aContext->MoreSelected(); aContext->NextSelected() )
658             aObjects.append( aContext->SelectedObject() );
659
660         //aMimeSource->setObjects( aObjects ); ouv 6.05.04
661
662         QClipboard *aClipboard = QApplication::clipboard();
663         aClipboard->clear();
664         aClipboard->setData( aMimeSource );
665
666         for( int i = 0; i < aObjNum; i++ )
667             aContext->deleteObject( aObjects[i] );
668     }
669 }
670
671 void GLViewer_ViewPort2d::onCopyObject()
672 {
673     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
674     if( aMovingObject )    
675     {        
676         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
677         aMimeSource->setObject( aMovingObject );
678         
679         QClipboard *aClipboard = QApplication::clipboard();
680         aClipboard->clear();
681         aClipboard->setData( aMimeSource );
682     }
683     */
684     GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
685     int aObjNum = aContext->NbSelected();
686     if( aObjNum > 0 )
687     {
688         QValueList<GLViewer_Object*> aObjects;
689         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
690         aContext->InitSelected();
691         for( ; aContext->MoreSelected(); aContext->NextSelected() )
692             aObjects.append( aContext->SelectedObject() );
693
694         //aMimeSource->setObjects( aObjects ); ouv 6.05.04
695
696         QClipboard *aClipboard = QApplication::clipboard();
697         aClipboard->clear();
698         aClipboard->setData( aMimeSource );
699     }
700 }
701
702 void GLViewer_ViewPort2d::onPasteObject()
703 {
704     /*QClipboard *aClipboard = QApplication::clipboard();
705     QMimeSource* aMimeSource = aClipboard->data();
706     if( aMimeSource->provides( "GLViewer_Object" ) )
707     {
708         const char* aType;
709         int i = 1;
710         QByteArray anArray;
711         do
712         {
713             aType = aMimeSource->format( i );
714             anArray = aMimeSource->encodedData( aType );
715             if( anArray.size() != 0 )
716                 break;
717             i++;
718         }
719         while( aType != 0 );
720         if( anArray.size() == 0 )
721             return;
722
723         GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
724         if( !aObject )
725             return;
726         
727         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
728     }
729     */
730     //QClipboard *aClipboard = QApplication::clipboard();
731     //QMimeSource* aMimeSource = aClipboard->data();
732
733     /* ouv 6.05.04
734     if( aMimeSource->provides( "GLViewer_Objects" ) )
735     {
736         QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" );
737         QValueList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
738         if( aObjects.empty() )
739             return;
740         GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
741         for( int i = 0; i < aObjects.count(); i++ )
742             aContext->insertObject( aObjects[i], true );
743     }
744     */
745 }
746
747 void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
748 {
749   //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl;
750   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
751   GLViewer_Context* aContext = aViewer->getGLContext();
752   GLViewer_Object* anObject = aContext->getCurrentObject();
753   
754   if( !aContext )
755     return;
756
757   float aX = e->pos().x();
758   float anY = e->pos().y();
759   aViewer->transPoint( aX, anY );
760     
761   if( myCurDragPosX == NULL && myCurDragPosY == NULL )
762   {
763     myCurDragPosX = new float(aX);
764     myCurDragPosY = new float(anY);
765     return;
766   }
767
768   //QPoint aNewPos = e->pos();
769   //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
770   
771   if( anObject && (e->state() & LeftButton ) )
772   {
773     if( aContext->isSelected( anObject ) )
774     {
775       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
776       {
777         GLViewer_Object* aMovingObject = aContext->SelectedObject();
778         //= aViewer->getGLContext()->getCurrentObject();
779         if( aMovingObject )
780         {
781           aMovingObject->moveObject( aX - *myCurDragPosX ,
782                                      anY - *myCurDragPosY);
783           //QRect* rect = aMovingObject->getRect()->toQRect();
784           //aViewer->updateBorders( *rect );
785           aViewer->updateBorders();
786         }
787       }
788     }
789     else
790       anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
791   }
792   else if( aContext->NbSelected() && (e->state() & MidButton ) )
793     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
794       (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
795   
796   aViewer->updateBorders();
797
798   delete myCurDragPosX;
799   delete myCurDragPosY;
800   myCurDragPosX = new float(aX);
801   myCurDragPosY = new float(anY);    
802
803   myGLWidget->updateGL();
804 }
805
806 /*!
807     Emits 'mouseEvent' signal. [ virtual protected ]
808 */
809 void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent *e )
810 {
811     
812     //if(  )
813     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
814     if( aMovingObject )
815     {
816         onStartDragObject();
817     }*/
818     emit vpMouseEvent( e );
819     
820     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();   
821     GLViewer_Context* aContext = aViewer->getGLContext();
822
823     GLViewer_Object* anObject = NULL;
824     if( aContext )
825       anObject = aContext->getCurrentObject();
826     
827     bool accel = e->state() & GLViewer_ViewTransformer::accelKey();
828     if( ( anObject && !( accel || e->button() == Qt::RightButton ) )
829         ||
830         ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton )  )
831     {       
832       myIsDragProcess = inDrag;
833     }
834 }
835
836 /*!
837     Emits 'mouseEvent' signal. [ virtual protected ]
838 */
839 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
840 {
841     //GLViewer_Context* context = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
842     //if( context->getCurrentObject() ) cout << "LASTPICKED" << endl;
843     emit vpMouseEvent( e );
844     
845     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();   
846     GLViewer_Context* aContext = aViewer->getGLContext();
847
848     if( myIsDragProcess == inDrag )
849         onDragObject( e );
850     
851     GLViewer_Object* anObj = aContext->getCurrentObject();
852     if( anObj && aContext->currentObjectIsChanged() )
853     {
854         //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::add}" << endl;
855         //QToolTip::remove( myGLWidget );
856         QRect* aRect = (aViewer->getWinObjectRect(anObj));
857         //QToolTip::add( myGLWidget, *aRect, anObj->getToolTipText() );
858         myGLWidget->addToolTip( anObj->getToolTipText(), *aRect );
859     }
860     if(!anObj)
861     {
862         //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::remove}" << endl;
863         //QRect* aRect = (aViewer->getWinObjectRect(anObj));
864         //QToolTip::remove( myGLWidget, *aRect );
865         myGLWidget->removeToolTip();
866     }
867 }
868
869 /*!
870     Emits 'mouseEvent' signal. [ virtual protected ]
871 */
872 void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent *e )
873 {
874   /*if( myIsDragProcess == inDrag )
875     {
876         GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
877         GLViewer_Context* aContext = aViewer->getGLContext();
878         for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
879         {
880             GLViewer_Object* aMovingObject = aContext->SelectedObject();
881             if( aMovingObject )
882                 aMovingObject->finishMove();
883         }
884
885         myIsDragProcess = noDrag;
886         //yCurDragMousePos.setX( 0 );
887         //myCurDragMousePos.setY( 0 );
888         delete myCurDragPosX;
889         delete myCurDragPosY;
890         myCurDragPosX = NULL;
891         myCurDragPosY = NULL;
892         }*/
893     
894
895     /* show popup menu */
896     if ( e->button() == Qt::RightButton )
897     {
898         //QPopupMenu* popup = createPopup();
899         //if ( popup && popup->count() )
900         //    popup->exec( QCursor::pos() );
901         //destroyPopup( /*popup*/ );
902     }
903     emit vpMouseEvent( e );
904     
905     if( myIsDragProcess == inDrag )
906     {
907       bool isAnyMoved = false;
908       GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
909       GLViewer_Context* aContext = aViewer->getGLContext();
910       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
911       {
912         GLViewer_Object* aMovingObject = aContext->SelectedObject();
913         if( aMovingObject )
914         {
915           aMovingObject->finishMove();
916           isAnyMoved = true;
917         }
918       }
919       
920       GLViewer_Object* anObject = aContext->getCurrentObject();
921       if( anObject )
922         anObject->finishMove();
923       
924       myIsDragProcess = noDrag;
925       //yCurDragMousePos.setX( 0 );
926       //myCurDragMousePos.setY( 0 );
927       delete myCurDragPosX;
928       delete myCurDragPosY;
929       myCurDragPosX = NULL;
930       myCurDragPosY = NULL;
931       emit objectMoved();
932     }
933 }
934
935 void GLViewer_ViewPort2d::turnCompass( GLboolean on )
936 {
937     if( on )
938         myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
939     else if( myCompass )
940         delete myCompass;
941 }
942
943 void GLViewer_ViewPort2d::turnGrid( GLboolean on )
944 {
945     if( on )
946       myGrid = new GLViewer_RectangularGrid( 2*WIDTH, 2*HEIGHT,
947                                              2*WIDTH, 2*HEIGHT, 
948                                              XSIZE, YSIZE,
949                                              myXPan, myYPan,
950                                              myXScale, myYScale );
951     else if( myGrid )
952       delete myGrid;
953 }
954
955 void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor )
956 {
957     if( myGrid )
958     {
959         myGrid->setGridColor( ( GLfloat )gridColor.red() / 255,
960                   ( GLfloat )gridColor.green() / 255,
961                   ( GLfloat )gridColor.blue() / 255 );
962         myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255,
963                   ( GLfloat )axisColor.green() / 255,
964                   ( GLfloat )axisColor.blue() / 255 );
965     }
966 }
967
968 void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
969 {
970     GLViewer_ViewPort::setBackgroundColor( color );
971     myGLWidget->makeCurrent();
972     glClearColor( ( GLfloat )color.red() / 255,
973             ( GLfloat )color.green() / 255,
974             ( GLfloat )color.blue() / 255, 1.0 );
975     myGLWidget->repaint();
976 }
977
978 QColor GLViewer_ViewPort2d::backgroundColor() const
979 {
980     return GLViewer_ViewPort::backgroundColor();
981 }
982
983 void GLViewer_ViewPort2d::initResize( int x, int y )
984 {
985     float xa, xb, ya, yb;
986     xa = myBorder->left() - myMargin;
987     xb = myBorder->right() + myMargin;
988     ya = myBorder->top() - myMargin;
989     yb = myBorder->bottom() + myMargin;
990
991     GLfloat zoom, xzoom, yzoom;
992     GLfloat w = x;
993     GLfloat h = y;
994     bool max = FALSE;
995
996     xzoom = (GLfloat)x / myWidth; 
997     yzoom = (GLfloat)y / myHeight; 
998
999     if ( ( xzoom < yzoom ) && ( xzoom < 1 ) ) 
1000         zoom = xzoom; 
1001     else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) ) 
1002         zoom = yzoom; 
1003     else 
1004     { 
1005         max = TRUE; 
1006         zoom = xzoom > yzoom ? xzoom : yzoom; 
1007     } 
1008
1009     if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
1010              ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || 
1011              ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
1012              ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) ) 
1013         zoom = 1; 
1014
1015     if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
1016             ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || 
1017             ( ( myYPan + h/2 ) < yb * myYScale * zoom ) || 
1018             ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) 
1019         zoom = 1; 
1020  
1021     myWidth = x;
1022     myHeight = y; 
1023
1024     myXScale *= zoom; 
1025     myYScale = myXScale; 
1026
1027     if ( myGrid )
1028         myGrid->setResize( 2*x, 2*y, zoom );
1029
1030     myGLWidget->setScale( myXScale, myYScale, 1.0 );
1031 }
1032
1033 void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
1034 {
1035     //cout << "GLViewer_ViewPort2d::paintEvent" << endl;
1036     myGLWidget->updateGL();
1037     GLViewer_ViewPort::paintEvent( e );
1038 }
1039
1040 void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e )
1041 {
1042     //cout << "GLViewer_ViewPort2d::resizeEvent" << endl;
1043     GLViewer_ViewPort::resizeEvent( e );
1044 }
1045
1046 void GLViewer_ViewPort2d::reset()
1047 {
1048     //cout << "GLViewer_ViewPort2d::reset" << endl;
1049
1050     GLint val[4]; 
1051     GLint vpWidth, vpHeight; 
1052
1053     myGLWidget->makeCurrent();
1054     glGetIntegerv( GL_VIEWPORT, val );
1055     vpWidth = val[2]; 
1056     vpHeight = val[3]; 
1057
1058     GLint w = myGLWidget->getWidth();
1059     GLint h = myGLWidget->getHeight();
1060     GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ? 
1061                  vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h; 
1062
1063     if( myGrid )
1064     {
1065         myGrid->setPan( 0.0, 0.0 );
1066         myGrid->setZoom( zoom / myXScale );
1067     }
1068
1069     myXPan = 0.0;
1070     myYPan = 0.0;
1071     myXScale = zoom;
1072     myYScale = zoom;
1073
1074     myGLWidget->setPan( myXPan, myYPan, 0.0 );
1075     myGLWidget->setScale( myXScale, myYScale, 1.0 );
1076     myGLWidget->setRotationAngle( 0.0 );
1077     myGLWidget->setRotation( 0.0, 0.0, 0.0, 1.0 );
1078     myGLWidget->updateGL();
1079 }
1080
1081 void GLViewer_ViewPort2d::pan( int dx, int dy )
1082 {
1083     //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl;
1084
1085     /*myXPan += dx / myXScale;
1086     myYPan += dy / myYScale;
1087
1088     float ra, rx, ry, rz;
1089     myGLWidget->getRotation( ra, rx, ry, rz );
1090     GLfloat angle = ra * PI / 180.;
1091
1092     if( myGrid )
1093         myGrid->setPan( myXPan*cos(angle) + myYPan*sin(angle),
1094                         -myXPan*sin(angle) + myYPan*cos(angle) );
1095
1096     */
1097     float ra, rx, ry, rz;
1098     myGLWidget->getRotation( ra, rx, ry, rz );
1099     GLfloat angle = ra * PI / 180.;
1100
1101     myXPan += (dx*cos(angle) + dy*sin(angle)) / myXScale;
1102     myYPan += (-dx*sin(angle) + dy*cos(angle)) / myXScale;
1103
1104     if( myGrid )
1105         myGrid->setPan( myXPan, myYPan );
1106
1107     myGLWidget->setPan( myXPan, myYPan, 0.0 );
1108     myGLWidget->setScale( myXScale, myYScale, 1.0 );
1109     myGLWidget->updateGL();
1110 }
1111
1112 void GLViewer_ViewPort2d::setCenter( int x, int y )
1113 {
1114     //cout << "GLViewer_ViewPort2d::setCenter" << endl;
1115
1116     GLint val[4]; 
1117     GLint vpWidth, vpHeight; 
1118
1119     myGLWidget->makeCurrent();
1120     glGetIntegerv( GL_VIEWPORT, val );
1121     vpWidth = val[2]; 
1122     vpHeight = val[3]; 
1123
1124     myXPan -= ( x - vpWidth/2 ) / myXScale;
1125     myYPan += ( y - vpHeight/2 ) / myYScale;
1126
1127     if( myGrid )
1128     {
1129         myGrid->setPan( myXPan, myYPan );
1130         myGrid->setZoom( myXOldScale / myXScale );
1131     }
1132
1133     myXScale = myXOldScale;
1134     myYScale = myYOldScale;
1135
1136     myGLWidget->setPan( myXPan, myYPan, 0.0 );
1137     myGLWidget->setScale( myXScale, myYScale, 1.0 );
1138     myGLWidget->updateGL();
1139 }
1140
1141 void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
1142 {
1143     //cout << "GLViewer_ViewPort2d::zoom" << endl;
1144   
1145     float dx, dy, zm;
1146     dx = x - x0;
1147     dy = y - y0;
1148
1149     if ( dx == 0. && dy == 0. )
1150         return;
1151
1152     zm = sqrt(dx * dx + dy * dy) / 100. + 1; 
1153     zm = (dx > 0.) ?  zm : 1. / zm; 
1154
1155     //backup values
1156     float bX = myXScale;
1157     float bY = myYScale;
1158     myXScale *= zm; 
1159     myYScale *= zm; 
1160
1161     if( myGrid )
1162     {
1163         if( myGrid->setZoom( zm ) )
1164         {
1165             myGLWidget->setPan( myXPan, myYPan, 0.0 );
1166             myGLWidget->setScale( myXScale, myYScale, 1.0 );
1167             myGLWidget->updateGL();
1168         }
1169         else
1170         {// undo
1171             myXScale = bX;
1172             myYScale = bY;
1173         } 
1174     }
1175     else
1176     {
1177         myGLWidget->setPan( myXPan, myYPan, 0.0 );
1178         myGLWidget->setScale( myXScale, myYScale, 1.0 );
1179         myGLWidget->updateGL();
1180     }
1181 }
1182
1183 void GLViewer_ViewPort2d::fitRect( const QRect& rect )
1184 {
1185     //cout << "GLViewer_ViewPort2d::fitRect" << endl;
1186
1187     float x0, x1, y0, y1;
1188     float dx, dy, zm, centerX, centerY; 
1189
1190     GLint val[4]; 
1191     GLint vpWidth, vpHeight; 
1192
1193     myGLWidget->makeCurrent();
1194     glGetIntegerv( GL_VIEWPORT, val );
1195     vpWidth = val[2]; 
1196     vpHeight = val[3]; 
1197
1198     x0 = rect.left();
1199     x1 = rect.right();
1200     y0 = rect.top();
1201     y1 = rect.bottom();
1202
1203     dx = fabs( x1 - x0 ); 
1204     dy = fabs( y1 - y0 ); 
1205     centerX = ( x0 + x1 ) / 2.; 
1206     centerY = ( y0 + y1 ) / 2.; 
1207
1208     if ( dx == 0. || dy == 0. )
1209         return;
1210
1211     zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; 
1212
1213     //myXPan += ( vpWidth / 2. - centerX ) / myXScale;
1214     //myYPan -= ( vpHeight / 2. - centerY ) / myYScale;
1215
1216     float aDX = ( vpWidth / 2. - centerX ) / myXScale;
1217     float aDY = ( vpHeight / 2. - centerY ) / myYScale;
1218
1219     float ra, rx, ry, rz;
1220     myGLWidget->getRotation( ra, rx, ry, rz );
1221     GLfloat angle = ra * PI / 180.;
1222
1223     myXPan += (aDX*cos(angle) - aDY*sin(angle));
1224     myYPan -= (aDX*sin(angle) + aDY*cos(angle));
1225
1226     if( myGrid )
1227         myGrid->setPan( myXPan, myYPan );
1228
1229     myXScale *= zm;
1230     myYScale = myXScale;
1231
1232     if( myGrid )
1233         myGrid->setZoom( zm );
1234
1235     myGLWidget->setPan( myXPan, myYPan, 0.0 );
1236     myGLWidget->setScale( myXScale, myYScale, 1.0 );
1237     myGLWidget->updateGL();
1238 }
1239
1240 void GLViewer_ViewPort2d::fitSelect()
1241 {
1242   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1243   GLViewer_Context* aContext = aViewer->getGLContext();
1244   if( !aContext )
1245     return;
1246   
1247   QRect aSelRect;
1248   for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
1249     aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() ));
1250
1251   if( aSelRect.isValid() )
1252   {
1253     aSelRect.setTop( aSelRect.top() - SELECTION_RECT_GAP );
1254     aSelRect.setBottom( aSelRect.bottom() + SELECTION_RECT_GAP );
1255     aSelRect.setLeft( aSelRect.left() - SELECTION_RECT_GAP );
1256     aSelRect.setRight( aSelRect.right() + SELECTION_RECT_GAP );
1257     fitRect( aSelRect );
1258   }
1259 }
1260
1261 void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
1262 {
1263     //cout << "GLViewer_ViewPort2d::fitAll" << endl;
1264
1265     float xa, xb, ya, yb;
1266     float dx, dy, zm;
1267     float xScale, yScale;
1268
1269     myMargin = QMAX( myBorder->width(), myBorder->height() ) / 10;
1270
1271     xa = myBorder->left() - myMargin;
1272     xb = myBorder->right() + myMargin;
1273     ya = myBorder->top() - myMargin;
1274     yb = myBorder->bottom() + myMargin;
1275
1276     float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb };
1277
1278     float ra, rx, ry, rz;
1279     myGLWidget->getRotation( ra, rx, ry, rz );
1280     float angle = ra * PI / 180.;
1281
1282     int i;
1283     for( i = 0; i < 7; i = i + 2 )
1284         rotate_point( aPoints[i], aPoints[i+1], angle );
1285
1286     float aBorders[4] = { aPoints[0], aPoints[0], aPoints[1], aPoints[1] };
1287
1288     for( i = 2; i < 7; i = i + 2 )
1289     {
1290         if( aBorders[0] < aPoints[i] )
1291             aBorders[0] = aPoints[i];
1292         if( aBorders[1] > aPoints[i] )
1293             aBorders[1] = aPoints[i];
1294
1295         if( aBorders[2] < aPoints[i+1] )
1296             aBorders[2] = aPoints[i+1];
1297         if( aBorders[3] > aPoints[i+1] )
1298             aBorders[3] = aPoints[i+1];
1299     }
1300
1301     GLint val[4];
1302     GLint vpWidth, vpHeight;
1303
1304     myGLWidget->makeCurrent();
1305     glGetIntegerv( GL_VIEWPORT, val );
1306     vpWidth = val[2];
1307     vpHeight = val[3];
1308
1309     dx = fabs( aBorders[1] - aBorders[0] );
1310     dy = fabs( aBorders[3] - aBorders[2] );
1311
1312     myXPan = -( aBorders[0] + aBorders[1] ) / 2; 
1313     myYPan = -( aBorders[2] + aBorders[3] ) / 2;
1314     
1315
1316     if( keepScale )
1317     {
1318         myXOldScale = myXScale;
1319         myYOldScale = myYScale;
1320     }
1321
1322     xScale = myXScale;
1323     yScale = myYScale;
1324     zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; 
1325     myXScale = zm; 
1326     myYScale = zm;    
1327     
1328
1329     if( myGrid )
1330     {
1331         myGrid->setPan( myXPan, myYPan );
1332         if( dx > dy )
1333             myGrid->setZoom(  zm / xScale );
1334         else  
1335             myGrid->setZoom( zm / yScale );
1336     }
1337
1338     myGLWidget->setPan( myXPan, myYPan, 0.0 );
1339     myGLWidget->setScale( myXScale, myYScale, 1.0 );
1340     myGLWidget->updateGL();
1341
1342     if( keepScale )
1343         emit vpUpdateValues();
1344 }
1345
1346 void GLViewer_ViewPort2d::startRotation( int x, int y )
1347 {
1348     //cout << "GLViewer_ViewPort2d::startRotation" << endl;
1349
1350     myGLWidget->setRotationStart( x, y, 1.0 );
1351 }
1352
1353 void GLViewer_ViewPort2d::rotate( int x, int y )
1354 {
1355     //cout << "GLViewer_ViewPort2d::rotate " << x << " " << y << endl;
1356
1357     GLint val[4];
1358     GLint vpWidth, vpHeight;
1359
1360     myGLWidget->makeCurrent();
1361     glGetIntegerv( GL_VIEWPORT, val );
1362     vpWidth = val[2];
1363     vpHeight = val[3];
1364
1365     float x0 = vpWidth/2;
1366     float y0 = vpHeight/2;
1367
1368     float xs, ys, zs, dx, dy;
1369     myGLWidget->getRotationStart( xs, ys, zs );
1370
1371     xs = xs - x0;
1372     x = ( int )( x - x0 );
1373     dx = x - xs;
1374     ys = y0 - ys;
1375     y = ( int )( y0 - y );
1376     dy = y - ys;
1377
1378     float l1 = pow( double( xs*xs + ys*ys ), 0.5 );
1379     float l2 = pow( double( x*x + y*y ), 0.5 );
1380     float l = pow( double( dx*dx + dy*dy ), 0.5 );
1381
1382     double mult = xs * y - x * ys;
1383     short sign;
1384     if( mult > 0 ) sign = 1;
1385     else if( mult < 0 ) sign = -1;
1386     else sign = 0;
1387
1388     float anglePrev = myGLWidget->getRotationAngle();
1389     float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI;
1390     float angle = anglePrev + angleNew;
1391
1392     //GLfloat anAngle = angle * PI / 180.;
1393
1394     //if( myGrid )
1395     //    myGrid->setPan( myXPan*cos(anAngle) + myYPan*sin(anAngle),
1396     //                    -myXPan*sin(anAngle) + myYPan*cos(anAngle) );
1397
1398     //cout << l1 << endl;
1399     //cout << l2 << endl;
1400     //cout << l << endl;
1401
1402     //cout << xs << " " << ys << " " << x << " " << y << endl;
1403     //cout << "MULTIPLICATION : " << mult << endl;
1404
1405     //cout << "ANGLE_PREV = " << anglePrev << endl;
1406     //cout << "ANGLE_NEW = " << angleNew << endl;
1407     //cout << "ANGLE = " << angle << endl;
1408
1409     float ra, rx, ry, rz;
1410     myGLWidget->getRotation( ra, rx, ry, rz );
1411     myGLWidget->setRotation( angle, rx, ry, rz );
1412     myGLWidget->updateGL();
1413 }
1414
1415 void GLViewer_ViewPort2d::endRotation()
1416 {
1417     //cout << "GLViewer_ViewPort2d::endRotation" << endl;
1418
1419     float ra, rx, ry, rz;
1420     myGLWidget->getRotation( ra, rx, ry, rz );
1421     myGLWidget->setRotationAngle( ra );
1422 }
1423
1424 void GLViewer_ViewPort2d::drawCompass(){
1425     if( !myCompass->getVisible() ) return;
1426
1427     GLfloat xScale, yScale, xPan, yPan;
1428
1429     int xPos = getWidth();
1430     int yPos = getHeight();
1431
1432     int cPos = myCompass->getPos();
1433     int cSize = myCompass->getSize();
1434     QColor* cCol = &(myCompass->getColor());
1435     int cWidthTop = myCompass->getArrowWidthTop();
1436     int cWidthBot = myCompass->getArrowWidthBottom();
1437     int cHeightTop = myCompass->getArrowHeightTop();
1438     int cHeightBot = myCompass->getArrowHeightBottom();
1439
1440     GLfloat colorR = (cCol->red())/255;
1441     GLfloat colorG = (cCol->green())/255;
1442     GLfloat colorB = (cCol->blue())/255;
1443
1444     float delX = cSize * 0.5;
1445     float delY = cSize * 0.5;
1446
1447     getScale( xScale, yScale );
1448     getPan( xPan, yPan);
1449
1450     float centerX = (xPos/2 - delX - cSize)/xScale;
1451     float centerY = (yPos/2 - delY - cSize)/yScale;
1452     
1453     switch ( cPos )
1454     {
1455     case GLViewer_Compass::TopLeft:
1456             centerX = -centerX;
1457             break;
1458         case GLViewer_Compass::BottomLeft:
1459             centerX = -centerX;
1460             centerY = -centerY;
1461             break;
1462         case GLViewer_Compass::BottomRight:
1463             centerY = -centerY;
1464             break;
1465         default: break;
1466     }
1467     
1468     float ra, rx, ry, rz;
1469     myGLWidget->getRotation( ra, rx, ry, rz );
1470     GLfloat angle = ra * PI / 180.;
1471     GLfloat /*r = 0.0,*/ x = 0.0 , y = 0.0;
1472
1473     rotate_point( centerX, centerY, -angle );
1474
1475     centerX -= xPan;
1476     centerY -= yPan;
1477
1478     glColor3f( colorR, colorG, colorB );
1479     glBegin( GL_POLYGON );     
1480     //arrow
1481         x = centerX;                      y = centerY + cSize / yScale;    
1482         glVertex2f( x, y );
1483         //point #2
1484         x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1485         glVertex2f( x, y );
1486         //point #3    
1487         x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1488         glVertex2f( x, y );
1489         //point #4
1490         x = centerX + cWidthBot / xScale; y = centerY - cSize/yScale;
1491         glVertex2f( x, y );
1492         //point #5
1493         x = centerX;                      y = centerY - (cSize - cHeightBot) / yScale ;
1494         glVertex2f( x, y ); 
1495         //point #6
1496         x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale;
1497         glVertex2f( x, y );
1498         //point #7
1499         x = centerX - cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1500         glVertex2f( x, y );
1501         //point #8
1502         x = centerX - cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1503         glVertex2f( x, y );
1504     glEnd();
1505     glLineWidth( 2.0 );
1506     glEnable( GL_LINE_SMOOTH );
1507     glBegin(GL_LINE_LOOP);
1508     //circle
1509         float aCircAngle = 0;
1510         for ( int i = 0; i < 20 * SEGMENTS + 1; i++ )
1511         {
1512             x = centerX + cos(aCircAngle) * cSize / xScale;
1513             y = centerY + sin(aCircAngle) * cSize / yScale;
1514             glVertex2f( x, y );    
1515             aCircAngle += float( STEP ) / 2;
1516         }        
1517     glEnd(); 
1518     
1519     GLdouble        modelMatrix[16], projMatrix[16];
1520     GLint           viewport[4];
1521     GLdouble        winxN, winyN, winz;
1522     GLdouble        winxE, winyE;
1523     GLdouble        winxS, winyS;
1524     GLdouble        winxW, winyW;
1525     GLuint          aTextList;    
1526
1527     GLViewer_TexFont* aFont = myCompass->getFont();
1528     float widN = (float)aFont->getStringWidth( "N" );
1529     float widW = (float)aFont->getStringWidth( "W" );
1530     float widS = (float)aFont->getStringWidth( "S" );
1531     float widE = (float)aFont->getStringWidth( "E" );
1532     float heightL = (float)aFont->getStringHeight();
1533
1534     float xGapN = - widN/2 *( 1.0 + sin(angle) );
1535     float xGapS = - widS/2 *( 1.0 - sin(angle) );
1536     float xGapW = - widW/2 *( 1.0 + cos(angle) );
1537     float xGapE = - widE/2 *( 1.0 - cos(angle) );
1538
1539     float yGapN = - heightL/2 *( 1.0 - cos(angle) ) * 0.75;
1540     float yGapS = - heightL/2 *( 1.0 + cos(angle) ) * 0.75;
1541     float yGapW = - heightL/2 *( 1.0 + sin(angle) ) * 0.75;
1542     float yGapE = - heightL/2 *( 1.0 - sin(angle) ) * 0.75;
1543
1544     glGetIntegerv (GL_VIEWPORT, viewport);
1545     glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1546     glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1547     
1548     gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz);
1549     gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz);
1550     gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz);
1551     gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz);
1552
1553     glColor3f( 1.0, 1.0, 1.0 );    
1554
1555     aTextList = glGenLists( 1 );
1556     glNewList( aTextList, GL_COMPILE );
1557
1558     glMatrixMode(GL_PROJECTION);
1559     glPushMatrix();
1560     glLoadIdentity();
1561     glOrtho(0,viewport[2],0,viewport[3],-100,100);
1562     glMatrixMode(GL_MODELVIEW);
1563     glPushMatrix();
1564     glLoadIdentity();    
1565
1566     aFont->drawString( "N", winxN + xGapN, winyN + yGapN );
1567     aFont->drawString( "E", winxE + xGapE, winyE + yGapE );
1568     aFont->drawString( "S", winxS + xGapS, winyS + yGapS );
1569     aFont->drawString( "W", winxW + xGapW, winyW + yGapW );
1570
1571     glMatrixMode(GL_PROJECTION);
1572     glPopMatrix();
1573     glMatrixMode(GL_MODELVIEW);
1574     glPopMatrix();
1575
1576     glEndList();
1577
1578     if ( aTextList != -1 ) 
1579         glCallList( aTextList );
1580 }
1581
1582 BlockStatus GLViewer_ViewPort2d::currentBlock()
1583 {
1584     if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL)
1585         return BlockStatus(BS_Highlighting | BS_Selection);
1586     
1587     if( mypFirstPoint && mypLastPoint )
1588         return BlockStatus(BS_Highlighting | BS_Selection);
1589     
1590     return BS_NoBlock;
1591 }
1592
1593 void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
1594 {
1595     if( !mypFirstPoint && !mypLastPoint )
1596     {
1597         mypFirstPoint = new QPoint( x, y );
1598         mypLastPoint = new QPoint( x, y );
1599     }
1600 }
1601 void GLViewer_ViewPort2d::drawSelectByRect( int x, int y )
1602 {
1603     if( mypFirstPoint && mypLastPoint )
1604     {
1605
1606         QPainter p( getPaintDevice() );
1607         p.setPen( Qt::white );
1608         p.setRasterOp( Qt::XorROP );
1609
1610         p.drawRect( selectionRect() );    /* erase */
1611
1612         mypLastPoint->setX( x );
1613         mypLastPoint->setY( y );
1614         
1615         p.drawRect( selectionRect() );    /* draw */
1616     }
1617
1618 }
1619 void GLViewer_ViewPort2d::finishSelectByRect()
1620 {
1621     if( mypFirstPoint && mypLastPoint )
1622     {
1623
1624         QPainter p( getPaintDevice() );
1625         p.setPen( Qt::white );
1626         p.setRasterOp( Qt::XorROP );
1627
1628         p.drawRect( selectionRect() );    /* erase */
1629
1630         delete mypFirstPoint;
1631         delete mypLastPoint;
1632
1633         mypFirstPoint = NULL;
1634         mypLastPoint = NULL;
1635     }
1636 }
1637
1638 QRect GLViewer_ViewPort2d::selectionRect()
1639 {
1640     QRect aRect;
1641     if( mypFirstPoint && mypLastPoint )
1642     {
1643         aRect.setLeft( QMIN( mypFirstPoint->x(), mypLastPoint->x() ) );
1644         aRect.setTop( QMIN( mypFirstPoint->y(), mypLastPoint->y() ) );
1645         aRect.setRight( QMAX( mypFirstPoint->x(), mypLastPoint->x() ) );
1646         aRect.setBottom( QMAX( mypFirstPoint->y(), mypLastPoint->y() ) );
1647     }
1648
1649     return aRect;
1650 }
1651
1652 bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
1653 {
1654     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1655     GLViewer_Context* aContext = aViewer->getGLContext();
1656     ObjectMap anObjects = aContext->getObjects();
1657
1658     for( ObjectMap::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1659     {
1660         GLViewer_Rect* aRect = it.key()->getRect();
1661
1662         if( aRect->contains( point ) && it.key()->startPulling( point ) )
1663         {
1664             myIsPulling = true;
1665             myPullingObject = it.key();
1666             setCursor( *getHandCursor() );
1667             return true;
1668         }
1669     }
1670
1671     return false;
1672 }
1673
1674 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
1675 {
1676     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1677     GLViewer_Context* aContext = aViewer->getGLContext();
1678     ObjectMap anObjects = aContext->getObjects();
1679
1680     GLViewer_Object* aLockedObject = 0;
1681     for( ObjectMap::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1682     {
1683         GLViewer_Rect* aRect = it.key()->getRect();
1684
1685         if( aRect->contains( point ) && it.key()->portContains( point ) )
1686         {
1687             aLockedObject = it.key();
1688             break;
1689         }
1690     }
1691
1692     myPullingObject->pull( point, aLockedObject );
1693 }
1694
1695 void GLViewer_ViewPort2d::finishPulling()
1696 {
1697     myIsPulling = false;
1698     myPullingObject->finishPulling();
1699     setCursor( *getDefaultCursor() );
1700 }
1701
1702 GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
1703 {
1704   GLViewer_Rect aRect;
1705
1706   GLdouble        modelMatrix[16], projMatrix[16];
1707   GLint           viewport[4];
1708
1709   GLdouble        objx1, objy1;
1710   GLdouble        objx2, objy2;
1711   GLdouble        objz;
1712
1713   glGetIntegerv (GL_VIEWPORT, viewport);
1714   glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1715   glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1716
1717   gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz );
1718   gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz );
1719   
1720   aRect.setLeft( objx1 );
1721   aRect.setTop( objy1 );
1722   aRect.setRight( objx2 );
1723   aRect.setBottom( objy2 );
1724
1725   return aRect;
1726 }
1727
1728 QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
1729 {
1730   QRect aRect;
1731
1732   GLdouble        modelMatrix[16], projMatrix[16];
1733   GLint           viewport[4];
1734
1735   GLdouble        winx1, winy1;
1736   GLdouble        winx2, winy2;
1737   GLdouble        winz;
1738
1739   glGetIntegerv (GL_VIEWPORT, viewport);
1740   glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1741   glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1742
1743   gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz );
1744   gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz );
1745   
1746   aRect.setLeft( (int)(winx1) );
1747   aRect.setTop( (int)(viewport[3] - winy1) );
1748   aRect.setRight( (int)(winx2) );
1749   aRect.setBottom( (int)(viewport[3] - winy2) );
1750
1751   return aRect;
1752 }
1753
1754 void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion )
1755 {
1756   GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
1757
1758   GLViewer_Object* anObj = aContext->getCurrentObject();
1759   if( anObj )
1760   {
1761     theText = anObj->getToolTipText();
1762     if( theText.isEmpty() )
1763       theText = anObj->getName();
1764
1765     QStringList aList;
1766     if( anObj->isTooTipHTML() )
1767       aList = QStringList::split( "<br>", theText );
1768     else
1769       aList = QStringList::split( "\n", theText );
1770
1771     if( !aList.isEmpty() )
1772     {
1773       int index = 0;
1774       int str_size = aList.first().length();
1775       for( int i = 1, size = aList.count(); i < size; i++ )
1776       {
1777         if( str_size < aList[i].length() )
1778         {
1779           index = i;
1780           str_size = aList[i].length();
1781         }
1782       }
1783       theFont = font();
1784       int cur_height = 24;
1785       QCursor* aCursor = QApplication::overrideCursor();
1786       if( aCursor )
1787       {
1788         const QBitmap* aBitmap = aCursor->bitmap();
1789         if( aBitmap )
1790           cur_height = aBitmap->height();
1791       }
1792       QFontMetrics fm( theFont );
1793       //temp
1794       theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height, fm.width( /*theText*/aList[index] ), fm.height()*aList.count() + 2 );
1795       theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 );
1796     }
1797   }
1798 }