]> SALOME platform Git repositories - modules/gui.git/blob - src/GLViewer/GLViewer_Viewer2d.cxx
Salome HOME
d801cb6425c65a1d3e9bba79a482e0cc953fa6a9
[modules/gui.git] / src / GLViewer / GLViewer_Viewer2d.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  Author : OPEN CASCADE
23 // File:      GLViewer_Viewer2d.cxx
24 // Created:   November, 2004
25 //#include <GLViewerAfx.h>
26 //
27 #include "GLViewer_Viewer2d.h"
28 #include "GLViewer_Object.h"
29 #include "GLViewer_ViewFrame.h"
30 #include "GLViewer_BaseObjects.h"
31 #include "GLViewer_CoordSystem.h"
32 #include "GLViewer_Context.h"
33 #include "GLViewer_Drawer.h"
34 #include "GLViewer_Selector2d.h"
35 #include "GLViewer_ViewPort2d.h"
36
37 #include "SUIT_Desktop.h"
38 #include "SUIT_ViewWindow.h"
39 #include "SUIT_ViewManager.h"
40
41 #include <QMenu>
42 #include <QRect>
43 #include <QFile>
44 #include <QPolygon>
45 #include <QMouseEvent>
46 #include <QColorDialog>
47
48 /*!
49   Constructor
50   \param title - viewer title
51 */
52 GLViewer_Viewer2d::GLViewer_Viewer2d( const QString& title) :
53 GLViewer_Viewer( title )
54 {
55   myGLContext = new GLViewer_Context( this );
56
57   createSelector();
58
59   mySelMode = GLViewer_Viewer::Multiple;
60
61   myDrawers.clear();
62 }
63
64 /*!
65   Destructor
66 */
67 GLViewer_Viewer2d::~GLViewer_Viewer2d()
68 {    
69     //myGLSketcher = 0;
70     //delete myGLSketcher;
71   GLViewer_TexFont::clearTextBases();
72 }
73
74 /*!Create new instance of view window on desktop \a theDesktop.
75  *\retval SUIT_ViewWindow* - created view window pointer.
76  */
77 SUIT_ViewWindow* GLViewer_Viewer2d::createView( SUIT_Desktop* theDesktop )
78 {
79     return new GLViewer_ViewFrame( theDesktop, this );
80 }
81
82 /*!
83   Adds item for change background color
84   \param thePopup - menu
85 */
86 void GLViewer_Viewer2d::addPopupItems( QMenu* thePopup )
87 {
88   // CTH8434. "Change background color" menu item is available if there are no selected objects
89   if ( getSelector() == 0 || getSelector()->numSelected() == 0 )
90   {
91     if( thePopup->actions().count() > 0 )
92         thePopup->addSeparator();
93     thePopup->addAction( tr( "CHANGE_BGCOLOR" ), this, SLOT( onChangeBgColor() ) );
94   }
95 }
96
97 /*!
98   Changes background color
99 */
100 void GLViewer_Viewer2d::onChangeBgColor()
101 {
102   if( !getActiveView() )
103     return;
104   GLViewer_ViewPort2d* vp = ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() );
105
106   QColor selColor = QColorDialog::getColor( vp->backgroundColor(), vp );        
107   if ( selColor.isValid() ) {
108     vp->setBackgroundColor( selColor );
109   }
110 }
111
112 /*!
113   Updates colors for all drawers (does not work)
114 */
115 void GLViewer_Viewer2d::updateColors( QColor colorH, QColor colorS )
116 {
117 //  cout << "GLViewer_Viewer2d::updateColors" << endl;
118
119 /*
120     for ( DrawerMap::Iterator it = myDrawers.begin(); it != myDrawers.end(); ++it )
121     {
122         it.key()->setHColor( colorH );
123         it.key()->setSColor( colorS );
124     }
125 */
126     /*
127     ObjList anObjects = myGLContext->getObjects();
128     ObjList::Iterator beginIt = anObjects.begin();
129     ObjList::Iterator endIt = anObjects.end();
130     for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
131     {
132         //GLViewer_Drawer* aDrawer = (*it)->getDrawer();
133         //aDrawer->setHColor( colorH );
134         //aDrawer->setSColor( colorS );
135     }
136     */
137
138
139   activateAllDrawers( TRUE );
140 }
141
142 /*!
143   Updates rect of global scene by adding new rectangle
144   \param theRect - rectangle
145 */
146 void GLViewer_Viewer2d::updateBorders( GLViewer_Rect* theRect )
147 {
148   QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
149   for ( int i = 0, n = views.count(); i < n; i++ )
150   {
151     GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
152
153     border->setLeft( qMin( border->left(), theRect->left() ) );
154     border->setRight( qMax( border->right(), theRect->right() ) );
155     border->setBottom( qMin( border->bottom(), theRect->bottom() ) );
156     border->setTop( qMax( border->top(), theRect->top() ) );
157   }
158 }
159
160 /*!
161   Recomputes global scene rect
162 */
163 void GLViewer_Viewer2d::updateBorders()
164 {
165     QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
166
167     ObjList anObjects = myGLContext->getObjects();
168     ObjList::Iterator beginIt = anObjects.begin();
169     ObjList::Iterator endIt = anObjects.end();
170     for ( int i = 0, n = views.count(); i < n; i++ )
171     {
172         GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
173         if ( !border )
174           continue;
175         border->setIsEmpty( true );
176         // initialise border by default values to avoid old values
177         border->setCoords( 0, 0, 0, 0 );
178         for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
179         {
180             GLViewer_Object* anObject = *it;
181             GLViewer_Rect* aRect = anObject->getRect();
182             if( !anObject->isSelectable() || !anObject->getVisible() )
183                 continue;
184
185             if( border->isEmpty() )
186             {
187                 border->setIsEmpty( false );
188                 border->setCoords( aRect->left(), aRect->right(), aRect->bottom(), aRect->top() );
189             }
190             else
191             {
192                 border->setLeft( qMin( border->left(), aRect->left() ) );
193                 border->setRight( qMax( border->right(), aRect->right() ) );
194                 border->setBottom( qMin( border->bottom(), aRect->bottom() ) );
195                 border->setTop( qMax( border->top(), aRect->top() ) );
196             }
197         }
198     }
199 }
200
201 /*!
202   Redraws all active objects by updating all drawers in all views
203 */
204 void GLViewer_Viewer2d::updateAll()
205 {
206   if ( !getActiveView() )
207     return;
208
209   QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
210   for ( int i = 0, n = views.count(); i < n; i++ )
211     ( ( GLViewer_ViewPort2d* )( ( GLViewer_ViewFrame* )views[i] )->getViewPort() )->getGLWidget()->updateGL();
212 }
213
214 /*!
215    \param onlyUpdate is passed to method activateAllDrawers drawers
216 */
217 void GLViewer_Viewer2d::updateDrawers( GLboolean update, GLfloat scX, GLfloat scY )
218 {
219 //  cout << "GLViewer_Viewer2d::updateDrawers" << endl;
220
221     //myGLContext->updateScales( scX, scY );
222     //myGLSketcher->drawContour();
223     activateAllDrawers( update );
224 }
225
226 /*!
227   Activates drawers for objects from list \param theObjects only
228 */
229 void GLViewer_Viewer2d::activateDrawers( QList<GLViewer_Object*>& theObjects, bool onlyUpdate, GLboolean swap )
230 {
231     //cout << "GLViewer_Viewer2d::activateDrawers " << (int)onlyUpdate << " " << (int)swap << endl;
232     QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
233     QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
234     for( ; anIt != endDIt; anIt++ )
235         (*anIt)->clear();
236
237     QList<GLViewer_Drawer*> anActiveDrawers;
238     QList<GLViewer_Object*>::Iterator endOIt = theObjects.end();
239
240     for( QList<GLViewer_Object*>::Iterator oit = theObjects.begin(); oit != endOIt; ++oit )
241     {
242         GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
243         if( !aDrawer )
244         {
245             anIt = myDrawers.begin();
246             endDIt = myDrawers.end();
247
248             for( ; anIt != endDIt; anIt++ )
249                 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
250                 {
251                     (*oit)->setDrawer( *anIt );
252                     aDrawer = *anIt;
253                     break;
254                 }
255
256             if( !aDrawer )
257             {
258                 myDrawers.append( (*oit)->createDrawer() );
259                 aDrawer = (*oit)->getDrawer();
260             }
261         }
262         if ( !aDrawer )
263           continue;
264         aDrawer->addObject( (*oit) );
265
266         int aPriority = aDrawer->getPriority();
267
268         if( anActiveDrawers.indexOf( aDrawer ) != -1 )
269             continue;
270
271         QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
272         QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
273         for( ; aDIt != aDEndIt; ++aDIt )
274             if( (*aDIt)->getPriority() > aPriority )
275                 break;
276
277         anActiveDrawers.insert( aDIt, aDrawer );
278     } 
279
280     QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
281     QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
282
283     QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
284     for ( int i = 0, n = views.count(); i < n; i++ )
285     {
286         float xScale, yScale;
287         GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort();
288         vp->getScale( xScale, yScale );
289         vp->getGLWidget()->makeCurrent();
290
291         for( ; aDIt != aDEndIt; aDIt++ )
292         {
293             GLViewer_Drawer* aDrawer = *aDIt;
294             if( aDrawer )
295                 aDrawer->create( xScale, yScale, onlyUpdate );
296         }
297 /*
298         // draw border
299         GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
300         (*aDIt)->drawRectangle( border, Qt::blue );
301
302         QString coords = QString::number( border->left() ) + " " + QString::number( border->right() ) + " " +
303                          QString::number( border->bottom() ) + " " + QString::number( border->top() );
304         (*aDIt)->drawText( "Border : " + coords, border->left(), border->top() + 10 / yScale,
305                            Qt::blue, &QFont( "Courier", 8, QFont::Normal ), 2 );
306 */
307         if ( swap )
308            vp->getGLWidget()->swapBuffers();
309     }
310
311     ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
312 }
313
314 /*!
315   Activates drawer for \param theObject
316 */
317 void GLViewer_Viewer2d::activateDrawer( GLViewer_Object* theObject, bool onlyUpdate, GLboolean swap )
318 {
319   ObjList aList;
320   aList.append( theObject );
321   activateDrawers( aList, onlyUpdate, swap );
322 }
323
324 /*!
325    \param onlyUpdate is passed to drawers
326 */
327 void GLViewer_Viewer2d::activateAllDrawers( bool onlyUpdate, GLboolean swap )
328 {
329     if ( !getActiveView() )
330       return;
331
332     ObjList anActiveObjs;
333     const ObjList& objs = myGLContext->getObjects();
334     for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
335     {
336       GLViewer_Object* obj = (GLViewer_Object*)(*it);
337       if( obj->getVisible() )
338           anActiveObjs.append( obj );
339     }
340
341     activateDrawers( anActiveObjs, onlyUpdate, swap );
342 }
343
344 /*!
345   Creates set of marker
346   \param theMarkersNum - number of markers 
347   \param theMarkersRad - radius of markers
348 */
349 void GLViewer_Viewer2d::onCreateGLMarkers( int theMarkersNum, int theMarkersRad )
350 {
351     if ( !getActiveView() )
352       return;
353
354     GLViewer_MarkerSet* aMarkerSet = new GLViewer_MarkerSet( theMarkersNum, theMarkersRad );
355     getGLContext()->insertObject( aMarkerSet );
356
357     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
358     int vpWidth = vp->getWidth();
359     int vpHeight = vp->getHeight();
360
361     float* aXCoord = new float[ theMarkersNum ];
362     float* anYCoord = new float[ theMarkersNum ];
363
364     srand( 1 );
365     for ( long i = 0; i < theMarkersNum; i++ )  
366     {
367         aXCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
368         anYCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
369     }
370
371     aMarkerSet->setXCoord( aXCoord, theMarkersNum );
372     aMarkerSet->setYCoord( anYCoord, theMarkersNum );
373     aMarkerSet->compute();
374
375     updateBorders( aMarkerSet->getRect() );
376     
377     activateAllDrawers( false );
378     activateTransform( GLViewer_Viewer::FitAll );
379
380     delete[] aXCoord;
381     delete[] anYCoord;
382 }
383
384 /*!
385   Creates GL polyline
386   \param theAnglesNum - number of angles
387   \param theRadius - radius
388   \param thePolylineNumber - number
389 */
390 void GLViewer_Viewer2d::onCreateGLPolyline( int theAnglesNum, int theRadius, int thePolylineNumber )
391 {
392     if ( !getActiveView() )
393       return;
394
395     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
396     int vpWidth = vp->getWidth();
397     int vpHeight = vp->getHeight();
398
399     float* aXCoord = new float[ theAnglesNum ];
400     float* anYCoord = new float[ theAnglesNum ];
401
402     //srand( ( unsigned )time( NULL ) );
403     srand( 1 );
404     for( int j = 0; j < thePolylineNumber; j++)
405     {
406         GLViewer_Polyline* aPolyline = new GLViewer_Polyline( theAnglesNum, theRadius );
407         getGLContext()->insertObject( aPolyline );
408
409         float aXOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
410         float anYOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
411         for( int i = 0; i < theAnglesNum; i++ )  
412         {
413             aXCoord[i] = cos( 2. * PI * i / theAnglesNum ) * theRadius + aXOffset;
414             anYCoord[i] = sin( 2. * PI * i / theAnglesNum ) * theRadius + anYOffset;
415         }
416
417         aPolyline->setHighSelAll( true );
418         aPolyline->setClosed( true );
419         aPolyline->setXCoord( aXCoord, theAnglesNum );
420         aPolyline->setYCoord( anYCoord, theAnglesNum );
421         aPolyline->compute();
422
423         updateBorders( aPolyline->getRect() );
424     }
425     
426     activateAllDrawers( false );
427     activateTransform( GLViewer_Viewer::FitAll );
428
429     delete[] aXCoord;
430     delete[] anYCoord;
431 }
432
433 /*!
434   Creates text
435   \param theStr - text string
436   \param theTextNumber - number
437 */
438 void GLViewer_Viewer2d::onCreateGLText( QString theStr, int theTextNumber )
439 {
440     if ( !getActiveView() )
441       return;
442
443     if( theTextNumber <= 0 )
444         return;
445     
446     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
447     int vpWidth = vp->getWidth();
448     int vpHeight = vp->getHeight();
449
450     //srand( ( unsigned )time( NULL ) );
451     srand( 1 );
452     for( int j = 0; j < theTextNumber; j++)
453     {
454         float aXPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
455         float anYPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
456         QColor aColor( 255, 0, 255 );
457
458         GLViewer_TextObject* aText = new GLViewer_TextObject( theStr, aXPos, anYPos, aColor  );
459         aText->compute();
460         getGLContext()->insertObject( aText );
461
462         updateBorders( aText->getRect() );
463     }
464
465     activateAllDrawers( false );
466 }
467
468 /*!
469   Translates point from global CS to curreent viewer CS
470   \param x, y - co-ordinates to be translated
471 */
472 void GLViewer_Viewer2d::transPoint( GLfloat& x, GLfloat& y )
473 {
474     if ( !getActiveView() )
475       return;
476
477     GLfloat xScale, yScale;
478     GLfloat xPan, yPan;
479
480     GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
481
482     curvp->getScale( xScale, yScale );
483     curvp->getPan( xPan, yPan );
484
485     GLfloat a = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
486     
487     x = (  x - ( GLfloat )curvp->getWidth()  / 2 ) / xScale;
488     y = ( -y + ( GLfloat )curvp->getHeight() / 2 ) / yScale;
489
490     GLfloat x1 = x;
491     GLfloat y1 = y;
492
493     x = x1 * cos(a) + y1 * sin(a);
494     y = -x1 * sin(a) + y1 * cos(a);
495
496     x -= xPan;
497     y -= yPan;
498 }
499
500 /*!
501   \return object rect in window CS
502   \param theObject - object
503 */
504 QRect* GLViewer_Viewer2d::getWinObjectRect( GLViewer_Object* theObject )
505 {
506     if ( !getActiveView() )
507       return 0;
508
509     GLfloat xScale, yScale;
510     GLfloat xPan, yPan;
511
512     GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
513     GLfloat aWidth = curvp->getWidth();
514     GLfloat aHeight = curvp->getHeight();
515
516
517     curvp->getScale( xScale, yScale );
518     curvp->getPan( xPan, yPan );
519
520     QRect aObjRect = theObject->getRect()->toQRect();
521     float aLeft = aObjRect.left() + xPan, aRight = aObjRect.right() + xPan;
522     float aTop = aObjRect.top() + yPan, aBot = aObjRect.bottom() + yPan;
523
524     GLfloat anAngle = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
525
526     QPolygon aPointArray(4);
527     aPointArray[0] = QPoint( (int)(aLeft*cos(anAngle) - aTop*sin(anAngle)),
528                              (int)(aLeft*sin(anAngle) + aTop*cos(anAngle)) );
529     aPointArray[1] = QPoint( (int)(aRight*cos(anAngle) - aTop*sin(anAngle)),
530                              (int)(aRight*sin(anAngle) + aTop*cos(anAngle)) );
531     aPointArray[2] = QPoint( (int)(aRight*cos(anAngle) - aBot*sin(anAngle)),
532                              (int)(aRight*sin(anAngle) + aBot*cos(anAngle)) );
533     aPointArray[3] = QPoint( (int)(aLeft*cos(anAngle) - aBot*sin(anAngle)),
534                              (int)(aLeft*sin(anAngle) + aBot*cos(anAngle)) );
535
536     int aMinLeft = aPointArray[0].x(), aMaxRight = aPointArray[0].x(), 
537         aMinTop = aPointArray[0].y(), aMaxBottom = aPointArray[0].y();
538     for( int i = 1; i < 4; i++ )
539     {
540         int x = aPointArray[i].x();
541         int y = aPointArray[i].y();
542         aMinLeft = qMin( aMinLeft,x );
543         aMaxRight = qMax( aMaxRight, x );
544         aMinTop = qMin( aMinTop, y );
545         aMaxBottom = qMax( aMaxBottom, y );
546     }
547
548     aLeft = (aMinLeft/* + xPan*/)*xScale + aWidth / 2;
549     aRight = (aMaxRight/* + xPan*/)*xScale + aWidth / 2;
550
551     aTop = -( (aMaxBottom/* + yPan*/)*yScale - aHeight / 2 );
552     aBot = -( (aMinTop/* + yPan*/)*yScale - aHeight / 2 );    
553
554     QRect* newRect = new QRect( (int)aLeft, (int)aTop, (int)(aRight-aLeft), (int)(aBot-aTop) );
555     
556     return newRect;
557 }
558
559 /*!
560   Translates rect in window CS to rect in global CS
561   \param theRect - rectangle to be translated
562   \return transformed rect
563 */
564 GLViewer_Rect GLViewer_Viewer2d::getGLVRect( const QRect& theRect ) const
565 {
566   if ( !getActiveView() )
567       return GLViewer_Rect();
568
569   GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
570
571   if( !vp )
572     return GLViewer_Rect();
573
574   return vp->win2GLV( theRect );
575 }
576
577 /*!
578   Translates rect in global CS to rect in window CS
579   \param theRect - rectangle to be translated
580   \return transformed rect
581 */
582 QRect GLViewer_Viewer2d::getQRect( const GLViewer_Rect& theRect ) const
583 {
584   if ( !getActiveView() )
585       return QRect();
586
587   GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
588
589   if( !vp )
590     return QRect();
591
592   return vp->GLV2win( theRect );
593 }
594
595 /*!
596   \return new selector
597 */
598 GLViewer_Selector* GLViewer_Viewer2d::createSelector()
599 {
600   return new GLViewer_Selector2d( this, getGLContext() );
601 }
602
603 /*!
604   \return new Transformer 
605   \param type - type of new transformer
606 */
607 GLViewer_ViewTransformer* GLViewer_Viewer2d::createTransformer( int type )
608 {
609     return new GLViewer_View2dTransformer( this, type );
610 }
611
612 /*!
613   Custom mouse event handler
614 */
615 void GLViewer_Viewer2d::onMouseEvent( SUIT_ViewWindow*, QMouseEvent* e )
616 {
617     if ( !getActiveView() )
618         return;
619
620     //if ( testRotation( e ) )
621     //    return;
622
623     switch( e->type() )
624     {
625         case QEvent::MouseButtonPress :
626         case QEvent::MouseMove :
627         case QEvent::MouseButtonRelease :
628             //if( myGLSketcher->getType() != None )
629             //    myGLSketcher->sketch( e );
630         default: break;
631     }
632
633     GLViewer_Viewer::onMouseEvent( 0, e );
634 }
635
636 /*!
637   Rotation transformation
638 */
639 bool GLViewer_Viewer2d::testRotation( QMouseEvent* e )
640 {
641     if ( ( e->button() == GLViewer_View2dTransformer::rotateButton() ) &&
642          ( e->type() == QEvent::MouseButtonPress ) &&
643          ( e->modifiers() & GLViewer_ViewTransformer::accelKey() ) )
644     {
645         activateTransform( GLViewer_Viewer::Rotate );
646         return true;
647     }
648     return false;
649 }
650
651 /*!
652   Inserts text lines as header for file
653   \param aType - file type
654   \param hFile - file instance
655 */
656 void GLViewer_Viewer2d::insertHeader( VectorFileType aType, QFile& hFile )
657 {
658     if( aType == POST_SCRIPT )
659     {
660         QString header = "%!PS-Adobe-3.0\n";
661         header += "%%Creator: OpenCascade 2004\n";
662         header += "%%Title: Our document\n";        
663         header += "%%PageOrder: Ascend\n";      
664         header += "%%Orientation: Portrait\n";
665         header += "%%LanguageLevel: 2\n";
666
667         header += "%%Pages: 1\n";
668         header += "%%Page: 1\n\n";
669         
670         hFile.write( header.toAscii() );
671     }
672     else if( aType == HPGL )
673     {
674         QString header = "[Esc].(;\n";
675         header += "[Esc].I81;;17:\n";
676         header += "[Esc].N;19:\n";
677         header += "IN;\n";
678         header += "SC;\n";
679         header += "PU;\n";
680         header += "SP1;\n";
681         header += "LT;\n";
682         header += "VS36;\n";
683         
684         hFile.write( header.toAscii() );
685     }
686 }
687
688 /*!
689   Inserts text lines as ending for file
690   \param aType - file type
691   \param hFile - file instance
692 */
693 void GLViewer_Viewer2d::insertEnding( VectorFileType aType, QFile& hFile )
694 {
695     if( aType == POST_SCRIPT )
696     {
697         QString ending = "showpage\n\n%%EOF";
698         hFile.write( ending.toAscii() );
699     }
700     else if( aType == HPGL )
701     {
702         QString ending = "PU;PA0,0;SP;EC;PG1;EC1;OE\n"; 
703         hFile.write( ending.toAscii() );
704     }
705 }
706
707 inline void mm2custom( GLViewer_Viewer2d::VectorFileType aType, double& value )
708 {
709     if( aType==GLViewer_Viewer2d::POST_SCRIPT )
710         value*=2.8346; //mm to pt
711
712     else if( aType==GLViewer_Viewer2d::HPGL )
713         value*=40;     //mm to plu (there are 40 plues in mm)
714 #ifdef WIN32
715     else if( aType==GLViewer_Viewer2d::ENH_METAFILE )
716         value*=100;    //this unit is 1/100 mm
717 #endif 
718 }
719
720 /*!
721   Translates current view content to vector file
722   \param aType - type of file
723   \param FileName - name of file,
724   \param aPType - paper size type
725   \param mmLeft, mmRight, mmTop, mmBottom - margins
726 */
727 bool GLViewer_Viewer2d::translateTo( VectorFileType aType, QString FileName, PaperType aPType, 
728                                   double mmLeft, double mmRight, double mmTop, double mmBottom )
729 {
730     if ( !getActiveView() )
731       return false;
732
733         QFile hFile( FileName.toAscii() );
734
735 #ifdef WIN32
736     HDC hMetaFileDC;
737 #endif
738
739     GLViewer_ViewPort2d* aCurVP = (GLViewer_ViewPort2d*) getActiveView()->getViewPort();
740
741     GLfloat xPan, yPan;
742     aCurVP->getPan( xPan, yPan );
743     GLfloat aRotation = aCurVP->getGLWidget()->getRotationAngle() * 3.14159265 / 180.0;
744
745     GLViewer_CoordSystem aViewerCS( GLViewer_CoordSystem::Cartesian, xPan, yPan, 1.0, 1.0, aRotation );
746
747     double AW = Sizes[2*int(aPType)], 
748            AH = Sizes[2*int(aPType)+1]; //size of Axx paper in mm
749
750     mm2custom( aType, mmLeft ); //we translate mm to custom units
751     mm2custom( aType, mmRight );
752     mm2custom( aType, mmTop );
753     mm2custom( aType, mmBottom );
754     mm2custom( aType, AW );
755     mm2custom( aType, AH );
756
757     float xScale, yScale;
758     aCurVP->getScale( xScale, yScale );
759
760     double VPWidth = aCurVP->getWidth()/xScale,   //the width in reference units
761            VPHeight = aCurVP->getHeight()/yScale;
762
763     double k1 = ( AW-mmLeft-mmRight ) / VPWidth,
764            k2 = ( AH-mmTop-mmBottom ) / VPHeight;
765
766     if( k1>k2 )
767         k1 = k2; //We select the minimum
768
769     double hdelta = ( AW-mmLeft-mmRight - VPWidth * k1 )/2.0, //addition in horizontal
770            vdelta = ( AH-mmTop-mmBottom - VPHeight * k1 )/2.0; //addition in vertical
771
772     mmLeft   += hdelta; //The real free space on the left and right borders
773     mmRight  += hdelta;
774     mmTop    += vdelta;
775     mmBottom += vdelta;
776
777     GLViewer_CoordSystem aPaperCS( GLViewer_CoordSystem::Cartesian, 
778         -(mmLeft/k1+VPWidth/2.0), -(mmBottom/k1+VPHeight/2.0), 1/k1, 1/k1 );
779
780     if( aType==POST_SCRIPT || aType==HPGL )
781     {
782         hFile.open( QIODevice::ReadWrite | QIODevice::Truncate );
783         hFile.seek( 0 );
784         insertHeader( aType, hFile );
785     }
786 #ifdef WIN32
787     else if( aType==ENH_METAFILE )
788     {
789         RECT r; 
790         r.left = 0; r.right = AW; 
791         r.top = 0; r.bottom = AH; 
792         HDC screen_dc = GetDC( 0 ); //The screen device context
793         HDC bitDC = CreateCompatibleDC ( screen_dc ); //The context compatible with screen
794
795         hMetaFileDC = CreateEnhMetaFile( bitDC, FileName.toAscii(), &r, "" );
796         SetMapMode( hMetaFileDC, MM_HIMETRIC );
797         SetWindowOrgEx( hMetaFileDC, 0, r.bottom, NULL );
798         HRGN ClipRgn = CreateRectRgn( 0, 0, AW, AH );
799         SelectClipRgn( hMetaFileDC, ClipRgn );
800
801         LOGBRUSH aBrushData;
802         aBrushData.lbColor = RGB( 255, 255, 255 );      
803         aBrushData.lbStyle = BS_SOLID;
804
805         FillRect( hMetaFileDC, &r, CreateBrushIndirect( &aBrushData ) );
806
807         ReleaseDC( 0, screen_dc );
808         DeleteDC( bitDC );
809
810         aCurVP->getGLWidget()->translateBackgroundToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
811     }
812 #endif
813
814     if( aType==POST_SCRIPT )
815     {
816         QString temp = "%1 %2 %3 %4 rectclip\n\n",
817                 aBuffer = temp.arg( mmLeft ).arg( mmBottom ).
818                                arg( AW-mmLeft-mmRight ).arg( AH-mmBottom-mmTop );
819         //It is set clipping path
820
821         hFile.write( aBuffer.toAscii() );
822
823         aCurVP->getGLWidget()->translateBackgroundToPS( hFile, &aViewerCS, &aPaperCS );
824     }
825
826     bool result = true;
827     for( int i=0, n=myDrawers.count(); i<n; i++ )
828         if( aType==POST_SCRIPT )
829             result &= myDrawers[ i ]->translateToPS( hFile, &aViewerCS, &aPaperCS );
830         else if( aType==HPGL )
831             result &= myDrawers[ i ]->translateToHPGL( hFile, &aViewerCS, &aPaperCS );
832 #ifdef WIN32
833         else if( aType==ENH_METAFILE )
834             result &= myDrawers[ i ]->translateToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
835 #endif
836
837     if( aType==POST_SCRIPT || aType==HPGL )
838     {
839         insertEnding( aType, hFile);
840         hFile.close();
841     }
842 #ifdef WIN32
843     else if( aType==ENH_METAFILE )  
844         DeleteEnhMetaFile( CloseEnhMetaFile( hMetaFileDC ) );
845 #endif
846
847     return true;
848 }
849
850 /*!
851   Repaints view
852   \param theView - view to be repainted. If it is NULL then all views will be repainted
853 */
854 void GLViewer_Viewer2d::repaintView( GLViewer_ViewFrame* theView, bool makeCurrent )
855 {
856     GLViewer_ViewFrame* aCurView;
857     if( !theView )
858         aCurView = (GLViewer_ViewFrame*)getActiveView();
859     else
860         aCurView = theView;
861     
862     if ( !aCurView )
863       return;
864
865     ObjList anActiveObjs;
866     const ObjList& objs = myGLContext->getObjects();
867     for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
868     {
869       GLViewer_Object* obj = (GLViewer_Object*)(*it);
870       if( obj->getVisible() )
871           anActiveObjs.append( obj );
872     }
873
874     float xScale;
875     float yScale;
876
877     QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
878     QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
879     for( ; anIt != endDIt; anIt++ )
880             (*anIt)->clear();
881
882     QList<GLViewer_Drawer*> anActiveDrawers;
883     QList<GLViewer_Object*>::Iterator endOIt = anActiveObjs.end();
884
885     for( QList<GLViewer_Object*>::Iterator oit = anActiveObjs.begin(); oit != endOIt; ++oit )
886     {
887         GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
888         if( !aDrawer )
889         {
890             anIt = myDrawers.begin();            
891
892             for( ; anIt != endDIt; anIt++ )
893                 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
894                 {
895                     (*oit)->setDrawer( *anIt );
896                     aDrawer = *anIt;
897                     break;
898                 }
899
900             if( !aDrawer ) //are not exists
901             {
902                 myDrawers.append( (*oit)->createDrawer() );
903                 aDrawer = (*oit)->getDrawer();
904             }
905         }
906         aDrawer->addObject( (*oit) );
907         if( anActiveDrawers.indexOf( aDrawer ) == -1 )
908             anActiveDrawers.append( aDrawer );
909     } 
910
911     QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
912     QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
913
914     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )aCurView->getViewPort();
915     vp->getScale( xScale, yScale );
916
917     if( makeCurrent )
918         vp->getGLWidget()->makeCurrent();
919
920     for( ; aDIt != aDEndIt; aDIt++ )
921         (*aDIt)->create( xScale, yScale, false );
922     
923 //    if ( swap )
924     vp->getGLWidget()->swapBuffers();
925
926 //    ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
927 }
928
929 /*!
930   Starts some operation on mouse event
931 */
932 void GLViewer_Viewer2d::startOperations( QMouseEvent* e )
933 {
934     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
935
936     float x = e->pos().x();
937     float y = e->pos().y();
938     transPoint( x, y );
939     GLViewer_Pnt point( x, y );
940
941     if( e->button() == Qt::LeftButton && !myGLContext->getCurrentObject() && vp->startPulling( point ) )
942         return;
943
944     if( e->button() == Qt::LeftButton && !(vp->currentBlock() & BS_Selection) && !myGLContext->getCurrentObject() )
945         vp->startSelectByRect( e->x(), e->y() );
946 }
947
948 /*!
949   Updates started operation on mouse event
950 */
951 bool GLViewer_Viewer2d::updateOperations( QMouseEvent* e )
952 {
953     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
954
955     if( vp->isPulling() )
956     {
957         float x = e->pos().x();
958         float y = e->pos().y();
959         transPoint( x, y );
960
961         vp->drawPulling( GLViewer_Pnt( x, y ) );
962         updateAll();
963         return true;
964     }
965
966     if( !myGLContext->getCurrentObject() )
967     {
968         vp->drawSelectByRect( e->x(), e->y() );
969         return true;
970     }
971     return false;
972 }
973
974 /*!
975   Completes started operation on mouse event
976 */
977 void GLViewer_Viewer2d::finishOperations( QMouseEvent* e )
978 {
979     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
980
981     if( vp->isPulling() )
982     {
983         vp->finishPulling();
984         updateAll();
985         return;
986     }
987
988     if( !myGLContext->getCurrentObject() )
989     {
990         QRect aSelRect = vp->selectionRect();
991         vp->finishSelectByRect();
992         if ( getSelector() && !aSelRect.isNull() )
993         {            
994             bool append = bool ( e->modifiers() & GLViewer_Selector::appendKey() );
995             getSelector()->select( aSelRect, append );
996         }
997     }
998 }
999
1000 /*!
1001   Starts some operation on mouse wheel event
1002 */
1003 void GLViewer_Viewer2d::startOperations( QWheelEvent* e )
1004 {
1005     bool zoomIn = e->delta() > 0;
1006     bool update = false;
1007     for( myGLContext->InitSelected(); myGLContext->MoreSelected(); myGLContext->NextSelected() )
1008     {
1009         GLViewer_Object* anObject = myGLContext->SelectedObject();
1010         update = anObject->updateZoom( zoomIn ) || update;
1011     }
1012
1013     emit wheelZoomChange( zoomIn );
1014
1015     if( update )
1016         updateAll();
1017 }
1018
1019
1020 int GLViewer_View2dTransformer::rotateBtn = Qt::RightButton;
1021
1022 /*!
1023   Constructor
1024 */
1025 GLViewer_View2dTransformer::GLViewer_View2dTransformer( GLViewer_Viewer* viewer, int typ )
1026 : GLViewer_ViewTransformer( viewer, typ )
1027 {
1028     if ( type() == GLViewer_Viewer::Rotate )
1029         initTransform( true );
1030 }
1031
1032 /*!
1033   Destructor
1034 */
1035 GLViewer_View2dTransformer::~GLViewer_View2dTransformer()
1036 {
1037     if ( type() == GLViewer_Viewer::Rotate )
1038         initTransform( false );
1039 }
1040
1041 /*!
1042     Redefined to provide specific 3D transfomations. [ virtual public ]
1043 */
1044 void GLViewer_View2dTransformer::exec()
1045 {
1046     if ( !myViewer->getActiveView() )
1047       return;
1048
1049     /* additional transforms */
1050     GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1051     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1052     switch ( myType )
1053     {
1054         case GLViewer_Viewer::Rotate:
1055             myMajorBtn = rotateButton();
1056             avp->setCursor( *avp->getRotCursor() );
1057             break;
1058         default:
1059             GLViewer_ViewTransformer::exec();
1060     }
1061 }
1062
1063 /*!
1064     Handles rotation. [ protected virtual ]
1065 */
1066 void GLViewer_View2dTransformer::onTransform( TransformState state )
1067 {
1068     if ( !myViewer->getActiveView() )
1069       return;
1070
1071     GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1072     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1073     if ( type() == GLViewer_Viewer::Rotate )
1074     {
1075         switch ( state )
1076         {
1077             case Debut:
1078                 if ( myButtonState & myMajorBtn )
1079                     avp->startRotation( myStart.x(), myStart.y() );
1080                 break;
1081             case EnTrain:
1082                 if ( myButtonState & myMajorBtn )
1083                     avp->rotate( myCurr.x(), myCurr.y() );
1084                 break;
1085             case Fin:
1086                 avp->endRotation();
1087                 break;
1088             default: break;
1089         }
1090     }
1091     GLViewer_ViewTransformer::onTransform( state );
1092 }