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