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