]> SALOME platform Git repositories - modules/gui.git/blob - src/GLViewer/GLViewer_ViewPort2d.cxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/gui.git] / src / GLViewer / GLViewer_ViewPort2d.cxx
1 //  Copyright (C) 2005 OPEN CASCADE
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 //  Author : OPEN CASCADE
20 //
21
22 // File:      GLViewer_ViewPort2d.cxx
23 // Created:   November, 2004
24
25 /* GLViewer_ViewPort2d Source File */
26
27 //#include <GLViewerAfx.h>
28 #include "GLViewer_ViewPort2d.h"
29 #include "GLViewer_Viewer2d.h"
30 #include "GLViewer_ViewFrame.h"
31 #include "GLViewer_MimeSource.h"
32 #include "GLViewer_Context.h"
33 #include "GLViewer_Compass.h"
34 #include "GLViewer_Grid.h"
35
36 #include <QtxToolTip.h>
37
38 #include <qlayout.h>
39 #include <qevent.h>
40 #include <qrect.h>
41 #include <qpopupmenu.h>
42 #include <qtooltip.h>
43 #include <qapplication.h>
44 #include <qclipboard.h>
45 #include <qpainter.h>
46 #include <qbitmap.h>
47 #include <qlabel.h>
48
49 #define WIDTH       640
50 #define HEIGHT      480
51 #define MARGIN      100
52
53 #define GRID_XSIZE  100
54 #define GRID_YSIZE  100
55
56 int static aLastViewPostId = 0;
57
58 void rotate_point( float& theX, float& theY, float theAngle )
59 {
60     float aTempX = theX * cos(theAngle) - theY * sin(theAngle);
61     float aTempY = theX * sin(theAngle) + theY * cos(theAngle);
62     theX = aTempX;
63     theY = aTempY;
64 }
65
66 /*!
67   Constructor
68 */
69 GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame ) :
70        GLViewer_ViewPort( parent ),
71        myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ),
72        myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
73        myXPan( 0.0 ), myYPan( 0.0 ),
74        myIsMouseReleaseBlock( false )
75 {
76     if( theViewFrame == NULL )
77         myViewFrame = ( GLViewer_ViewFrame* )parent;
78     else
79         myViewFrame = theViewFrame;
80
81     myGrid = 0;
82     myCompass = 0;
83     myBorder = new GLViewer_Rect();
84
85     QBoxLayout* qbl = new QHBoxLayout( this );
86     myGLWidget = new GLViewer_Widget( this, 0 ) ;
87     qbl->addWidget( myGLWidget );
88     myGLWidget->setFocusProxy( this );
89     setMouseTracking( TRUE );
90
91     myIsDragProcess = noDrag;
92     //myCurDragMousePos = QPoint();
93     myCurDragPosX = NULL;
94     myCurDragPosY = NULL;
95
96     myIsPulling = false;
97
98     myViewPortId = aLastViewPostId;
99     aLastViewPostId++;
100
101     mypFirstPoint = NULL;
102     mypLastPoint = NULL;
103
104     myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
105     myObjectTip->setShowDelayTime( 60000 );
106     connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ),
107              this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );
108 //    myGLWidget->installEventFilter( myObjectTip );
109 }
110
111 /*!
112   Destructor
113 */
114 GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
115 {
116     if( myCompass )
117         delete myCompass;
118
119     if( myGrid )
120         delete myGrid;
121
122     delete myBorder;
123     delete myGLWidget;
124 }
125
126 /*!
127   SLOT: initializes drag process
128 */
129 void GLViewer_ViewPort2d::onStartDragObject( )
130 {
131     if( myIsDragProcess == noDrag )
132     {
133         myIsDragProcess = initDrag;
134         QCursor::setPos( (int)(*myCurDragPosX), (int)(*myCurDragPosY) );
135         //myCurDragMousePos = QPoint( 0, 0 );
136         delete myCurDragPosX;
137         delete myCurDragPosY;
138         myCurDragPosX = NULL;
139         myCurDragPosY = NULL;
140         return;
141     } 
142 }
143
144 /*!
145   SLOT: cuts object to clipboard
146 */
147 void GLViewer_ViewPort2d::onCutObject()
148
149     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
150     if( aMovingObject )    
151     {        
152         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
153         aMimeSource->setObject( aMovingObject );
154         
155         QClipboard *aClipboard = QApplication::clipboard();
156         aClipboard->clear();
157         aClipboard->setData( aMimeSource );
158
159         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->deleteObject( aMovingObject );
160     }*/
161     GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
162     int aObjNum = aContext->NbSelected();
163     if( aObjNum > 0 )
164     {
165         QValueList<GLViewer_Object*> aObjects;
166         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
167         aContext->InitSelected();
168         for( ; aContext->MoreSelected(); aContext->NextSelected() )
169             aObjects.append( aContext->SelectedObject() );
170
171         //aMimeSource->setObjects( aObjects ); ouv 6.05.04
172
173         QClipboard *aClipboard = QApplication::clipboard();
174         aClipboard->clear();
175         aClipboard->setData( aMimeSource );
176
177         for( int i = 0; i < aObjNum; i++ )
178             aContext->deleteObject( aObjects[i] );
179     }
180 }
181
182 /*!
183   SLOT: copies object to clipboard
184 */
185 void GLViewer_ViewPort2d::onCopyObject()
186 {
187     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
188     if( aMovingObject )    
189     {        
190         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
191         aMimeSource->setObject( aMovingObject );
192         
193         QClipboard *aClipboard = QApplication::clipboard();
194         aClipboard->clear();
195         aClipboard->setData( aMimeSource );
196     }
197     */
198     GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
199     int aObjNum = aContext->NbSelected();
200     if( aObjNum > 0 )
201     {
202         QValueList<GLViewer_Object*> aObjects;
203         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
204         aContext->InitSelected();
205         for( ; aContext->MoreSelected(); aContext->NextSelected() )
206             aObjects.append( aContext->SelectedObject() );
207
208         //aMimeSource->setObjects( aObjects ); ouv 6.05.04
209
210         QClipboard *aClipboard = QApplication::clipboard();
211         aClipboard->clear();
212         aClipboard->setData( aMimeSource );
213     }
214 }
215
216 /*!
217   SLOT: pastes object from clipboard
218 */
219 void GLViewer_ViewPort2d::onPasteObject()
220 {
221     /*QClipboard *aClipboard = QApplication::clipboard();
222     QMimeSource* aMimeSource = aClipboard->data();
223     if( aMimeSource->provides( "GLViewer_Object" ) )
224     {
225         const char* aType;
226         int i = 1;
227         QByteArray anArray;
228         do
229         {
230             aType = aMimeSource->format( i );
231             anArray = aMimeSource->encodedData( aType );
232             if( anArray.size() != 0 )
233                 break;
234             i++;
235         }
236         while( aType != 0 );
237         if( anArray.size() == 0 )
238             return;
239
240         GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
241         if( !aObject )
242             return;
243         
244         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
245     }
246     */
247     /* ouv 6.05.04
248     QClipboard *aClipboard = QApplication::clipboard();
249
250     QMimeSource* aMimeSource = aClipboard->data();
251     if( aMimeSource->provides( "GLViewer_Objects" ) )
252     {
253         QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" );
254         QValueList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
255         if( aObjects.empty() )
256             return;
257         GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
258         for( int i = 0; i < aObjects.count(); i++ )
259             aContext->insertObject( aObjects[i], true );
260     }
261     */
262 }
263
264 /*!
265   SLOT: called when object is being dragged
266 */
267 void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
268 {
269   //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl;
270   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
271   GLViewer_Context* aContext = aViewer->getGLContext();
272   GLViewer_Object* anObject = aContext->getCurrentObject();
273   
274   if( !aContext )
275     return;
276
277   float aX = e->pos().x();
278   float anY = e->pos().y();
279   aViewer->transPoint( aX, anY );
280     
281   if( myCurDragPosX == NULL && myCurDragPosY == NULL )
282   {
283     myCurDragPosX = new float(aX);
284     myCurDragPosY = new float(anY);
285     return;
286   }
287
288   //QPoint aNewPos = e->pos();
289   //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
290   
291   if( anObject && (e->state() & LeftButton ) )
292   {
293     if( aContext->isSelected( anObject ) )
294     {
295       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
296       {
297         GLViewer_Object* aMovingObject = aContext->SelectedObject();
298         if( aMovingObject )
299           aMovingObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
300       }
301     }
302     else
303       anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
304   }
305   else if( aContext->NbSelected() && (e->state() & MidButton ) )
306     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
307         (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
308   
309   delete myCurDragPosX;
310   delete myCurDragPosY;
311   myCurDragPosX = new float(aX);
312   myCurDragPosY = new float(anY);    
313
314   myGLWidget->updateGL();
315 }
316
317 /*!
318     Emits 'mouseEvent' signal. [ virtual protected ]
319 */
320 void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e )
321 {    
322     emit vpMouseEvent( e );
323     
324     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();   
325     GLViewer_Context* aContext = aViewer->getGLContext();
326
327     GLViewer_Object* anObject = NULL;
328     if( aContext )
329         anObject = aContext->getCurrentObject();
330     
331     bool accel = e->state() & GLViewer_ViewTransformer::accelKey();
332     if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) ||
333         ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton )  )
334     {       
335         myIsDragProcess = inDrag;
336     }
337 }
338
339 /*!
340     Emits 'mouseEvent' signal. [ virtual protected ]
341 */
342 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
343 {
344     emit vpMouseEvent( e );
345     
346     if( myIsDragProcess == inDrag )
347         onDragObject( e );
348
349     /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();   
350     GLViewer_Context* aContext = aViewer->getGLContext();
351
352     GLViewer_Object* anObj = aContext->getCurrentObject();
353     if( anObj && aContext->currentObjectIsChanged() )
354     {
355         //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::add}" << endl;
356         //QToolTip::remove( myGLWidget );
357         QRect* aRect = (aViewer->getWinObjectRect(anObj));
358         //QToolTip::add( myGLWidget, *aRect, anObj->getToolTipText() );
359         myGLWidget->addToolTip( anObj->getToolTipText(), *aRect );
360     }
361     if(!anObj)
362     {
363         //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::remove}" << endl;
364         //QRect* aRect = (aViewer->getWinObjectRect(anObj));
365         //QToolTip::remove( myGLWidget, *aRect );
366         myGLWidget->removeToolTip();
367     }*/
368 }
369
370 /*!
371     Emits 'mouseEvent' signal. [ virtual protected ]
372 */
373 void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
374 {    
375     if ( myIsMouseReleaseBlock )
376     {
377       // skip mouse release after double click
378       myIsMouseReleaseBlock = false;
379       return;
380     }
381
382     /* show popup menu */
383     if ( e->button() == Qt::RightButton )
384     {
385         //QPopupMenu* popup = createPopup();
386         //if ( popup && popup->count() )
387         //    popup->exec( QCursor::pos() );
388         //destroyPopup( /*popup*/ );
389     }
390     emit vpMouseEvent( e );
391     
392     if( myIsDragProcess == inDrag )
393     {
394       bool isAnyMoved = false;
395       GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
396       GLViewer_Context* aContext = aViewer->getGLContext();
397       GLViewer_Object* aMovingObject;
398       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
399       {
400         aMovingObject = aContext->SelectedObject();
401         if( aMovingObject )
402           isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
403       }
404       
405       aMovingObject = aContext->getCurrentObject();
406       if( aMovingObject )
407         isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
408       
409       myIsDragProcess = noDrag;
410       //myCurDragMousePos.setX( 0 );
411       //myCurDragMousePos.setY( 0 );
412       delete myCurDragPosX;
413       delete myCurDragPosY;
414       myCurDragPosX = NULL;
415       myCurDragPosY = NULL;
416
417       if( isAnyMoved )
418       {
419         emit objectMoved();
420         aViewer->updateBorders();
421       }
422     }
423 }
424
425 /*!
426   Custom mouse double click event handler
427 */
428 void GLViewer_ViewPort2d::mouseDoubleClickEvent( QMouseEvent * e )
429 {
430   //redefined to block mouse release after mouse double click
431   myIsMouseReleaseBlock = true;
432   // invoke base implementation
433   GLViewer_ViewPort::mouseDoubleClickEvent( e );
434 }
435
436 /*!
437   Creates or deletes compass
438   \param on - if it is true, then to create
439 */
440 void GLViewer_ViewPort2d::turnCompass( GLboolean on )
441 {
442     if( on )
443         myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
444     else if( myCompass )
445         delete myCompass;
446 }
447
448 /*!
449   Creates or deletes grid
450   \param on - if it is true, then to create
451 */
452 void GLViewer_ViewPort2d::turnGrid( GLboolean on )
453 {
454     if( on )
455     {
456         myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT,
457                                     2*WIDTH, 2*HEIGHT, 
458                                     GRID_XSIZE, GRID_YSIZE,
459                                     myXPan, myYPan,
460                                     myXScale, myYScale );
461     }
462     else if( myGrid )
463         delete myGrid;
464 }
465
466 /*!
467   Changes grid color
468   \param gridColor - new grid color
469   \param axisColor - new axis color
470 */
471 void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor )
472 {
473     if( myGrid )
474     {
475         myGrid->setGridColor( ( GLfloat )gridColor.red() / 255,
476                   ( GLfloat )gridColor.green() / 255,
477                   ( GLfloat )gridColor.blue() / 255 );
478         myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255,
479                   ( GLfloat )axisColor.green() / 255,
480                   ( GLfloat )axisColor.blue() / 255 );
481     }
482 }
483
484 /*!
485   Changes background color
486   \param color - new background color
487 */
488 void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
489 {
490     GLViewer_ViewPort::setBackgroundColor( color );
491     myGLWidget->makeCurrent();
492     glClearColor( ( GLfloat )color.red() / 255,
493             ( GLfloat )color.green() / 255,
494             ( GLfloat )color.blue() / 255, 1.0 );
495     myGLWidget->repaint();
496 }
497
498 /*!
499   \return background color
500 */
501 QColor GLViewer_ViewPort2d::backgroundColor() const
502 {
503     return GLViewer_ViewPort::backgroundColor();
504 }
505
506 /*!
507   Resize view
508 */
509 void GLViewer_ViewPort2d::initResize( int x, int y )
510 {
511     float xa, xb, ya, yb;
512     xa = myBorder->left() - myMargin;
513     xb = myBorder->right() + myMargin;
514     ya = myBorder->top() - myMargin;
515     yb = myBorder->bottom() + myMargin;
516
517     GLfloat zoom, xzoom, yzoom;
518     GLfloat w = x;
519     GLfloat h = y;
520     bool max = FALSE;
521
522     xzoom = (GLfloat)x / myWidth; 
523     yzoom = (GLfloat)y / myHeight; 
524
525     if ( ( xzoom < yzoom ) && ( xzoom < 1 ) ) 
526         zoom = xzoom; 
527     else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) ) 
528         zoom = yzoom; 
529     else 
530     { 
531         max = TRUE; 
532         zoom = xzoom > yzoom ? xzoom : yzoom; 
533     } 
534
535     if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
536              ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || 
537              ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
538              ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) ) 
539         zoom = 1; 
540
541     if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
542             ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || 
543             ( ( myYPan + h/2 ) < yb * myYScale * zoom ) || 
544             ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) 
545         zoom = 1; 
546  
547     myWidth = x;
548     myHeight = y; 
549
550     myXScale *= zoom; 
551     myYScale = myXScale; 
552
553     if ( myGrid )
554         myGrid->setResize( 2*x, 2*y, zoom );
555
556     myGLWidget->setScale( myXScale, myYScale, 1.0 );
557 }
558
559 /*!
560   Custom paint event handler
561 */
562 void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
563 {
564     //cout << "GLViewer_ViewPort2d::paintEvent" << endl;
565     myGLWidget->updateGL();
566     GLViewer_ViewPort::paintEvent( e );
567 }
568
569 /*!
570   Custom resize event handler
571 */
572 void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e )
573 {
574     //cout << "GLViewer_ViewPort2d::resizeEvent" << endl;
575     GLViewer_ViewPort::resizeEvent( e );
576 }
577
578 /*!
579   Resets view to start state
580 */
581 void GLViewer_ViewPort2d::reset()
582 {
583     //cout << "GLViewer_ViewPort2d::reset" << endl;
584
585     GLint val[4]; 
586     GLint vpWidth, vpHeight; 
587
588     myGLWidget->makeCurrent();
589     glGetIntegerv( GL_VIEWPORT, val );
590     vpWidth = val[2]; 
591     vpHeight = val[3]; 
592
593     GLint w = myGLWidget->getWidth();
594     GLint h = myGLWidget->getHeight();
595     GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ? 
596                  vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h; 
597
598     if( myGrid )
599     {
600         myGrid->setPan( 0.0, 0.0 );
601         myGrid->setZoom( zoom / myXScale );
602     }
603
604     myXPan = 0.0;
605     myYPan = 0.0;
606     myXScale = zoom;
607     myYScale = zoom;
608
609     myGLWidget->setPan( myXPan, myYPan, 0.0 );
610     myGLWidget->setScale( myXScale, myYScale, 1.0 );
611     myGLWidget->setRotationAngle( 0.0 );
612     myGLWidget->setRotation( 0.0, 0.0, 0.0, 1.0 );
613     myGLWidget->updateGL();
614 }
615
616 /*!
617   Sets offset to view
618   \param dx - X offset
619   \param dy - Y offset
620 */
621 void GLViewer_ViewPort2d::pan( int dx, int dy )
622 {
623     //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl;
624
625     /*myXPan += dx / myXScale;
626     myYPan += dy / myYScale;
627
628     float ra, rx, ry, rz;
629     myGLWidget->getRotation( ra, rx, ry, rz );
630     GLfloat angle = ra * PI / 180.;
631
632     if( myGrid )
633         myGrid->setPan( myXPan*cos(angle) + myYPan*sin(angle),
634                         -myXPan*sin(angle) + myYPan*cos(angle) );
635
636     */
637     float ra, rx, ry, rz;
638     myGLWidget->getRotation( ra, rx, ry, rz );
639     GLfloat angle = ra * PI / 180.;
640
641     myXPan += (dx*cos(angle) + dy*sin(angle)) / myXScale;
642     myYPan += (-dx*sin(angle) + dy*cos(angle)) / myXScale;
643
644     if( myGrid )
645         myGrid->setPan( myXPan, myYPan );
646
647     myGLWidget->setPan( myXPan, myYPan, 0.0 );
648     myGLWidget->setScale( myXScale, myYScale, 1.0 );
649     myGLWidget->updateGL();
650 }
651
652 /*!
653   Sets view center in global coords
654   \param x, y - global co-ordinates of center
655 */
656 void GLViewer_ViewPort2d::setCenter( int x, int y )
657 {
658     //cout << "GLViewer_ViewPort2d::setCenter" << endl;
659
660     GLint val[4]; 
661     GLint vpWidth, vpHeight; 
662
663     myGLWidget->makeCurrent();
664     glGetIntegerv( GL_VIEWPORT, val );
665     vpWidth = val[2]; 
666     vpHeight = val[3]; 
667
668     myXPan -= ( x - vpWidth/2 ) / myXScale;
669     myYPan += ( y - vpHeight/2 ) / myYScale;
670
671     if( myGrid )
672     {
673         myGrid->setPan( myXPan, myYPan );
674         myGrid->setZoom( myXOldScale / myXScale );
675     }
676
677     myXScale = myXOldScale;
678     myYScale = myYOldScale;
679
680     myGLWidget->setPan( myXPan, myYPan, 0.0 );
681     myGLWidget->setScale( myXScale, myYScale, 1.0 );
682     myGLWidget->updateGL();
683 }
684
685 /*!
686   Process zoming transformation with mouse tracking from ( x0, y0 ) to ( x1, y1 )
687 */
688 void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
689 {
690     //cout << "GLViewer_ViewPort2d::zoom" << endl;
691   
692     float dx, dy, zm;
693     dx = x - x0;
694     dy = y - y0;
695
696     if ( dx == 0. && dy == 0. )
697         return;
698
699     zm = sqrt(dx * dx + dy * dy) / 100. + 1; 
700     zm = (dx > 0.) ?  zm : 1. / zm; 
701
702     //backup values
703     float bX = myXScale;
704     float bY = myYScale;
705     myXScale *= zm; 
706     myYScale *= zm; 
707
708     if( myGrid )
709     {
710         if( myGrid->setZoom( zm ) )
711         {
712             myGLWidget->setPan( myXPan, myYPan, 0.0 );
713             myGLWidget->setScale( myXScale, myYScale, 1.0 );
714             myGLWidget->updateGL();
715         }
716         else
717         {// undo
718             myXScale = bX;
719             myYScale = bY;
720         } 
721     }
722     else
723     {
724         myGLWidget->setPan( myXPan, myYPan, 0.0 );
725         myGLWidget->setScale( myXScale, myYScale, 1.0 );
726         myGLWidget->updateGL();
727     }
728 }
729
730 /*!
731   Transforms view by rectangle
732   \param rect - rectangle
733 */
734 void GLViewer_ViewPort2d::fitRect( const QRect& rect )
735 {
736     float x0, x1, y0, y1;
737     float dx, dy, zm, centerX, centerY; 
738
739     GLint val[4]; 
740     GLint vpWidth, vpHeight; 
741
742     myGLWidget->makeCurrent();
743     glGetIntegerv( GL_VIEWPORT, val );
744     vpWidth = val[2]; 
745     vpHeight = val[3]; 
746
747     x0 = rect.left();
748     x1 = rect.right();
749     y0 = rect.top();
750     y1 = rect.bottom();
751
752     dx = fabs( x1 - x0 ); 
753     dy = fabs( y1 - y0 ); 
754     centerX = ( x0 + x1 ) / 2.; 
755     centerY = ( y0 + y1 ) / 2.; 
756
757     if ( dx == 0. || dy == 0. )
758         return;
759
760     zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; 
761
762     float aDX = ( vpWidth / 2. - centerX ) / myXScale;
763     float aDY = ( vpHeight / 2. - centerY ) / myYScale;
764
765     float ra, rx, ry, rz;
766     myGLWidget->getRotation( ra, rx, ry, rz );
767     GLfloat angle = ra * PI / 180.;
768
769     myXPan += (aDX*cos(angle) - aDY*sin(angle));
770     myYPan -= (aDX*sin(angle) + aDY*cos(angle));
771
772     if( myGrid )
773         myGrid->setPan( myXPan, myYPan );
774
775     myXScale *= zm;
776     myYScale = myXScale;
777
778     if( myGrid )
779         myGrid->setZoom( zm );
780
781     myGLWidget->setPan( myXPan, myYPan, 0.0 );
782     myGLWidget->setScale( myXScale, myYScale, 1.0 );
783     myGLWidget->updateGL();
784 }
785
786 /*!
787   Transforms view by selection
788 */
789 void GLViewer_ViewPort2d::fitSelect()
790 {
791   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
792   GLViewer_Context* aContext = aViewer->getGLContext();
793   if( !aContext )
794     return;
795   
796   QRect aSelRect;
797   for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
798     aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() ));
799
800   if( aSelRect.isValid() )
801   {
802     aSelRect.setTop( aSelRect.top() - SELECTION_RECT_GAP );
803     aSelRect.setBottom( aSelRect.bottom() + SELECTION_RECT_GAP );
804     aSelRect.setLeft( aSelRect.left() - SELECTION_RECT_GAP );
805     aSelRect.setRight( aSelRect.right() + SELECTION_RECT_GAP );
806     fitRect( aSelRect );
807   }
808 }
809
810 /*!
811   Transform view by view borders
812   \param keepScale - if it is true, zoom does not change
813 */
814 void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
815 {
816     //cout << "GLViewer_ViewPort2d::fitAll" << endl;
817
818     float xa, xb, ya, yb;
819     float dx, dy, zm;
820     float xScale, yScale;
821
822     myMargin = QMAX( myBorder->width(), myBorder->height() ) / 5;
823
824     xa = myBorder->left() - myMargin;
825     xb = myBorder->right() + myMargin;
826     ya = myBorder->bottom() - myMargin;
827     yb = myBorder->top() + myMargin;
828
829     float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb };
830
831     float ra, rx, ry, rz;
832     myGLWidget->getRotation( ra, rx, ry, rz );
833     float angle = ra * PI / 180.;
834
835     int i;
836     for( i = 0; i < 7; i = i + 2 )
837         rotate_point( aPoints[i], aPoints[i+1], angle );
838
839     float aBorders[4] = { aPoints[0], aPoints[0], aPoints[1], aPoints[1] };
840
841     for( i = 2; i < 7; i = i + 2 )
842     {
843         if( aBorders[0] < aPoints[i] )
844             aBorders[0] = aPoints[i];
845         if( aBorders[1] > aPoints[i] )
846             aBorders[1] = aPoints[i];
847
848         if( aBorders[2] < aPoints[i+1] )
849             aBorders[2] = aPoints[i+1];
850         if( aBorders[3] > aPoints[i+1] )
851             aBorders[3] = aPoints[i+1];
852     }
853
854     GLint val[4];
855     GLint vpWidth, vpHeight;
856
857     myGLWidget->makeCurrent();
858     glGetIntegerv( GL_VIEWPORT, val );
859     vpWidth = val[2];
860     vpHeight = val[3];
861
862     dx = fabs( aBorders[1] - aBorders[0] );
863     dy = fabs( aBorders[3] - aBorders[2] );
864
865     myXPan = -( aBorders[0] + aBorders[1] ) / 2; 
866     myYPan = -( aBorders[2] + aBorders[3] ) / 2;
867     
868
869     if( keepScale )
870     {
871         myXOldScale = myXScale;
872         myYOldScale = myYScale;
873     }
874
875     xScale = myXScale;
876     yScale = myYScale;
877     if( dx && dy )
878         zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; 
879     else
880         zm = 1.0;
881     myXScale = zm; 
882     myYScale = zm;    
883     
884
885     if( myGrid )
886     {
887         myGrid->setPan( myXPan, myYPan );
888         if( dx > dy )
889             myGrid->setZoom(  zm / xScale );
890         else  
891             myGrid->setZoom( zm / yScale );
892     }
893
894     myGLWidget->setPan( myXPan, myYPan, 0.0 );
895     myGLWidget->setScale( myXScale, myYScale, 1.0 );
896     myGLWidget->updateGL();
897
898     if( keepScale )
899         emit vpUpdateValues();
900 }
901
902 /*!
903   Begins rotation
904   \param x, y - start point
905 */
906 void GLViewer_ViewPort2d::startRotation( int x, int y )
907 {
908     myGLWidget->setRotationStart( x, y, 1.0 );
909 }
910
911 /*!
912   Performs rotation
913   \param intX, intY - current point
914 */
915 void GLViewer_ViewPort2d::rotate( int intX, int intY )
916 {
917     GLint val[4];
918     GLint vpWidth, vpHeight;
919
920     myGLWidget->makeCurrent();
921     glGetIntegerv( GL_VIEWPORT, val );
922     vpWidth = val[2];
923     vpHeight = val[3];
924
925     float x = intX, y = intY;
926     float x0 = vpWidth/2;
927     float y0 = vpHeight/2;
928
929     float xs, ys, zs, dx, dy;
930     myGLWidget->getRotationStart( xs, ys, zs );
931
932     xs = xs - x0;
933     x = x - x0;
934     dx = x - xs;
935     ys = y0 - ys;
936     y = y0 - y;
937     dy = y - ys;
938
939     float l1 = pow( double( xs*xs + ys*ys ), 0.5 );
940     float l2 = pow( double( x*x + y*y ), 0.5 );
941     float l = pow( double( dx*dx + dy*dy ), 0.5 );
942
943     double mult = xs * y - x * ys;
944     short sign;
945     if( mult > 0 ) sign = 1;
946     else if( mult < 0 ) sign = -1;
947     else sign = 0;
948
949     float anglePrev = myGLWidget->getRotationAngle();
950     float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI;
951     float angle = anglePrev + angleNew;
952
953     // GLfloat anAngle = angle * PI / 180.; unused
954
955     float ra, rx, ry, rz;
956     myGLWidget->getRotation( ra, rx, ry, rz );
957     myGLWidget->setRotation( angle, rx, ry, rz );
958     myGLWidget->updateGL();
959 }
960
961 /*!
962   Finishes rotation
963 */
964 void GLViewer_ViewPort2d::endRotation()
965 {
966     float ra, rx, ry, rz;
967     myGLWidget->getRotation( ra, rx, ry, rz );
968     myGLWidget->setRotationAngle( ra );
969 }
970
971 /*!
972   Draws compass
973 */
974 void GLViewer_ViewPort2d::drawCompass()
975 {
976     if( !myCompass->getVisible() )
977         return;
978
979     GLfloat xScale, yScale, xPan, yPan;
980
981     int xPos = getWidth();
982     int yPos = getHeight();
983
984     int cPos = myCompass->getPos();
985     int cSize = myCompass->getSize();
986     QColor cCol = myCompass->getColor();
987     int cWidthTop = myCompass->getArrowWidthTop();
988     int cWidthBot = myCompass->getArrowWidthBottom();
989     int cHeightTop = myCompass->getArrowHeightTop();
990     int cHeightBot = myCompass->getArrowHeightBottom();
991
992     GLfloat colorR = (cCol.red())/255;
993     GLfloat colorG = (cCol.green())/255;
994     GLfloat colorB = (cCol.blue())/255;
995
996     float delX = cSize * 0.5;
997     float delY = cSize * 0.5;
998
999     getScale( xScale, yScale );
1000     getPan( xPan, yPan);
1001
1002     float centerX = (xPos/2 - delX - cSize)/xScale;
1003     float centerY = (yPos/2 - delY - cSize)/yScale;
1004     
1005     switch ( cPos )
1006     {
1007     case GLViewer_Compass::TopLeft:
1008             centerX = -centerX;
1009             break;
1010         case GLViewer_Compass::BottomLeft:
1011             centerX = -centerX;
1012             centerY = -centerY;
1013             break;
1014         case GLViewer_Compass::BottomRight:
1015             centerY = -centerY;
1016             break;
1017         default: break;
1018     }
1019     
1020     float ra, rx, ry, rz;
1021     myGLWidget->getRotation( ra, rx, ry, rz );
1022     GLfloat angle = ra * PI / 180.;
1023     GLfloat /*r = 0.0,*/ x = 0.0 , y = 0.0;
1024
1025     rotate_point( centerX, centerY, -angle );
1026
1027     centerX -= xPan;
1028     centerY -= yPan;
1029
1030     glColor3f( colorR, colorG, colorB );
1031     glBegin( GL_POLYGON );     
1032     //arrow
1033         x = centerX;                      y = centerY + cSize / yScale;    
1034         glVertex2f( x, y );
1035         //point #2
1036         x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1037         glVertex2f( x, y );
1038         //point #3    
1039         x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1040         glVertex2f( x, y );
1041         //point #4
1042         x = centerX + cWidthBot / xScale; y = centerY - cSize/yScale;
1043         glVertex2f( x, y );
1044         //point #5
1045         x = centerX;                      y = centerY - (cSize - cHeightBot) / yScale ;
1046         glVertex2f( x, y ); 
1047         //point #6
1048         x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale;
1049         glVertex2f( x, y );
1050         //point #7
1051         x = centerX - cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1052         glVertex2f( x, y );
1053         //point #8
1054         x = centerX - cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1055         glVertex2f( x, y );
1056     glEnd();
1057     glLineWidth( 2.0 );
1058     glEnable( GL_LINE_SMOOTH );
1059     glBegin(GL_LINE_LOOP);
1060     //circle
1061         float aCircAngle = 0;
1062         for ( int i = 0; i < 20 * SEGMENTS + 1; i++ )
1063         {
1064             x = centerX + cos(aCircAngle) * cSize / xScale;
1065             y = centerY + sin(aCircAngle) * cSize / yScale;
1066             glVertex2f( x, y );    
1067             aCircAngle += float( STEP ) / 2;
1068         }        
1069     glEnd(); 
1070     
1071     GLdouble        modelMatrix[16], projMatrix[16];
1072     GLint           viewport[4];
1073     GLdouble        winxN, winyN, winz;
1074     GLdouble        winxE, winyE;
1075     GLdouble        winxS, winyS;
1076     GLdouble        winxW, winyW;
1077     GLuint          aTextList;    
1078
1079     GLViewer_TexFont* aFont = myCompass->getFont();
1080     float widN = (float)aFont->getStringWidth( "N" );
1081     float widW = (float)aFont->getStringWidth( "W" );
1082     float widS = (float)aFont->getStringWidth( "S" );
1083     float widE = (float)aFont->getStringWidth( "E" );
1084     float heightL = (float)aFont->getStringHeight();
1085
1086     float xGapN = - widN/2 *( 1.0 + sin(angle) );
1087     float xGapS = - widS/2 *( 1.0 - sin(angle) );
1088     float xGapW = - widW/2 *( 1.0 + cos(angle) );
1089     float xGapE = - widE/2 *( 1.0 - cos(angle) );
1090
1091     float yGapN = - heightL/2 *( 1.0 - cos(angle) ) * 0.75;
1092     float yGapS = - heightL/2 *( 1.0 + cos(angle) ) * 0.75;
1093     float yGapW = - heightL/2 *( 1.0 + sin(angle) ) * 0.75;
1094     float yGapE = - heightL/2 *( 1.0 - sin(angle) ) * 0.75;
1095
1096     glGetIntegerv (GL_VIEWPORT, viewport);
1097     glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1098     glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1099     
1100     gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz);
1101     gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz);
1102     gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz);
1103     gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz);
1104
1105     glColor3f( 1.0, 1.0, 1.0 );    
1106
1107     aTextList = glGenLists( 1 );
1108     glNewList( aTextList, GL_COMPILE );
1109
1110     glMatrixMode(GL_PROJECTION);
1111     glPushMatrix();
1112     glLoadIdentity();
1113     glOrtho(0,viewport[2],0,viewport[3],-100,100);
1114     glMatrixMode(GL_MODELVIEW);
1115     glPushMatrix();
1116     glLoadIdentity();    
1117
1118     aFont->drawString( "N", winxN + xGapN, winyN + yGapN );
1119     aFont->drawString( "E", winxE + xGapE, winyE + yGapE );
1120     aFont->drawString( "S", winxS + xGapS, winyS + yGapS );
1121     aFont->drawString( "W", winxW + xGapW, winyW + yGapW );
1122
1123     glMatrixMode(GL_PROJECTION);
1124     glPopMatrix();
1125     glMatrixMode(GL_MODELVIEW);
1126     glPopMatrix();
1127
1128     glEndList();
1129
1130     if ( aTextList != -1 ) 
1131         glCallList( aTextList );
1132 }
1133
1134 /*!
1135   \return blocking status for current started operations
1136 */
1137 BlockStatus GLViewer_ViewPort2d::currentBlock()
1138 {
1139     if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL)
1140         return BlockStatus(BS_Highlighting | BS_Selection);
1141     
1142     if( mypFirstPoint && mypLastPoint )
1143         return BlockStatus(BS_Highlighting | BS_Selection);
1144     
1145     return BS_NoBlock;
1146 }
1147
1148 /*!
1149   Initializes rectangle selection
1150   \param x, y - start point
1151 */
1152 void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
1153 {
1154     if( !mypFirstPoint && !mypLastPoint )
1155     {
1156         mypFirstPoint = new QPoint( x, y );
1157         mypLastPoint = new QPoint( x, y );
1158     }
1159 }
1160
1161 /*!
1162   Draws rectangle selection
1163   \param x, y - current point
1164 */
1165 void GLViewer_ViewPort2d::drawSelectByRect( int x, int y )
1166 {
1167     if( mypFirstPoint && mypLastPoint )
1168     {
1169
1170         QPainter p( getPaintDevice() );
1171         p.setPen( Qt::white );
1172         p.setRasterOp( Qt::XorROP );
1173
1174         p.drawRect( selectionRect() );    /* erase */
1175
1176         mypLastPoint->setX( x );
1177         mypLastPoint->setY( y );
1178         
1179         p.drawRect( selectionRect() );    /* draw */
1180     }
1181
1182 }
1183
1184 /*!
1185   Finishes rectangle selection
1186 */
1187 void GLViewer_ViewPort2d::finishSelectByRect()
1188 {
1189     if( mypFirstPoint && mypLastPoint )
1190     {
1191
1192         QPainter p( getPaintDevice() );
1193         p.setPen( Qt::white );
1194         p.setRasterOp( Qt::XorROP );
1195
1196         p.drawRect( selectionRect() );    /* erase */
1197
1198         delete mypFirstPoint;
1199         delete mypLastPoint;
1200
1201         mypFirstPoint = NULL;
1202         mypLastPoint = NULL;
1203     }
1204 }
1205
1206 /*!
1207   \return rectangle selection
1208 */
1209 QRect GLViewer_ViewPort2d::selectionRect()
1210 {
1211     QRect aRect;
1212     if( mypFirstPoint && mypLastPoint )
1213     {
1214         aRect.setLeft( QMIN( mypFirstPoint->x(), mypLastPoint->x() ) );
1215         aRect.setTop( QMIN( mypFirstPoint->y(), mypLastPoint->y() ) );
1216         aRect.setRight( QMAX( mypFirstPoint->x(), mypLastPoint->x() ) );
1217         aRect.setBottom( QMAX( mypFirstPoint->y(), mypLastPoint->y() ) );
1218     }
1219
1220     return aRect;
1221 }
1222
1223 /*!
1224 */
1225 bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
1226 {
1227     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1228     GLViewer_Context* aContext = aViewer->getGLContext();
1229     ObjList anObjects = aContext->getObjects();
1230
1231     for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1232     {
1233         GLViewer_Object* anObject = *it;
1234         GLViewer_Rect aRect = anObject->getPullingRect();
1235
1236         if( aRect.contains( point ) && anObject->startPulling( point ) )
1237         {
1238             myIsPulling = true;
1239             myPullingObject = anObject;
1240             setCursor( *getHandCursor() );
1241             return true;
1242         }
1243     }
1244
1245     return false;
1246 }
1247
1248 /*!
1249 */
1250 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
1251 {
1252     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1253     GLViewer_Context* aContext = aViewer->getGLContext();
1254     ObjList anObjects = aContext->getObjects();
1255
1256     GLViewer_Object* aLockedObject = 0;
1257     for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1258     {
1259         GLViewer_Object* anObject = *it;
1260         if( !anObject->getVisible() )
1261             continue;
1262
1263         GLViewer_Rect aRect = anObject->getPullingRect();
1264
1265         if( aRect.contains( point ) && anObject->portContains( point ) )
1266         {
1267             aLockedObject = anObject;
1268             break;
1269         }
1270     }
1271
1272     myPullingObject->pull( point, aLockedObject );
1273 }
1274
1275 /*!
1276 */
1277 void GLViewer_ViewPort2d::finishPulling()
1278 {
1279     myIsPulling = false;
1280     myPullingObject->finishPulling();
1281     setCursor( *getDefaultCursor() );
1282 }
1283
1284 /*!
1285   Convert rectangle in window co-ordinates to GL co-ordinates
1286   \return converted rectangle
1287 */
1288 GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
1289 {
1290   GLViewer_Rect aRect;
1291
1292   GLdouble        modelMatrix[16], projMatrix[16];
1293   GLint           viewport[4];
1294
1295   GLdouble        objx1, objy1;
1296   GLdouble        objx2, objy2;
1297   GLdouble        objz;
1298
1299   glGetIntegerv (GL_VIEWPORT, viewport);
1300   glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1301   glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1302
1303   gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz );
1304   gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz );
1305   
1306   aRect.setLeft( objx1 );
1307   aRect.setTop( objy1 );
1308   aRect.setRight( objx2 );
1309   aRect.setBottom( objy2 );
1310
1311   return aRect;
1312 }
1313
1314 /*!
1315   Convert rectangle in GL co-ordinates to window co-ordinates
1316   \return converted rectangle
1317 */
1318 QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
1319 {
1320   QRect aRect;
1321
1322   GLdouble        modelMatrix[16], projMatrix[16];
1323   GLint           viewport[4];
1324
1325   GLdouble        winx1, winy1;
1326   GLdouble        winx2, winy2;
1327   GLdouble        winz;
1328
1329   glGetIntegerv (GL_VIEWPORT, viewport);
1330   glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1331   glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1332
1333   gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz );
1334   gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz );
1335   
1336   aRect.setLeft( (int)winx1 );
1337   aRect.setTop( viewport[3] - (int)winy1 );
1338   aRect.setRight( (int)winx2 );
1339   aRect.setBottom( viewport[3] - (int)winy2 );
1340
1341   return aRect;
1342 }
1343
1344 /*!
1345   SLOT: called when tooltip should be shown
1346 */
1347 void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion )
1348 {
1349   GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
1350
1351   GLViewer_Object* anObj = aContext->getCurrentObject();
1352   if( anObj )
1353   {
1354     theText = anObj->getToolTipText();
1355     if( theText.isEmpty() )
1356       theText = anObj->getName();
1357
1358     QStringList aList;
1359     if( anObj->isTooTipHTML() )
1360       aList = QStringList::split( "<br>", theText );
1361     else
1362       aList = QStringList::split( "\n", theText );
1363
1364     if( !aList.isEmpty() )
1365     {
1366       int index = 0;
1367       int str_size = aList.first().length();
1368       for( int i = 1, size = aList.count(); i < size; i++ )
1369       {
1370         if ( str_size < (int)aList[i].length() )
1371         {
1372           index = i;
1373           str_size = aList[i].length();
1374         }
1375       }
1376       theFont = font();
1377       int cur_height = 24;
1378       QCursor* aCursor = QApplication::overrideCursor();
1379       if( aCursor )
1380       {
1381         const QBitmap* aBitmap = aCursor->bitmap();
1382         if( aBitmap )
1383           cur_height = aBitmap->height();
1384       }
1385
1386       //temp
1387       QSize aSize = QLabel( theText, 0 ).sizeHint();
1388       theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height,
1389                           aSize.width(), aSize.height() );
1390       theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 );
1391     }
1392   }
1393 }