Salome HOME
Transaction management in operations modifed.
[modules/gui.git] / src / GLViewer / GLViewer_BaseObjects.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 /***************************************************************************
23 **  Class:   GLViewer_BaseObjects
24 **  Descr:   Internal OpenGL Objects
25 **  Module:  GLViewer
26 **  Created: UI team, 02.09.02
27 ****************************************************************************/
28
29 //#include <GLViewerAfx.h>
30 #include "GLViewer_BaseObjects.h"
31 #include "GLViewer_BaseDrawers.h"
32 #include "GLViewer_AspectLine.h"
33 #include "GLViewer_CoordSystem.h"
34 #include "GLViewer_Text.h"
35 #include "GLViewer_Group.h"
36
37 #include "GLViewer_Drawer.h"
38
39 //#include <cmath>
40 //using namespace std;
41
42 /***************************************************************************
43 **  Class:   GLViewer_MarkerSet
44 **  Descr:   OpenGL MarkerSet
45 **  Module:  GLViewer
46 **  Created: UI team, 03.09.02
47 ****************************************************************************/
48
49 GLViewer_MarkerSet::GLViewer_MarkerSet( int number, float size, const QString& toolTip ) :
50   GLViewer_Object(),
51   myNumber( 0 ),
52   myXCoord( 0 ),
53   myYCoord( 0 )       
54 {
55     
56     myMarkerSize = size;
57     myHNumbers.clear();
58     myUHNumbers.clear();
59     mySelNumbers.clear();
60     myUSelNumbers.clear();
61     myCurSelNumbers.clear();
62     myPrevHNumbers.clear();    
63
64     myType = "GLViewer_MarkerSet";
65     myToolTipText = toolTip;
66     
67     setNumMarkers( number );    
68 }
69
70 GLViewer_MarkerSet::~GLViewer_MarkerSet()
71 {
72     if ( myXCoord )
73         delete[] myXCoord;
74     if ( myYCoord )
75         delete[] myYCoord;
76 }
77
78 void AddCoordsToHPGL( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS, 
79                       GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
80 {
81     if( aViewerCS && aPaperCS )
82         aViewerCS->transform( *aPaperCS, x, y );
83
84     QString temp = command + "%1, %2;";
85     buffer += temp.arg( x ).arg( y );
86     if( NewLine )
87         buffer += ";\n";
88 }
89
90 void AddCoordsToPS( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS, 
91                     GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
92 {
93     if( aViewerCS && aPaperCS )
94         aViewerCS->transform( *aPaperCS, x, y );
95
96     QString temp = "%1 %2 "+command;    
97     buffer += temp.arg( x ).arg( y );
98     if( NewLine )
99         buffer += "\n";
100 }
101
102 void AddLineAspectToPS( QString& buffer, GLViewer_AspectLine* anAspect, 
103                         GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
104 {
105     if( anAspect )
106     {
107         QColor col1, col2, col3;
108         anAspect->getLineColors( col1, col2, col3 );
109
110         float aWidth = anAspect->getLineWidth();
111         int aLineType = anAspect->getLineType();
112
113         QString temp = "%1 %2 %3 setrgbcolor\n";
114         double rr = 1 - double( col1.red() ) / 255.0, //color inverting
115                gg = 1 - double( col1.green() ) / 255.0,
116                bb = 1 - double( col1.blue() ) / 255.0;
117
118         buffer += temp.arg( rr ).arg( gg ).arg( bb );
119
120         double x_stretch, y_stretch;
121         aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
122         buffer += temp.arg( x_stretch * aWidth )+" setlinewidth\n";
123
124         if( aLineType==0 ) //solid
125             buffer += "[] 0 setdash\n";
126         else if( aLineType==1 ) //strip
127             buffer += "[2] 0 setdash\n";
128     }
129 }
130
131 #ifdef WIN32
132 HPEN AddLineAspectToEMF( HDC hDC, GLViewer_AspectLine* anAspect, 
133                          GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
134 {
135     if( anAspect )
136     {
137         QColor col1, col2, col3;
138         anAspect->getLineColors( col1, col2, col3 );
139
140         double x_stretch, y_stretch;
141         aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
142
143         double aWidth = anAspect->getLineWidth()*x_stretch;
144         int aLineType = anAspect->getLineType();
145
146         return CreatePen( PS_SOLID, aWidth, RGB( 255-col1.red(), 255-col1.green(), 255-col1.blue() ) );
147     }
148     else
149         return NULL;
150 }
151 #endif
152
153 bool GLViewer_MarkerSet::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
154 {   
155     int noPoints = 20;
156
157     QString aBuffer = "newpath\n";
158
159     AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
160
161     for( int i=0; i<myNumber; i++ )
162     {       
163         aBuffer += "\n";
164
165         double x_stretch, y_stretch;
166         aViewerCS->getStretching( *aPSCS, x_stretch, y_stretch );
167
168         double x0 = myXCoord[i],
169                y0 = myYCoord[i],
170                r  = myMarkerSize,
171                x, y;
172
173         for( int j=0; j<=noPoints; j++ )
174         {
175             x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
176             y = y0 + r*sin( double(j)*2*PI/double(noPoints) );          
177             if( j==0 )
178                 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, x, y, true );               
179             else
180                 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, x, y, true );
181         }
182     }
183     aBuffer+="closepath\nstroke\n";
184
185     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
186
187     return true;
188 }
189
190 bool GLViewer_MarkerSet::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS,
191                                        GLViewer_CoordSystem* aHPGLCS )
192 {
193     int noPoints = 20;
194     QString aBuffer;
195     for( int i=0; i<myNumber; i++ )
196     {
197         aBuffer = "";
198
199         double x_stretch, y_stretch;
200         aViewerCS->getStretching( *aHPGLCS, x_stretch, y_stretch );
201
202         double x0 = myXCoord[i],
203                y0 = myYCoord[i],
204                r  = myMarkerSize,
205                x, y;
206
207         AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, x0+r, y0 );
208         aBuffer+="PD;\n";
209         for( int j=1; j<=noPoints; j++ )
210         {
211             x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
212             y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
213             AddCoordsToHPGL( aBuffer, "PD", aViewerCS, aHPGLCS, x, y );
214         }
215         aBuffer+="PU;\n";
216
217         hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
218     }
219
220     return true;
221 }
222
223 #ifdef WIN32
224 bool GLViewer_MarkerSet::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
225 {
226     int noPoints = 20;
227     if( !aViewerCS || !aEMFCS )
228         return false;
229     
230     HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
231     HGDIOBJ old = SelectObject( dc, pen );
232
233     for( int i=0; i<myNumber; i++ )
234     {
235         double x0 = myXCoord[i],
236                y0 = myYCoord[i],
237                r  = myMarkerSize,
238                x, y;
239
240         for( int j=0; j<=noPoints; j++ )
241         {
242             x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
243             y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
244             aViewerCS->transform( *aEMFCS, x, y );
245             if( j==0 )
246                 MoveToEx( dc, x, y, NULL );
247             else
248                 LineTo( dc, x, y );
249         }
250     }
251
252     SelectObject( dc, old );
253     if( pen )
254         DeleteObject( pen );
255     return true;
256 }
257 #endif
258
259
260 void GLViewer_MarkerSet::compute()
261 {
262 //  cout << "GLViewer_MarkerSet::compute" << endl;
263   GLfloat xa = myXCoord[0]; 
264   GLfloat xb = myXCoord[0]; 
265   GLfloat ya = myYCoord[0]; 
266   GLfloat yb = myYCoord[0]; 
267
268   for ( int i = 0; i < myNumber; i++ )  
269   {
270     xa = QMIN( xa, myXCoord[i] );
271     xb = QMAX( xb, myXCoord[i] );
272     ya = QMIN( ya, myYCoord[i] );
273     yb = QMAX( yb, myYCoord[i] );
274   }
275   
276   myXGap = ( xb - xa ) / 10;
277   myYGap = ( yb - ya ) / 10;
278
279   myRect->setLeft( xa - myXGap );
280   myRect->setTop( yb + myYGap ); 
281   myRect->setRight( xb + myXGap );
282   myRect->setBottom( ya - myYGap );
283 }
284
285 GLViewer_Drawer* GLViewer_MarkerSet::createDrawer()
286 {
287 //  cout << "GLViewer_MarkerSet::createDrawer" << endl;
288   return myDrawer = new GLViewer_MarkerDrawer();
289 }
290
291
292 GLboolean GLViewer_MarkerSet::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
293 {
294     if( !myIsVisible )
295         return false;
296 //  cout << "GLViewer_MarkerSet::highlight " << x <<" " << y << " " << tol << endl;
297   int count = 0;
298   GLfloat xdist, ydist, radius;
299   QValueList<int>::Iterator it;
300   QValueList<int> curHNumbers;
301   bool isFound;
302   GLboolean update;
303   int cnt = 0;
304
305   radius = tol - myMarkerSize / 2.;
306   
307   myUHNumbers += myHNumbers;
308   myHNumbers.clear();
309
310   for ( int i = 0; i < myNumber; i++ ) 
311   {
312     xdist = ( myXCoord[i] - x ) * myXScale;
313     ydist = ( myYCoord[i] - y ) * myYScale;
314
315 //    if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
316     if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
317     !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) )
318     {
319       isFound = FALSE;
320       count++;
321       for ( it = myCurSelNumbers.begin(); it != myCurSelNumbers.end(); ++it )
322         if( i == *it )
323         {
324           isFound = TRUE;
325           curHNumbers.append( i );
326         }
327       
328       if( !isFound )
329           myHNumbers.append( i );
330       else
331         cnt++;
332     }
333   }
334   myCurSelNumbers = curHNumbers;
335
336   myIsHigh = ( GLboolean )count;
337   update = ( GLboolean )( myHNumbers != myPrevHNumbers );
338
339   myPrevHNumbers = myHNumbers;
340
341   //cout << "GLViewer_MarkerSet::highlight complete with " << (int)myIsHigh << endl;
342   return update;
343 }
344
345 GLboolean GLViewer_MarkerSet::unhighlight()
346 {
347   if( !myHNumbers.isEmpty() )
348   {
349     myUHNumbers += myHNumbers;
350     myPrevHNumbers.clear();
351     myHNumbers.clear();
352     //??? myCurSelNumbers.clear();
353     return GL_TRUE;
354   }
355   
356   return GL_FALSE;
357 }
358
359 GLboolean GLViewer_MarkerSet::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
360                                       GLboolean isCircle, GLboolean isShift )
361 {
362     if( !myIsVisible )
363         return false;
364 //  cout << "GLViewer_MarkerSet::select " << x << " " << y << endl;
365   int count = 0;
366   GLfloat xdist, ydist, radius;
367   QValueList<int>::Iterator it;
368   QValueList<int>::Iterator it1;
369   QValueList<int>::Iterator remIt;
370   QValueList<int>::Iterator curIt;
371
372   radius = tol - myMarkerSize / 2.;
373
374   if( radius < myMarkerSize / 2.)
375     radius = myMarkerSize / 2.;
376
377   count = isShift ? mySelNumbers.count() : 0;
378
379   myUSelNumbers = mySelNumbers;
380
381   if ( !isShift )
382   {
383     mySelNumbers.clear();
384     myCurSelNumbers.clear();
385   }
386
387   for ( int i = 0; i < myNumber; i++ ) 
388   {
389     xdist = ( myXCoord[i] - x ) * myXScale;
390     ydist = ( myYCoord[i] - y ) * myYScale;
391
392     //if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
393     if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
394           !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) )
395     {
396       count++;
397       if ( isShift )
398       {
399         bool isFound = FALSE;
400           for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
401             if ( *it == i )
402             {
403               myUSelNumbers.append( *it );
404             remIt = it;
405               isFound = TRUE;
406               break;
407             }
408
409           if ( !isFound )
410         {
411           mySelNumbers.append( i );
412             myCurSelNumbers.append( i );
413             for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
414               if( i == *it1 )
415               {
416                 myHNumbers.remove( it1 );
417                 break;
418               }
419       for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
420         if( i == *it1 )
421         {
422           myUHNumbers.remove( it1 );
423           break;
424         }
425         }
426     else
427         {
428       mySelNumbers.remove( remIt );
429       for ( curIt = myCurSelNumbers.begin(); curIt != myCurSelNumbers.end(); ++curIt )
430         if( *curIt == *remIt)
431         {
432           myCurSelNumbers.remove( curIt );
433           break;
434         }
435       for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
436         if( i == *it1 )
437         {
438           myHNumbers.remove( it1 );
439           break;
440         }
441       for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
442         if( i == *it1 )
443         {
444           myUHNumbers.remove( it1 );
445           break;
446         }
447         }
448       }
449       else
450       {
451     mySelNumbers.append( i );
452     myCurSelNumbers.append( i );
453     for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
454       if( i == *it1 )
455       {
456         myHNumbers.remove( it1 );
457         break;
458       }
459     for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
460       if( i == *it1 )
461           {
462         myUHNumbers.remove( it1 );
463         break;
464       }        
465       }     
466     }
467   }
468
469   for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
470     for( it1 = myUSelNumbers.begin(); it1 != myUSelNumbers.end(); ++it1 )
471       if( *it == *it1 )
472       {
473         it1 = myUSelNumbers.remove( it1 );
474         it1--;
475       }
476   
477   myIsSel = (GLboolean)count;
478
479 //  cout << "GLViewer_MarkerSet::select complete with " << (int)myIsSel << endl;
480   return myIsSel;
481 }
482
483 GLboolean GLViewer_MarkerSet::unselect()
484 {
485   if( !mySelNumbers.isEmpty() )
486   {
487     myUSelNumbers = mySelNumbers;
488     mySelNumbers.clear();
489     myCurSelNumbers.clear();
490     return GL_TRUE;
491   }
492
493   return GL_FALSE;
494 }
495
496 GLViewer_Rect* GLViewer_MarkerSet::getUpdateRect()
497 {
498   GLViewer_Rect* rect = new GLViewer_Rect();
499   
500   rect->setLeft( myRect->left() + myXGap - myMarkerSize / myXScale );
501   rect->setTop( myRect->top() + myYGap + myMarkerSize / myYScale ); 
502   rect->setRight( myRect->right() - myXGap + myMarkerSize / myXScale );
503   rect->setBottom( myRect->bottom() - myYGap - myMarkerSize / myYScale );
504   //cout << " Additional tolerance " << myMarkerSize / myYScale << endl;
505   //rect->setLeft( myRect->left() - myMarkerSize / myXScale );
506   //rect->setTop( myRect->top() - myMarkerSize / myYScale ); 
507   //rect->setRight( myRect->right() + myMarkerSize / myXScale );
508   //rect->setBottom( myRect->bottom() + myMarkerSize / myYScale );
509   
510   return rect;
511 }
512
513
514 void GLViewer_MarkerSet::setXCoord( GLfloat* xCoord, int size )
515 {
516   myXCoord = new GLfloat[ size ];
517   for( int i = 0; i < size; i++ )
518      myXCoord[i] = xCoord[i];
519 }
520
521 void GLViewer_MarkerSet::setYCoord( GLfloat* yCoord, int size )
522 {
523   myYCoord = new GLfloat[ size ];
524   for( int i = 0; i < size; i++ )
525      myYCoord[i] = yCoord[i];
526 }
527
528 void GLViewer_MarkerSet::setNumMarkers( GLint number )
529 {
530   if ( myNumber == number )
531     return;
532     
533   if ( myXCoord && myYCoord )
534   {
535     delete[] myXCoord;
536     delete[] myYCoord;
537   }
538
539   myNumber = number;
540   myXCoord = new GLfloat[ myNumber ];
541   myYCoord = new GLfloat[ myNumber ];
542 }
543 /*
544 void GLViewer_MarkerSet::onSelectionDone( bool append)
545 {
546   mySelectedIndexes.Clear();
547   QValueList<int>::Iterator it;
548   //for( it = myMarkers->mySelNumbers.begin(); it != myMarkers->mySelNumbers.end(); ++it )
549   //  mySelectedIndexes.Append( *it / 2 ); //!!!
550
551   emit dvMarkersSelected( mySelectedIndexes );
552 }
553
554 void GLViewer_MarkerSet::onSelectionCancel()
555 {
556   mySelectedIndexes.Clear();
557   emit dvMarkersSelected( mySelectedIndexes );
558 }
559 */
560 void GLViewer_MarkerSet::exportNumbers( QValueList<int>& highlight,
561                      QValueList<int>& unhighlight,
562                      QValueList<int>& select,
563                      QValueList<int>& unselect )
564 {
565     highlight = myHNumbers;
566     unhighlight = myUHNumbers;
567     select = mySelNumbers;
568     unselect = myUSelNumbers;
569
570     myUHNumbers = myHNumbers;
571 }
572
573 bool GLViewer_MarkerSet::addOrRemoveSelected( int index )
574 {
575   if( index < 0 || index > myNumber )
576     return FALSE;
577
578   int n = mySelNumbers.findIndex( index );
579   if( n == -1 )
580     mySelNumbers.append( index );
581   else
582   {
583     QValueList<int>::Iterator it;
584     it = mySelNumbers.at( n );
585     mySelNumbers.remove( it );
586     myUSelNumbers.append( index );
587   }
588   return TRUE;
589 }
590
591 void GLViewer_MarkerSet::addSelected( const TColStd_SequenceOfInteger& seq )
592 {
593   for ( int i = 1; i <= seq.Length(); i++ )
594     if( mySelNumbers.findIndex( seq.Value( i ) ) == -1 )
595       mySelNumbers.append( seq.Value( i ) - 1 );
596 }
597
598 void GLViewer_MarkerSet::setSelected( const TColStd_SequenceOfInteger& seq )
599 {
600 //   for( QValueList<int>::Iterator it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
601 //     if( myUSelNumbers.findIndex( *it ) == -1 )
602 //       myUSelNumbers.append( *it );
603
604   myUSelNumbers = mySelNumbers;
605   mySelNumbers.clear();
606     
607   for ( int i = 1; i <= seq.Length(); i++ )
608     mySelNumbers.append( seq.Value( i ) - 1 );
609 }
610
611 void GLViewer_MarkerSet::moveObject( float theX, float theY, bool fromGroup )
612 {
613     if( !fromGroup && myGroup)
614     {
615       myGroup->dragingObjects( theX, theY );
616       return;
617     }
618     for( int i = 0; i < myNumber;  i++ )
619     {
620         myXCoord[i] = myXCoord[i] + theX;
621         myYCoord[i] = myYCoord[i] + theY;
622     }
623     compute();    
624 }
625
626 QByteArray GLViewer_MarkerSet::getByteCopy()
627 {
628     int i = 0;
629     int anISize = sizeof( GLint );
630     int aFSize = sizeof( GLfloat );
631     
632     QByteArray aObject = GLViewer_Object::getByteCopy();
633
634     QByteArray aResult( anISize + 2*aFSize*myNumber + aFSize + aObject.size());
635
636     char* aPointer = (char*)&myNumber;
637     for( i = 0; i < anISize; i++, aPointer++ )
638         aResult[i] = *aPointer;
639
640     aPointer = (char*)myXCoord;
641     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
642         aResult[i] = *aPointer;
643     aPointer = (char*)myYCoord;
644     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
645         aResult[i] = *aPointer;
646     
647     aPointer = (char*)&myMarkerSize;
648     for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
649         aResult[i] = *aPointer;
650         
651     
652     for( ; i < aResult.size(); i++ )
653         aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - aFSize];
654
655     return aResult;
656 }
657
658 bool GLViewer_MarkerSet::initializeFromByteCopy( QByteArray theArray )
659 {
660     int i = 0;
661     int anISize = sizeof( GLint );
662     int aFSize = sizeof( GLfloat );
663
664     char* aPointer = (char*)&myNumber;
665     for( i = 0; i < anISize; i++, aPointer++ )
666         *aPointer = theArray[i];
667
668     int aSize = theArray.size();
669     if( aSize < anISize + 2*aFSize*myNumber + aFSize)
670         return false;
671
672     myXCoord = new GLfloat[myNumber];
673     myYCoord = new GLfloat[myNumber];
674     aPointer = (char*)myXCoord;
675     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
676         *aPointer = theArray[i];
677     aPointer = (char*)myYCoord;
678     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
679         *aPointer = theArray[i];
680
681     aPointer = (char*)&myMarkerSize;
682     for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
683          *aPointer = theArray[i];
684          
685     int aCurIndex = anISize + 2*aFSize*myNumber + aFSize;
686     QByteArray aObject( aSize - aCurIndex );
687     for( ; i < aSize; i++ )
688         aObject[i - aCurIndex] = theArray[i];
689         
690
691     if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_MarkerSet" )
692         return false;
693
694     myHNumbers.clear();
695     myUHNumbers.clear();
696     mySelNumbers.clear();
697     myUSelNumbers.clear();
698     myCurSelNumbers.clear();
699     myPrevHNumbers.clear();
700
701     return true;        
702 }
703
704 /***************************************************************************
705 **  Class:   GLViewer_Polyline
706 **  Descr:   OpenGL Polyline
707 **  Module:  GLViewer
708 **  Created: UI team, 03.09.02
709 ****************************************************************************/
710
711 #define SECTIONS 100
712 #define DISTANTION 5
713
714 GLViewer_Polyline::GLViewer_Polyline( int number, float size, const QString& toolTip ):
715   GLViewer_Object(),
716   myNumber( 0 ),
717   myXCoord( 0 ),
718   myYCoord( 0 )       
719 {
720   myHighFlag = GL_TRUE;
721
722   myHNumbers.clear();
723   myUHNumbers.clear();
724   mySelNumbers.clear();
725   myUSelNumbers.clear();
726   myCurSelNumbers.clear();
727   myPrevHNumbers.clear();
728
729   setNumber( number );
730
731   myType = "GLViewer_Polyline";
732   myToolTipText = toolTip;
733 }
734
735 GLViewer_Polyline::~GLViewer_Polyline()
736 {
737   if ( myXCoord )
738     delete[] myXCoord;
739   if ( myYCoord )
740     delete[] myYCoord;
741 }
742
743 bool GLViewer_Polyline::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
744 {
745     QString aBuffer = "newpath\n";
746
747     AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
748
749     for( int i=0; i<myNumber; i++ )
750         if( i==0 )
751             AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
752         else
753             AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
754
755     if( myIsClosed )
756         AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[0], myYCoord[0] );
757
758     aBuffer+="closepath\nstroke\n";
759     
760     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
761
762     return true;
763 }
764
765 bool GLViewer_Polyline::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
766 {
767     QString aBuffer = "";
768     for( int i=0; i<myNumber; i++ )
769     {
770         AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[i], myYCoord[i] );
771         if( i==0 )
772             aBuffer+="PD;\n";
773     }
774
775     if( myIsClosed )
776         AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[0], myYCoord[0] );
777
778     aBuffer+="PU;\n";
779     
780     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
781
782     return true;
783 }
784
785 #ifdef WIN32
786 bool GLViewer_Polyline::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
787 {
788     if( !aViewerCS || !aEMFCS )
789         return false;
790     
791     HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
792     HGDIOBJ old = SelectObject( dc, pen );
793
794     double x, y;
795     for( int i=0; i<myNumber; i++ )
796     {
797         x = myXCoord[i];
798         y = myYCoord[i];
799         aViewerCS->transform( *aEMFCS, x, y );
800         if( i==0 )
801             MoveToEx( dc, x, y, NULL );
802         else
803             LineTo( dc, x, y );
804     }
805
806     if( myIsClosed )
807     {
808         x = myXCoord[0];
809         y = myYCoord[0];
810         aViewerCS->transform( *aEMFCS, x, y );
811         LineTo( dc, x, y );
812     }
813
814     SelectObject( dc, old );
815     if( pen )
816         DeleteObject( pen );
817
818     return true;
819 }
820 #endif
821
822 void GLViewer_Polyline::compute()
823 {
824 //  cout << "GLViewer_MarkerSet::compute" << endl;
825   GLfloat xa = myXCoord[0]; 
826   GLfloat xb = myXCoord[0]; 
827   GLfloat ya = myYCoord[0]; 
828   GLfloat yb = myYCoord[0]; 
829
830   for ( int i = 0; i < myNumber; i++ )  
831   {
832     xa = QMIN( xa, myXCoord[i] );
833     xb = QMAX( xb, myXCoord[i] );
834     ya = QMIN( ya, myYCoord[i] );
835     yb = QMAX( yb, myYCoord[i] );
836   }
837
838   GLfloat xGap = ( xb - xa ) / 10;
839   GLfloat yGap = ( yb - ya ) / 10;
840
841   myRect->setLeft( xa - xGap );
842   myRect->setTop( yb + yGap ); 
843   myRect->setRight( xb + xGap );
844   myRect->setBottom( ya - yGap );
845 }
846
847 GLViewer_Rect* GLViewer_Polyline::getUpdateRect()
848 {
849     GLViewer_Rect* rect = new GLViewer_Rect();
850
851     rect->setLeft( myRect->left() - myXGap );
852     rect->setTop( myRect->top() + myYGap ); 
853     rect->setRight( myRect->right() + myXGap );
854     rect->setBottom( myRect->bottom() - myYGap );
855
856     return rect;
857 }
858
859 GLViewer_Drawer* GLViewer_Polyline::createDrawer()
860 {
861 //  cout << "GLViewer_MarkerSet::createDrawer" << endl;
862     return myDrawer = new GLViewer_PolylineDrawer();
863 }
864
865 GLboolean GLViewer_Polyline::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
866 {
867     if( !myIsVisible )
868         return false;
869     GLfloat xa, xb, ya, yb, l;
870     GLfloat rsin, rcos, r, ra, rb;
871     GLboolean update;
872     GLboolean highlighted = myIsHigh;
873
874     myIsHigh = GL_FALSE;
875
876     int c = 0;
877     if( myIsClosed )
878         c = 1;
879
880     for( int i = 0; i < myNumber-1+c; i++ ) 
881     {
882         xa = myXCoord[i];
883         ya = myYCoord[i];
884         if( i != myNumber-1 )
885         {
886               xb = myXCoord[i+1];
887               yb = myYCoord[i+1];
888         }
889         else
890         {    
891               xb = myXCoord[0];      
892               yb = myYCoord[0];
893         }
894
895         l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
896         rsin = (yb-ya) / l;
897         rcos = (xb-xa) / l;
898         r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
899         ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
900         rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
901         if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
902         {
903             myIsHigh = GL_TRUE;
904             break;
905         }
906     }
907
908     if( !myHighFlag && myIsHigh )
909         myIsHigh = GL_FALSE;
910     else
911         myHighFlag = GL_TRUE;
912
913     update = ( GLboolean )( myIsHigh != highlighted );
914
915 //  cout << "GLViewer_Polyline::highlight complete with " << (int)myIsHigh << endl;
916     return update;
917 }
918
919 GLboolean GLViewer_Polyline::unhighlight()
920 {
921 //   if( !myHNumbers.isEmpty() )
922 //   {
923 //     myUHNumbers = myHNumbers;
924 //     myHNumbers.clear();
925 //     return GL_TRUE;
926 //   }
927
928   if( myIsHigh )
929   {
930     myIsHigh = GL_FALSE;
931     return GL_TRUE;
932   }
933
934   return GL_FALSE;
935 }
936
937 GLboolean GLViewer_Polyline::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
938                                      GLboolean isCircle, GLboolean isShift )
939 {
940     if( !myIsVisible )
941         return false;
942     GLfloat xa, xb, ya, yb, l;
943     GLfloat rsin, rcos, r, ra, rb;
944     GLboolean update;
945     GLboolean selected = myIsSel;
946
947     myIsSel = GL_FALSE;
948
949     int c = 0;
950     if( myIsClosed )
951         c = 1;
952
953     for( int i = 0; i < myNumber-1+c; i++ ) 
954     {
955         xa = myXCoord[i];
956         ya = myYCoord[i];
957         if( i != myNumber-1 )
958         {
959             xb = myXCoord[i+1];
960             yb = myYCoord[i+1];
961         }
962         else
963         {
964             xb = myXCoord[0];
965             yb = myYCoord[0];
966         }
967
968         l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
969         rsin = (yb-ya) / l;
970         rcos = (xb-xa) / l;
971         r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
972         ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
973         rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
974         if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
975         {
976             myIsSel = GL_TRUE;
977             break;
978         }
979     }
980
981     if ( myIsSel )
982     {
983         myHighFlag = GL_FALSE;
984         myIsHigh = GL_FALSE;
985     }
986     else
987         myHighFlag = GL_TRUE;
988
989     update = ( GLboolean )( myIsSel != selected );
990
991     //  cout << "GLViewer_Polyline::select complete with " << (int)myIsSel << endl;
992
993     //  return update;  !!!!!!!!!!!!!!!!!!!!!!!!!!! no here
994     return myIsSel;
995 }
996
997 GLboolean GLViewer_Polyline::unselect()
998 {
999 //   if( !mySelNumbers.isEmpty() )
1000 //   {
1001 //     myUSelNumbers = mySelNumbers;
1002 //     mySelNumbers.clear();
1003 //     myCurSelNumbers.clear();
1004 //     return GL_TRUE;
1005 //   }
1006
1007   if( myIsSel )
1008   {
1009     myIsSel = GL_FALSE;
1010     return GL_TRUE;
1011   }
1012
1013   return GL_FALSE;
1014 }
1015
1016 void GLViewer_Polyline::setXCoord( GLfloat* xCoord, int size )
1017 {
1018   myXCoord = new GLfloat[ size ];
1019   for( int i = 0; i < size; i++ )
1020      myXCoord[i] = xCoord[i];
1021 }
1022
1023 void GLViewer_Polyline::setYCoord( GLfloat* yCoord, int size )
1024 {
1025   myYCoord = new GLfloat[ size ];
1026   for( int i = 0; i < size; i++ )
1027      myYCoord[i] = yCoord[i];
1028 }
1029
1030 void GLViewer_Polyline::setNumber( GLint number )
1031 {
1032   if ( myNumber == number )
1033     return;
1034     
1035   if ( myXCoord && myYCoord )
1036   {
1037     delete[] myXCoord;
1038     delete[] myYCoord;
1039   }
1040
1041   myNumber = number;
1042   myXCoord = new GLfloat[ myNumber ];
1043   myYCoord = new GLfloat[ myNumber ];
1044 }
1045 /*
1046 void GLViewer_Polyline::onSelectionDone( bool append)
1047 {
1048   mySelectedIndexes.Clear();
1049   QValueList<int>::Iterator it;
1050   //for( it = myMarkers->mySelNumbers.begin(); it != myMarkers->mySelNumbers.end(); ++it )
1051   //  mySelectedIndexes.Append( *it / 2 ); //!!!
1052 }
1053
1054 void GLViewer_Polyline::onSelectionCancel()
1055 {
1056   mySelectedIndexes.Clear();
1057 }
1058 */
1059 void GLViewer_Polyline::exportNumbers( QValueList<int>& highlight,
1060                      QValueList<int>& unhighlight,
1061                      QValueList<int>& select,
1062                      QValueList<int>& unselect )
1063 {
1064   highlight = myHNumbers;
1065   unhighlight = myUHNumbers;
1066   select = mySelNumbers;
1067   unselect = myUSelNumbers;
1068 }
1069
1070 void GLViewer_Polyline::moveObject( float theX, float theY, bool fromGroup )
1071 {
1072   if( !fromGroup && myGroup)
1073   {
1074     myGroup->dragingObjects( theX, theY );
1075     return;
1076   }
1077   for( int i = 0; i < myNumber;  i++ )
1078   {
1079       myXCoord[i] = myXCoord[i] + theX;
1080       myYCoord[i] = myYCoord[i] + theY;
1081   }
1082   compute();    
1083 }
1084
1085 QByteArray GLViewer_Polyline::getByteCopy()
1086 {
1087     int i = 0;
1088     int anISize = sizeof( GLint );
1089     int aFSize = sizeof( GLfloat );
1090     int aBSize = sizeof( GLboolean );
1091
1092     QByteArray aObject = GLViewer_Object::getByteCopy();
1093
1094     QByteArray aResult( aFSize*myNumber*2 + anISize + 2*aBSize + aObject.size());
1095
1096     char* aPointer = (char*)&myNumber;
1097     for( i = 0; i < anISize; i++, aPointer++ )
1098         aResult[i] = *aPointer;
1099
1100     aPointer = (char*)myXCoord;
1101     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1102         aResult[i] = *aPointer;
1103     aPointer = (char*)myYCoord;
1104     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1105         aResult[i] = *aPointer;
1106     
1107     aPointer = (char*)&myIsClosed;
1108     for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1109         aResult[i] = *aPointer;
1110     aPointer = (char*)&myHighSelAll;
1111     for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1112         aResult[i] = *aPointer;
1113
1114     for( ; i < aResult.size(); i++ )
1115         aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - 2*aBSize];
1116
1117     return aResult;
1118 }
1119
1120
1121 bool GLViewer_Polyline::initializeFromByteCopy( QByteArray theArray )
1122 {
1123     int i = 0;
1124     int anISize = sizeof( GLint );
1125     int aFSize = sizeof( GLfloat );
1126     int aBSize = sizeof( GLboolean );
1127
1128     char* aPointer = (char*)&myNumber;
1129     for( i = 0; i < anISize; i++, aPointer++ )
1130         *aPointer = theArray[i];
1131
1132     int aSize = theArray.size();
1133     if( aSize < aFSize*myNumber*2 + anISize + 2*aBSize )
1134         return false;
1135
1136     myXCoord = new GLfloat[myNumber];
1137     myYCoord = new GLfloat[myNumber];
1138     aPointer = (char*)myXCoord;
1139     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1140         *aPointer = theArray[i];
1141     aPointer = (char*)myYCoord;
1142     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1143         *aPointer = theArray[i];
1144
1145     aPointer = (char*)&myIsClosed;
1146     for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1147          *aPointer = theArray[i];
1148     aPointer = (char*)&myHighSelAll;
1149     for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1150          *aPointer = theArray[i];
1151
1152     int aCurIndex = anISize + 2*aFSize*myNumber + 2*aBSize;
1153     QByteArray aObject( aSize - aCurIndex );
1154     for( ; i < aSize; i++ )
1155         aObject[i - aCurIndex] = theArray[i];
1156
1157     if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_Polyline" )
1158         return false;
1159
1160     myHNumbers.clear();
1161     myUHNumbers.clear();
1162     mySelNumbers.clear();
1163     myUSelNumbers.clear();
1164     myCurSelNumbers.clear();
1165     myPrevHNumbers.clear();
1166
1167     return true;        
1168 }
1169
1170 /***************************************************************************
1171 **  Class:   GLViewer_TextObject
1172 **  Descr:   Text as Object for OpenGL
1173 **  Module:  GLViewer
1174 **  Created: UI team, 12.02.04
1175 ****************************************************************************/
1176
1177 GLViewer_TextObject::GLViewer_TextObject( const QString& theStr, float xPos, float yPos, 
1178                                     const QColor& color, const QString& toolTip )
1179                                     : GLViewer_Object()
1180 {
1181     myGLText = new GLViewer_Text( theStr, xPos, yPos, color );
1182     myWidth = 0;
1183     myHeight = 0;
1184
1185     myHighFlag = GL_TRUE;
1186
1187     myToolTipText = toolTip;
1188 }
1189 GLViewer_TextObject::~GLViewer_TextObject()
1190 {
1191   if ( myGLText )
1192     delete myGLText;
1193 }
1194
1195 bool GLViewer_TextObject::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
1196 {
1197     QString aText = myGLText->getText();    
1198     float xPos, yPos;
1199     myGLText->getPosition( xPos, yPos );
1200
1201     QString aBuffer = "/Times-Roman findfont\n";
1202     aBuffer += "12 scalefont setfont\n";
1203
1204     AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, double(xPos), double(yPos) );
1205     aBuffer += "(" + aText + ") show\n";
1206
1207     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1208
1209     return true;
1210 }
1211
1212 bool GLViewer_TextObject::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
1213 {
1214     QString aText = myGLText->getText();    
1215     float xPos, yPos;
1216     myGLText->getPosition( xPos, yPos );
1217
1218     QString aBuffer = "";
1219     AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, double(xPos), double(yPos) );
1220     
1221     aBuffer = "LB" + aText + "#;";
1222     
1223     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1224
1225     return true;
1226 }
1227
1228 #ifdef WIN32
1229 bool GLViewer_TextObject::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
1230 {
1231     QString aText = myGLText->getText();    
1232     float xPos, yPos;
1233     myGLText->getPosition( xPos, yPos );
1234
1235     double x = double( xPos ), 
1236            y = double( yPos );
1237
1238     aViewerCS->transform( *aEMFCS, x, y );
1239     const char* str = aText.ascii();
1240
1241     int nHeight = 35*14;       // height of font
1242     int nWidth = 35*12;        // average character width
1243     int nEscapement = 0;       // angle of escapement
1244     int nOrientation = 0;      // base-line orientation angle
1245     int fnWeight = FW_NORMAL;  // font weight
1246     DWORD fdwItalic = FALSE;    // italic attribute option
1247     DWORD fdwUnderline = FALSE; // underline attribute option
1248     DWORD fdwStrikeOut = FALSE; // strikeout attribute option
1249     DWORD fdwCharSet = ANSI_CHARSET; // character set identifier
1250     DWORD fdwOutputPrecision = OUT_DEFAULT_PRECIS;  // output precision
1251     DWORD fdwClipPrecision = CLIP_DEFAULT_PRECIS;    // clipping precision
1252     DWORD fdwQuality = PROOF_QUALITY;          // output quality
1253     DWORD fdwPitchAndFamily = FIXED_PITCH | FF_DONTCARE;   // pitch and family
1254     LPCTSTR lpszFace = NULL;         // typeface name
1255
1256
1257     HFONT aFont = CreateFont( nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic,
1258                               fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision, 
1259                               fdwClipPrecision, fdwQuality, fdwPitchAndFamily, lpszFace );
1260     LOGBRUSH aBrushData;
1261     aBrushData.lbStyle = BS_HOLLOW;
1262
1263     HBRUSH aBrush = CreateBrushIndirect( &aBrushData );
1264
1265     HGDIOBJ old1 = SelectObject( dc, aFont );
1266     HGDIOBJ old2 = SelectObject( dc, aBrush );
1267
1268     TextOut( dc, x, y, str, aText.length() );
1269
1270     SelectObject ( dc, old1 );
1271     SelectObject ( dc, old2 );
1272
1273     DeleteObject( aFont );
1274
1275     return true;
1276 }
1277 #endif
1278
1279 GLViewer_Drawer* GLViewer_TextObject::createDrawer()
1280 {
1281     myDrawer = new GLViewer_TextDrawer();
1282     compute();
1283     return myDrawer;
1284 }
1285
1286 void GLViewer_TextObject::compute()
1287 {
1288     float xPos, yPos;
1289     QString aStr = myGLText->getText();
1290     myGLText->getPosition( xPos, yPos );
1291
1292     myWidth = myGLText->getWidth();
1293     myHeight = myGLText->getHeight();
1294     myRect->setLeft( xPos );
1295     myRect->setTop( yPos + myHeight  ); 
1296     myRect->setRight( xPos + myWidth );
1297     myRect->setBottom( yPos );
1298 }
1299
1300 void GLViewer_TextObject::setDrawer( GLViewer_Drawer* theDrawer )
1301 {
1302     myDrawer = theDrawer;
1303     //compute();
1304 }
1305
1306 GLViewer_Rect* GLViewer_TextObject::getUpdateRect()
1307 {    
1308     GLViewer_Rect* rect = new GLViewer_Rect();
1309
1310     float xPos, yPos;
1311     QString aStr = myGLText->getText();
1312     myGLText->getPosition( xPos, yPos );
1313
1314     rect->setLeft( myRect->left() + myXGap - myWidth / myXScale );
1315     rect->setTop( myRect->top() + myYGap + myHeight / myYScale );
1316     rect->setRight( myRect->right() - myXGap + myWidth / myXScale );
1317     rect->setBottom( myRect->bottom() - myYGap - myHeight / myYScale );
1318
1319     return rect;
1320 }
1321
1322 GLboolean GLViewer_TextObject::highlight( GLfloat theX, GLfloat theY, GLfloat theTol, GLboolean isCircle )
1323 {
1324     if( !myIsVisible )
1325         return false;
1326
1327     float xPos, yPos;
1328     myGLText->getPosition( xPos, yPos );
1329
1330     QRect aRect;
1331     aRect.setLeft( (int)xPos );
1332     aRect.setRight( (int)(xPos + myWidth / myXScale) );
1333     aRect.setTop( (int)yPos );// - myHeight / myYScale );
1334     aRect.setBottom( (int)(yPos + myHeight / myYScale) );
1335
1336     //cout << "theX: " << theX << "  theY: " << theY << endl;
1337     //cout << "aRect.left(): " << aRect.left() << "  aRect.right(): " << aRect.right() << endl;
1338     //cout << "aRect.top(): " << aRect.top() << "  aRect.bottom(): " << aRect.bottom() << endl;
1339
1340     QRegion obj( aRect );
1341     QRegion intersection;
1342     QRect region;
1343
1344     region.setLeft( (int)(theX - theTol) );
1345     region.setRight( (int)(theX + theTol) );
1346     region.setTop( (int)(theY - theTol) );
1347     region.setBottom( (int)(theY + theTol) );
1348
1349     QRegion circle( (int)(theX - theTol), (int)(theY - theTol),
1350                       (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1351     if( isCircle )
1352         intersection = obj.intersect( circle );
1353     else
1354         intersection = obj.intersect( region );
1355     
1356     if( intersection.isEmpty() )
1357         myIsHigh = false;
1358     else
1359         myIsHigh = true;
1360     
1361     if( !myHighFlag && myIsHigh )
1362         myIsHigh = GL_FALSE;
1363     else
1364         myHighFlag = GL_TRUE;
1365
1366     return myIsHigh;
1367 }
1368
1369 GLboolean GLViewer_TextObject::unhighlight()
1370 {
1371     if( myIsHigh )
1372     {
1373         myIsHigh = GL_FALSE;
1374         return GL_TRUE;
1375     }
1376
1377     return GL_FALSE;
1378 }
1379
1380 GLboolean GLViewer_TextObject::select( GLfloat theX, GLfloat theY, GLfloat theTol, GLViewer_Rect rect,
1381                                        GLboolean isFull, GLboolean isCircle, GLboolean isShift )
1382
1383     if( !myIsVisible )
1384         return false;
1385
1386     QRegion obj( myRect->toQRect() );
1387     QRegion intersection;
1388     QRect region;
1389
1390     region.setLeft( (int)(theX - theTol) );
1391     region.setRight( (int)(theX + theTol) );
1392     region.setTop( (int)(theY - theTol) );
1393     region.setBottom( (int)(theY + theTol) );
1394
1395     QRegion circle( (int)(theX - theTol), (int)(theY - theTol),
1396                       (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1397     if( isCircle )
1398         intersection = obj.intersect( circle );
1399     else
1400         intersection = obj.intersect( region );
1401     
1402     if( intersection.isEmpty() )
1403         myIsSel = false;
1404     else
1405         myIsSel = true;
1406
1407     if ( myIsSel )
1408     {
1409         myHighFlag = GL_FALSE;
1410         myIsHigh = GL_FALSE;
1411     }
1412     else
1413         myHighFlag = GL_TRUE;
1414
1415     return myIsSel;
1416 }
1417
1418 GLboolean GLViewer_TextObject::unselect()
1419 {
1420     if( myIsSel )
1421     {
1422         myIsSel = GL_FALSE;
1423         return GL_TRUE;
1424     }
1425
1426     return GL_FALSE;
1427 }
1428
1429 void GLViewer_TextObject::moveObject( float theX, float theY, bool fromGroup )
1430 {
1431   if( !fromGroup && myGroup)
1432   {
1433     myGroup->dragingObjects( theX, theY );
1434     return;
1435   }
1436   float aX, anY;
1437   myGLText->getPosition( aX, anY );
1438   aX += theX;
1439   anY += theY;
1440   myGLText->setPosition( aX, anY );
1441   compute();
1442 }
1443
1444 QByteArray GLViewer_TextObject::getByteCopy()
1445 {
1446     QByteArray aObject = GLViewer_Object::getByteCopy();
1447
1448     return aObject;
1449 }
1450
1451 bool GLViewer_TextObject::initializeFromByteCopy( QByteArray theArray )
1452 {
1453     if( !GLViewer_Object::initializeFromByteCopy( theArray ) || myType != "GLViewer_TextObject" )
1454         return false;
1455
1456     myHighFlag = true;
1457     return true;        
1458 }