Salome HOME
PAL10870 - to improve export of Plot2d to PostScript
[modules/gui.git] / src / Plot2d / Plot2d_ViewFrame.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "Plot2d_ViewFrame.h"
20
21 #include "Plot2d_Prs.h"
22 #include "Plot2d_Curve.h"
23 #include "Plot2d_FitDataDlg.h"
24 #include "Plot2d_ViewWindow.h"
25 #include "Plot2d_SetupViewDlg.h"
26
27 #include "SUIT_Tools.h"
28 #include "SUIT_Session.h"
29 #include "SUIT_MessageBox.h"
30 #include "SUIT_ResourceMgr.h"
31 #include "SUIT_Application.h"
32
33 #include "qapplication.h"
34 #include <qtoolbar.h>
35 #include <qtoolbutton.h>
36 #include <qcursor.h>
37 #include <qcolordialog.h>
38 #include <qptrlist.h>
39 #include <qlayout.h>
40 #include <qmap.h>
41 #include <qpainter.h>
42 #include <qpaintdevicemetrics.h>
43
44 #include <qwt_math.h>
45 #include <qwt_plot_canvas.h>
46 #include <iostream>
47 #include <stdlib.h>
48 #include <qprinter.h>
49
50 #include <qwt_legend.h>
51
52 #define DEFAULT_LINE_WIDTH     0     // (default) line width
53 #define DEFAULT_MARKER_SIZE    9     // default marker size
54 #define MIN_RECT_SIZE          11    // min sensibility area size
55
56 const char* imageZoomCursor[] = { 
57 "32 32 3 1",
58 ". c None",
59 "a c #000000",
60 "# c #ffffff",
61 "................................",
62 "................................",
63 ".#######........................",
64 "..aaaaaaa.......................",
65 "................................",
66 ".............#####..............",
67 "...........##.aaaa##............",
68 "..........#.aa.....a#...........",
69 ".........#.a.........#..........",
70 ".........#a..........#a.........",
71 "........#.a...........#.........",
72 "........#a............#a........",
73 "........#a............#a........",
74 "........#a............#a........",
75 "........#a............#a........",
76 ".........#...........#.a........",
77 ".........#a..........#a.........",
78 ".........##.........#.a.........",
79 "........#####.....##.a..........",
80 ".......###aaa#####.aa...........",
81 "......###aa...aaaaa.......#.....",
82 ".....###aa................#a....",
83 "....###aa.................#a....",
84 "...###aa...............#######..",
85 "....#aa.................aa#aaaa.",
86 ".....a....................#a....",
87 "..........................#a....",
88 "...........................a....",
89 "................................",
90 "................................",
91 "................................",
92 "................................"};
93
94 const char* imageCrossCursor[] = { 
95   "32 32 3 1",
96   ". c None",
97   "a c #000000",
98   "# c #ffffff",
99   "................................",
100   "................................",
101   "................................",
102   "................................",
103   "................................",
104   "................................",
105   "................................",
106   "...............#................",
107   "...............#a...............",
108   "...............#a...............",
109   "...............#a...............",
110   "...............#a...............",
111   "...............#a...............",
112   "...............#a...............",
113   "...............#a...............",
114   ".......#################........",
115   "........aaaaaaa#aaaaaaaaa.......",
116   "...............#a...............",
117   "...............#a...............",
118   "...............#a...............",
119   "...............#a...............",
120   "...............#a...............",
121   "...............#a...............",
122   "...............#a...............",
123   "................a...............",
124   "................................",
125   "................................",
126   "................................",
127   "................................",
128   "................................",
129   "................................",
130   "................................"};
131   
132
133 QPixmap zoomPixmap(imageZoomCursor);
134 QPixmap globalPanPixmap(imageCrossCursor);
135
136 QCursor panCursor(Qt::SizeAllCursor);
137 QCursor zoomCursor(zoomPixmap);
138 QCursor glPanCursor(globalPanPixmap);
139
140 //=================================================================================
141 // Plot2d_ViewFrame implementation
142 //=================================================================================
143
144 /*!
145   Constructor
146 */
147 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
148      : QWidget (parent, title, 0),
149        myOperation( NoOpId ), 
150        myCurveType( 1 ), 
151        myShowLegend( true ), myLegendPos( 1 ),
152        myMarkerSize( DEFAULT_MARKER_SIZE ),
153        myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
154        myBackground( white ),
155        myTitleEnabled( true ), myXTitleEnabled( true ),
156        myYTitleEnabled( true ), myY2TitleEnabled (true),
157        myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ), 
158        myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
159        myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
160        myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
161        myXMode( 0 ), myYMode( 0 ), mySecondY( false )
162 {
163   /* Plot 2d View */
164   QVBoxLayout* aLayout = new QVBoxLayout( this ); 
165   myPlot = new Plot2d_Plot2d( this );
166   aLayout->addWidget( myPlot );
167
168 //  createActions();
169
170   connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
171      this,   SLOT( plotMouseMoved( const QMouseEvent& ) ) );
172   connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
173      this,   SLOT( plotMousePressed( const QMouseEvent& ) ) );
174   connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
175      this,   SLOT( plotMouseReleased( const QMouseEvent& ) ) );
176   //connect( myPlot, SIGNAL( legendClicked( long ) ),
177   //   this,   SLOT( onLegendClicked( long ) ) );
178
179   /* Initial Setup - get from the preferences */
180   readPreferences();
181
182   myPlot->setMargin( 5 );
183   setCurveType( myCurveType, false );
184   setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
185   setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
186             myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
187
188   setTitle( myTitleEnabled,  myTitle,  MainTitle, false );
189   setTitle( myXTitleEnabled, myXTitle, XTitle, false );
190   setTitle( myYTitleEnabled, myYTitle, YTitle, false );
191
192   if (mySecondY)
193     setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
194   setHorScaleMode( myXMode, false );
195   setVerScaleMode( myYMode, false );
196   setBackgroundColor( myBackground );
197   setLegendPos( myLegendPos );
198   showLegend( myShowLegend, false );
199   myPlot->replot();
200
201   if ( parent ) {
202     resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
203   }
204   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
205   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
206   myXDistance = xMap.d2() - xMap.d1();
207   myYDistance = yMap.d2() - yMap.d1();
208   myYDistance2 = 0;
209   if (mySecondY) {
210     QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
211     myYDistance2 = yMap2.d2() - yMap2.d1();
212   }
213 }
214 /*!
215   Destructor
216 */
217 Plot2d_ViewFrame::~Plot2d_ViewFrame()
218 {
219 }
220 /*!
221   Gets window's central widget
222 */
223 QWidget* Plot2d_ViewFrame::getViewWidget()
224 {
225   return (QWidget*)myPlot;
226 }
227 /*!
228   Actually this method just re-displays all curves which are presented in the viewer
229 */
230 void Plot2d_ViewFrame::DisplayAll()
231 {
232   QList<Plot2d_Curve> clist;
233   getCurves( clist );
234   for ( int i = 0; i < (int)clist.count(); i++ ) {
235     updateCurve( clist.at( i ), false );
236   }
237   myPlot->replot();
238 }
239 /*!
240    Removes all curves from the view
241 */
242 void Plot2d_ViewFrame::EraseAll() 
243 {
244   myPlot->clear();
245   myCurves.clear();
246   myPlot->replot();
247 }
248 /*!
249   Redraws viewframe contents
250 */
251 void Plot2d_ViewFrame::Repaint()
252 {
253   myPlot->replot();
254 }
255 /*!
256   Display presentation
257 */
258 void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
259 {
260   if ( !prs || prs->IsNull() )
261     return;
262
263   if (prs->isSecondY()) {
264     myPlot->enableAxis(QwtPlot::yRight, true);
265     mySecondY = true;
266   }
267   else {
268     myPlot->enableAxis(QwtPlot::yRight, false);
269     mySecondY = false;
270   }
271
272   // display all curves from presentation
273   curveList aCurves = prs->getCurves();
274   displayCurves( aCurves );
275   setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
276   setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
277             myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
278 }
279
280 /*!
281   Erase presentation
282 */
283 void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
284 {
285   if ( !prs || prs->IsNull() )
286     return;
287
288   // erase all curves from presentation
289   curveList aCurves = prs->getCurves();
290   eraseCurves( aCurves );
291 }
292
293 /*!
294   Sets title
295 */
296 void Plot2d_ViewFrame::setTitle( const QString& title )
297 {
298   setTitle( myTitleEnabled, title, MainTitle, true );
299 }
300
301 /*!
302   Reads Plot2d view settings from the preferences
303 */
304 void Plot2d_ViewFrame::readPreferences()
305 {
306   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
307
308   myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
309   if ( myCurveType < 1 || myCurveType > 2 )
310     myCurveType = 1;
311   myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
312   myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
313   myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
314   myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
315
316   myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
317   myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
318   myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
319   myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
320
321   myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
322   myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
323   myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
324
325   myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
326   myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
327   myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
328
329   myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
330   myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
331   if ( mySecondY )
332     myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
333
334   myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
335   myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
336   if ( mySecondY )
337     myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
338
339   myXMode = resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode );
340   myXMode = QMAX( 0, QMIN( 1, myXMode ) );
341
342   myYMode = resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode );
343   myYMode = QMAX( 0, QMIN( 1, myYMode ) );
344 }
345
346 /*!
347   Writes Plot2d view settings to the preferences
348 */
349 void Plot2d_ViewFrame::writePreferences()
350 {
351   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
352
353   resMgr->setValue( "Plot2d", "CurveType", myCurveType );
354   resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
355   resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
356   resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
357   resMgr->setValue( "Plot2d", "Background", myBackground );
358   resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
359   resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
360   resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
361   if ( mySecondY )
362     resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
363
364   resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
365   resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
366   resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
367   resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
368
369   resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
370   resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
371
372   resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
373   resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
374
375   resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
376
377   if ( mySecondY )
378   {
379     resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
380     resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
381     resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
382     resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
383   }
384
385   resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
386 }
387
388 /*!
389   Prints mouse cursor coordinates into string
390 */
391 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt ) 
392 {
393   int i;
394   bool xFound = false, yFound = false;
395   double xCoord, yCoord;
396   const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
397   for ( i = 0; i < aXscale->majCnt(); i++ ) {
398     double majXmark = aXscale->majMark( i );
399     int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
400     if ( xmark-2 == pnt.x() ) {
401       xCoord = majXmark; 
402       xFound = true;
403       break;
404     }
405   }
406   if ( !xFound ) {
407     for ( i = 0; i < aXscale->minCnt(); i++ ) {
408       double minXmark = aXscale->minMark( i );
409       int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
410       if ( xmark-2 == pnt.x() ) {
411         xCoord = minXmark; 
412         xFound = true;
413         break;
414       }
415     }
416   }  
417   const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
418   for ( i = 0; i < aYscale->majCnt(); i++ ) {
419     double majYmark = aYscale->majMark( i );
420     int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
421     if ( ymark-2 == pnt.y() ) {
422       yCoord = majYmark; 
423       yFound = true;
424       break;
425     }
426   }
427   if ( !yFound ) {
428     for ( i = 0; i < aYscale->minCnt(); i++ ) {
429       double minYmark = aYscale->minMark( i );
430       int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
431       if ( ymark-2 == pnt.y() ) {
432         yCoord = minYmark; 
433         yFound = true;
434         break;
435       }
436     }
437   }  
438
439   QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
440   if ( strX == "-0" )
441     strX = "0";
442   QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
443   if ( strY == "-0" )
444     strY = "0";
445   QString info = "";
446
447   if (mySecondY) {
448     bool yFound2 = false;
449     double yCoord2;
450
451     const QwtScaleDiv* aYscale2 = myPlot->axisScale( QwtPlot::yRight );
452     for ( i = 0; i < aYscale2->majCnt(); i++ ) {
453       double majYmark = aYscale2->majMark( i );
454       int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
455       if ( ymark-2 == pnt.y() ) {
456         yCoord2 = majYmark; 
457         yFound2 = true;
458         break;
459       }
460     }
461     if ( !yFound2 ) {
462       for ( i = 0; i < aYscale2->minCnt(); i++ ) {
463         double minYmark = aYscale2->minMark( i );
464         int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
465         if ( ymark-2 == pnt.y() ) {
466           yCoord2 = minYmark; 
467           yFound2 = true;
468           break;
469         }
470       }
471     }
472     QString strY2 = QString::number( yFound2 ? yCoord2 : 
473                       myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).stripWhiteSpace();
474     if ( strY2 == "-0" )
475     strY2 = "0";
476     info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
477   }
478   else
479     info = tr("INF_COORDINATES").arg( strX ).arg( strY );
480
481   return info;
482 }
483
484 /*!
485   Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
486 */
487 static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
488 {
489   QwtSymbol::Style ms = QwtSymbol::None;  
490   switch ( m ) {
491   case Plot2d_Curve::Circle:
492     ms = QwtSymbol::Ellipse;   break;
493   case Plot2d_Curve::Rectangle:
494     ms = QwtSymbol::Rect;      break;
495   case Plot2d_Curve::Diamond:
496     ms = QwtSymbol::Diamond;   break;
497   case Plot2d_Curve::DTriangle:
498     ms = QwtSymbol::DTriangle; break;
499   case Plot2d_Curve::UTriangle:
500     ms = QwtSymbol::UTriangle; break;
501   case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
502     ms = QwtSymbol::RTriangle; break;
503   case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
504     ms = QwtSymbol::LTriangle; break;
505   case Plot2d_Curve::Cross:
506     ms = QwtSymbol::Cross;     break;
507   case Plot2d_Curve::XCross:
508     ms = QwtSymbol::XCross;    break;
509   case Plot2d_Curve::None:
510   default:
511     ms = QwtSymbol::None;      break;
512   }
513   return ms;
514 }
515
516 /*!
517   Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
518 */
519 static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
520 {
521   Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;  
522   switch ( m ) {
523   case QwtSymbol::Ellipse:
524     ms = Plot2d_Curve::Circle;    break;
525   case QwtSymbol::Rect:
526     ms = Plot2d_Curve::Rectangle; break;
527   case QwtSymbol::Diamond:
528     ms = Plot2d_Curve::Diamond;   break;
529   case QwtSymbol::DTriangle:
530     ms = Plot2d_Curve::DTriangle; break;
531   case QwtSymbol::UTriangle:
532     ms = Plot2d_Curve::UTriangle; break;
533   case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
534     ms = Plot2d_Curve::LTriangle; break;
535   case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
536     ms = Plot2d_Curve::RTriangle; break;
537   case QwtSymbol::Cross:
538     ms = Plot2d_Curve::Cross;     break;
539   case QwtSymbol::XCross:
540     ms = Plot2d_Curve::XCross;    break;
541   case QwtSymbol::None:
542   default:
543     ms = Plot2d_Curve::None;      break;
544   }
545   return ms;
546 }
547
548 /*!
549   Converts Plot2d_Curve's line style to Qwt line style [ static ]
550 */
551 static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
552 {
553   Qt::PenStyle ps = Qt::NoPen;
554   switch ( p ) {
555   case Plot2d_Curve::Solid:
556     ps = Qt::SolidLine;      break;
557   case Plot2d_Curve::Dash:
558     ps = Qt::DashLine;       break;
559   case Plot2d_Curve::Dot:
560     ps = Qt::DotLine;        break;
561   case Plot2d_Curve::DashDot:
562     ps = Qt::DashDotLine;    break;
563   case Plot2d_Curve::DashDotDot:
564     ps = Qt::DashDotDotLine; break;
565   case Plot2d_Curve::NoPen:
566   default:
567     ps = Qt::NoPen;          break;
568   }
569   return ps;
570 }
571
572 /*!
573   Converts Qwt line style to Plot2d_Curve's line style [ static ]
574 */
575 static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
576 {
577   Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
578   switch ( p ) {
579   case Qt::SolidLine:
580     ps = Plot2d_Curve::Solid;      break;
581   case Qt::DashLine:
582     ps = Plot2d_Curve::Dash;       break;
583   case Qt::DotLine:
584     ps = Plot2d_Curve::Dot;        break;
585   case Qt::DashDotLine:
586     ps = Plot2d_Curve::DashDot;    break;
587   case Qt::DashDotDotLine:
588     ps = Plot2d_Curve::DashDotDot; break;
589   case Qt::NoPen:
590   default:
591     ps = Plot2d_Curve::NoPen;      break;
592   }
593   return ps;
594 }
595
596 /*!
597   Adds curve into view
598 */
599 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
600 {
601   if ( !curve )
602     return;
603   if ( hasCurve( curve ) ) {
604     updateCurve( curve, update );
605   }
606   else {
607     long curveKey = myPlot->insertCurve( curve->getVerTitle() );
608     myPlot->setCurveYAxis(curveKey, curve->getYAxis());
609
610     myCurves.insert( curveKey, curve );
611     if ( curve->isAutoAssign() ) {
612       QwtSymbol::Style typeMarker;
613       QColor           color;
614       Qt::PenStyle     typeLine;
615       myPlot->getNextMarker( typeMarker, color, typeLine );
616       myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
617       myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker, 
618                QBrush( color ), 
619                QPen( color ), 
620                QSize( myMarkerSize, myMarkerSize ) ) );
621       curve->setColor( color );
622       curve->setLine( qwt2plotLine( typeLine ) );
623       curve->setMarker( qwt2plotMarker( typeMarker ) );
624     }
625     else {
626       Qt::PenStyle     ps = plot2qwtLine( curve->getLine() );
627       QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
628       myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
629       myPlot->setCurveSymbol( curveKey, QwtSymbol( ms, 
630                QBrush( curve->getColor() ), 
631                QPen( curve->getColor() ), 
632                QSize( myMarkerSize, myMarkerSize ) ) );
633     }
634     if ( myCurveType == 0 )
635       myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
636     else if ( myCurveType == 1 )
637       myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
638     else if ( myCurveType == 2 )
639       myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
640     myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
641   }
642   updateTitles();
643   if ( update )
644     myPlot->replot();
645 }
646
647 /*!
648   Adds curves into view
649 */
650 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
651 {
652   myPlot->setUpdatesEnabled( false );
653   QPtrListIterator<Plot2d_Curve> it(curves);
654   Plot2d_Curve* aCurve;
655   while( (aCurve = it.current()) ) {
656     displayCurve( aCurve, false );
657     ++it;
658   }
659
660   fitAll();
661   myPlot->setUpdatesEnabled( true );
662   if ( update )
663     myPlot->replot();
664 }
665
666 /*!
667   Erases curve
668 */
669 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
670 {
671   if ( !curve )
672     return;
673   int curveKey = hasCurve( curve );
674   if ( curveKey ) {
675     myPlot->removeCurve( curveKey );
676     myCurves.remove( curveKey );
677     if ( update )
678       myPlot->replot();
679   }
680 }
681
682 /*!
683   Erases curves
684 */
685 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
686 {
687   QPtrListIterator<Plot2d_Curve> it(curves);
688   Plot2d_Curve* aCurve;
689   while( (aCurve = it.current()) ) {
690     eraseCurve( aCurve, false );
691     ++it;
692   }
693 //  fitAll();
694   if ( update )
695     myPlot->replot();
696 }
697
698 /*!
699   Updates curves attributes
700 */
701 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
702 {
703   if ( !curve )
704     return;
705   int curveKey = hasCurve( curve );
706   if ( curveKey ) {
707     if ( !curve->isAutoAssign() ) {
708       Qt::PenStyle     ps = plot2qwtLine( curve->getLine() );
709       QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
710       myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
711       myPlot->setCurveSymbol( curveKey, QwtSymbol( ms, 
712                QBrush( curve->getColor() ), 
713                QPen( curve->getColor() ), 
714                QSize( myMarkerSize, myMarkerSize ) ) );
715       myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
716     }
717     myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
718     myPlot->curve( curveKey )->setEnabled( true );
719     if ( update )
720       myPlot->replot();
721   }
722 }
723
724 /*!
725   Returns curve key if is is displayed in the viewer and 0 otherwise
726 */
727 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
728 {
729   QIntDictIterator<Plot2d_Curve> it( myCurves );
730   for ( ; it.current(); ++it ) {
731     if ( it.current() == curve )
732       return it.currentKey();
733   }
734   return 0;
735 }
736
737 /*!
738   Gets lsit of displayed curves
739 */
740 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
741 {
742   clist.clear();
743   clist.setAutoDelete( false );
744   QIntDictIterator<Plot2d_Curve> it( myCurves );
745   for ( ; it.current(); ++it ) {
746     clist.append( it.current() );
747   }
748   return clist.count();
749 }
750
751 /*!
752   Returns true if the curve is visible
753 */
754 bool Plot2d_ViewFrame::isVisible( Plot2d_Curve* curve )
755 {
756   if(curve) {
757     int key = hasCurve( curve );
758     if ( key )
759       return myPlot->curve( key )->enabled();
760   }
761   return false;
762
763
764 /*!
765   update legend
766 */
767 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
768 {
769   if ( !prs || prs->IsNull() )
770     return;
771   curveList aCurves = prs->getCurves();
772
773   QPtrListIterator<Plot2d_Curve> it(aCurves);
774   Plot2d_Curve* aCurve;
775   while( (aCurve = it.current()) ) {
776     int curveKey = hasCurve( aCurve );
777     if ( curveKey )
778       myPlot->setCurveTitle( curveKey, aCurve->getVerTitle() );
779     ++it;
780   }
781 }
782
783 /*!
784   Fits the view to see all data
785 */
786 void Plot2d_ViewFrame::fitAll()
787 {
788   QwtDiMap xMap1 = myPlot->canvasMap( QwtPlot::xBottom );
789
790   myPlot->setAxisAutoScale( QwtPlot::yLeft );
791   myPlot->setAxisAutoScale( QwtPlot::xBottom );
792   myPlot->replot();
793
794   // for existing grid
795   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
796   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
797
798   myPlot->setAxisScale( QwtPlot::xBottom, 
799       myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ), 
800       myPlot->invTransform( QwtPlot::xBottom, xMap.i2() ) );
801   myPlot->setAxisScale( QwtPlot::yLeft, 
802       myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
803       myPlot->invTransform( QwtPlot::yLeft, yMap.i2() ) );
804
805   if (mySecondY) {
806     myPlot->setAxisAutoScale( QwtPlot::yRight );
807     myPlot->replot();
808     QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
809     myPlot->setAxisScale( QwtPlot::yRight, 
810         myPlot->invTransform( QwtPlot::yRight, yMap2.i1() ), 
811         myPlot->invTransform( QwtPlot::yRight, yMap2.i2() ) );
812   }
813   myPlot->replot();
814 }
815
816 /*!
817   Fits the view to rectangle area (pixels)
818 */
819 void Plot2d_ViewFrame::fitArea( const QRect& area )
820 {
821   QRect rect = area.normalize();
822   if ( rect.width() < MIN_RECT_SIZE ) {
823     rect.setWidth( MIN_RECT_SIZE );
824     rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
825   }
826   if ( rect.height() < MIN_RECT_SIZE ) {
827     rect.setHeight( MIN_RECT_SIZE );
828     rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
829   }
830   myPlot->setAxisScale( QwtPlot::yLeft, 
831             myPlot->invTransform( QwtPlot::yLeft, rect.top() ), 
832             myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
833   if (mySecondY)
834     myPlot->setAxisScale( QwtPlot::yRight, 
835             myPlot->invTransform( QwtPlot::yRight, rect.top() ), 
836             myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
837   myPlot->setAxisScale( QwtPlot::xBottom, 
838             myPlot->invTransform( QwtPlot::xBottom, rect.left() ), 
839             myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
840   myPlot->replot();
841 }
842
843 /*!
844   "Fit Data" command for TUI interface
845 */
846 void Plot2d_ViewFrame::fitData(const int mode,
847                                const double xMin, const double xMax,
848                                const double yMin, const double yMax,
849                                double y2Min, double y2Max)
850 {
851   if ( mode == 0 || mode == 2 ) {
852     myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
853     if (mySecondY)
854       myPlot->setAxisScale( QwtPlot::yRight, y2Max, y2Min );
855   }
856   if ( mode == 0 || mode == 1 ) 
857     myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax ); 
858   myPlot->replot();
859 }
860
861 /*!
862   Gets current fit ranges for view frame
863 */
864 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
865                                     double& yMin, double& yMax,
866                                     double& y2Min, double& y2Max)
867 {
868   int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
869   int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
870   int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
871   int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
872   xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
873   xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
874   yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
875   yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
876   y2Min = 0;
877   y2Max = 0;
878   if (mySecondY) {
879     int iyMin = myPlot->canvasMap( QwtPlot::yRight ).i1();
880     int iyMax = myPlot->canvasMap( QwtPlot::yRight ).i2();
881     y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
882     y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
883   }
884 }
885
886 /*!
887   Tests if it is necessary to start operation on mouse action
888 */
889 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
890 {
891   int btn = me.button() | me.state();
892   const int zoomBtn = ControlButton | LeftButton;
893   const int panBtn  = ControlButton | MidButton;
894   const int fitBtn  = ControlButton | RightButton;
895
896   switch (btn)
897   {
898   case zoomBtn:
899     myPlot->canvas()->setCursor( zoomCursor );
900     return ZoomId;
901   case panBtn:
902     myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
903     return PanId;
904   case fitBtn:
905     myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
906     return FitAreaId;
907   default :
908     return NoOpId;
909   }
910 }
911
912 /*!
913   "Settings" toolbar action slot
914 */
915 void Plot2d_ViewFrame::onSettings()
916 {
917 #ifdef TEST_AUTOASSIGN
918   typedef QMap<int,int> IList;
919   typedef QMap<QString,int> SList;
920   IList mars, lins;
921   SList cols;
922   cols[ "red-min" ]   = 1000;
923   cols[ "red-max" ]   = -1;
924   cols[ "green-min" ] = 1000;
925   cols[ "green-max" ] = -1;
926   cols[ "blue-min" ]  = 1000;
927   cols[ "blue-max" ]  = -1;
928   for ( unsigned i = 0; i < 10000; i++ ) {
929     QwtSymbol::Style typeMarker;
930     QColor           color;
931     Qt::PenStyle     typeLine;
932     myPlot->getNextMarker( typeMarker, color, typeLine );
933     if ( mars.contains(typeMarker) )
934       mars[ typeMarker ] = mars[ typeMarker ]+1;
935     else
936       mars[ typeMarker ] = 0;
937     if ( lins.contains(typeLine) )
938       lins[ typeLine ] = lins[ typeLine ]+1;
939     else
940       lins[ typeLine ] = 0;
941     if ( cols[ "red-max" ] < color.red() )
942       cols[ "red-max" ] = color.red();
943     if ( cols[ "red-min" ] > color.red() )
944       cols[ "red-min" ] = color.red();
945     if ( cols[ "green-max" ] < color.green() )
946       cols[ "green-max" ] = color.green();
947     if ( cols[ "green-min" ] > color.green() )
948       cols[ "green-min" ] = color.green();
949     if ( cols[ "blue-max" ] < color.blue() )
950       cols[ "blue-max" ] = color.blue();
951     if ( cols[ "blue-min" ] > color.blue() )
952       cols[ "blue-min" ] = color.blue();
953   }
954 #endif
955   
956   Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
957   dlg->setMainTitle( myTitleEnabled, myTitle );
958   dlg->setXTitle( myXTitleEnabled, myXTitle );
959   dlg->setYTitle( myYTitleEnabled, myYTitle );
960   if (mySecondY)
961     dlg->setY2Title( myY2TitleEnabled, myY2Title );
962   dlg->setCurveType( myCurveType );
963   dlg->setLegend( myShowLegend, myLegendPos );
964   dlg->setMarkerSize( myMarkerSize );
965   dlg->setBackgroundColor( myBackground );
966   dlg->setScaleMode(myXMode, myYMode);
967   //
968   dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
969          myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
970          myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
971   dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
972          myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
973          myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
974   if ( dlg->exec() == QDialog::Accepted ) {
975     // horizontal axis title
976     setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
977     // vertical left axis title
978     setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
979     if (mySecondY) // vertical right axis title
980       setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
981
982     // main title
983     setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
984     // curve type
985     if ( myCurveType != dlg->getCurveType() ) {
986       setCurveType( dlg->getCurveType(), false );
987     }
988     // legend
989     if ( myShowLegend != dlg->isLegendEnabled() ) {
990       showLegend( dlg->isLegendEnabled(), false );
991     }
992     if ( myLegendPos != dlg->getLegendPos() ) {
993       setLegendPos( dlg->getLegendPos() );
994     }
995     // marker size
996     if ( myMarkerSize != dlg->getMarkerSize() ) {
997       setMarkerSize( dlg->getMarkerSize(), false );
998     }
999     // background color
1000     if ( myBackground != dlg->getBackgroundColor() ) {
1001       setBackgroundColor( dlg->getBackgroundColor() );
1002     }
1003     // grid
1004     bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
1005          aY2GridMajorEnabled, aY2GridMinorEnabled;
1006     int  aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
1007          aY2GridMaxMajor, aY2GridMaxMinor;
1008     dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
1009                        aY2GridMajorEnabled, aY2GridMaxMajor);
1010     dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
1011                        aY2GridMinorEnabled, aY2GridMaxMinor);
1012     setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1013     setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
1014               aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
1015     if ( myXMode != dlg->getXScaleMode() ) {
1016       setHorScaleMode( dlg->getXScaleMode() );
1017     }
1018     if ( myYMode != dlg->getYScaleMode() ) {
1019       setVerScaleMode( dlg->getYScaleMode() );
1020     }
1021     // update view
1022     myPlot->replot();
1023     // update preferences
1024     if ( dlg->isSetAsDefault() ) 
1025       writePreferences();
1026   }
1027   delete dlg;
1028 }
1029
1030 /*!
1031   "Fit Data" command slot
1032 */
1033 void Plot2d_ViewFrame::onFitData()
1034 {
1035   Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
1036   double xMin,xMax,yMin,yMax,y2Min,y2Max;
1037   getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
1038   
1039   dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1040   if ( dlg->exec() == QDialog::Accepted ) {
1041     int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1042     fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
1043   }
1044   delete dlg;
1045 }
1046
1047 /*!
1048   Change background color
1049 */
1050 void Plot2d_ViewFrame::onChangeBackground()
1051 {
1052   QColor selColor = QColorDialog::getColor ( backgroundColor(), this ); 
1053   if ( selColor.isValid() ) {
1054     setBackgroundColor( selColor );
1055   }
1056 }
1057
1058 /*!
1059   Sets curve type
1060 */
1061 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1062 {
1063   myCurveType = curveType;
1064   QArray<long> keys = myPlot->curveKeys();
1065   for ( int i = 0; i < (int)keys.count(); i++ ) {
1066     if ( myCurveType == 0 )
1067       myPlot->setCurveStyle( keys[i], QwtCurve::Dots );//QwtCurve::NoCurve
1068     else if ( myCurveType == 1 )
1069       myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1070     else if ( myCurveType == 2 )
1071       myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1072   }
1073   if ( update )
1074     myPlot->replot();
1075   emit vpCurveChanged();
1076 }
1077
1078 void Plot2d_ViewFrame::setCurveTitle( int curveKey, const QString& title ) 
1079
1080   if(myPlot) myPlot->setCurveTitle(curveKey, title); 
1081 }   
1082
1083 /*!
1084   Shows/hides legend
1085 */
1086 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1087 {
1088   myShowLegend = show;
1089   myPlot->setAutoLegend( myShowLegend );
1090   myPlot->enableLegend( myShowLegend );
1091   if ( update )
1092     myPlot->replot();
1093 }
1094
1095 /*!
1096   Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1097 */
1098 void Plot2d_ViewFrame::setLegendPos( int pos )
1099 {
1100   myLegendPos = pos;
1101   switch( pos ) {
1102   case 0:
1103     myPlot->setLegendPos( Qwt::Left );
1104     break;
1105   case 1:
1106     myPlot->setLegendPos( Qwt::Right );
1107     break;
1108   case 2:
1109     myPlot->setLegendPos( Qwt::Top );
1110     break;
1111   case 3:
1112     myPlot->setLegendPos( Qwt::Bottom );
1113     break;
1114   }
1115 }
1116
1117 /*!
1118   Sets new marker size
1119 */
1120 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1121 {
1122   if ( myMarkerSize != size )
1123   {
1124     myMarkerSize = size;
1125     QArray<long> keys = myPlot->curveKeys();
1126     for ( int i = 0; i < (int)keys.count(); i++ )
1127     {
1128       QwtPlotCurve* crv = myPlot->curve( keys[i] );
1129       if ( crv )
1130       {
1131         QwtSymbol aSymbol = crv->symbol();
1132         aSymbol.setSize( myMarkerSize, myMarkerSize );
1133         myPlot->setCurveSymbol( keys[i], aSymbol );
1134       }
1135     }
1136     if ( update )
1137       myPlot->replot();
1138   }
1139 }
1140
1141 /*!
1142   Sets background color
1143 */
1144 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1145 {
1146   myBackground = color;
1147   //myPlot->setCanvasBackground( myBackground );
1148   myPlot->canvas()->setPalette( myBackground );
1149   myPlot->setPalette( myBackground );
1150   QPalette aPal = myPlot->getLegend()->palette();
1151   for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1152     QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1153     aPal.setColor( cg, QColorGroup::Base, myBackground );
1154     aPal.setColor( cg, QColorGroup::Background, myBackground );
1155   }
1156   myPlot->getLegend()->setPalette( aPal );
1157   Repaint();
1158 }
1159 /*!
1160   Gets background color
1161 */
1162 QColor Plot2d_ViewFrame::backgroundColor() const
1163 {
1164   return myBackground;
1165 }
1166 /*!
1167   Sets hor.axis grid parameters
1168 */
1169 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax, 
1170          bool xMinorEnabled, const int xMinorMax, 
1171          bool update )
1172 {
1173   if( xMinorMax>=xMajorMax )
1174     return;
1175
1176   myXGridMajorEnabled = xMajorEnabled;
1177   myXGridMinorEnabled = xMinorEnabled;
1178   myXGridMaxMajor = xMajorMax;
1179   myXGridMaxMinor = xMinorMax;
1180   myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1181   myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1182   myPlot->setGridXAxis(QwtPlot::xBottom);
1183   myPlot->enableGridX( myXGridMajorEnabled );
1184   myPlot->enableGridXMin( myXGridMinorEnabled );
1185   if ( update )
1186     myPlot->replot();
1187 }
1188 /*!
1189   Sets ver.axis grid parameters
1190 */
1191 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax, 
1192                                  bool yMinorEnabled, const int yMinorMax,
1193                                  bool y2MajorEnabled, const int y2MajorMax, 
1194                                  bool y2MinorEnabled, const int y2MinorMax, 
1195                                  bool update )
1196 {
1197   myYGridMajorEnabled = yMajorEnabled;
1198   myYGridMinorEnabled = yMinorEnabled;
1199   myYGridMaxMajor = yMajorMax;
1200   myYGridMaxMinor = yMinorMax;
1201
1202   if (mySecondY) {
1203     myY2GridMajorEnabled = y2MajorEnabled;
1204     myY2GridMinorEnabled = y2MinorEnabled;
1205     myY2GridMaxMajor = y2MajorMax;
1206     myY2GridMaxMinor = y2MinorMax;
1207   }
1208   myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1209   myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1210
1211   if (mySecondY) {
1212     myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
1213     myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
1214   }
1215
1216   myPlot->setGridYAxis(QwtPlot::yLeft);
1217
1218   if (mySecondY) {
1219     if (myYGridMajorEnabled) {
1220       myPlot->enableGridYMin(myYGridMinorEnabled);
1221       myPlot->enableGridY( myYGridMajorEnabled);
1222     }
1223     else if (myY2GridMajorEnabled) {
1224       myPlot->setGridYAxis(QwtPlot::yRight);
1225       myPlot->enableGridYMin(myY2GridMinorEnabled);
1226       myPlot->enableGridY(myY2GridMajorEnabled);
1227     }
1228     else {
1229       myPlot->enableGridYMin(false);
1230       myPlot->enableGridY(false);
1231     }
1232   }
1233   else {
1234     myPlot->enableGridY( myYGridMajorEnabled );
1235     myPlot->enableGridYMin( myYGridMinorEnabled );
1236   }
1237   if ( update )
1238     myPlot->replot();
1239 }
1240
1241 /*!
1242   Sets title for some axis
1243 */
1244 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
1245                                  ObjectType type, bool update )
1246 {
1247   switch (type) {
1248     case MainTitle:
1249       myTitleEnabled = enabled;
1250       myTitle = title;
1251       myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1252       break;
1253     case XTitle:
1254       myXTitleEnabled = enabled;
1255       myXTitle = title;
1256       myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1257       break;
1258     case YTitle:
1259       myYTitleEnabled = enabled;
1260       myYTitle = title;
1261       myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1262       break;
1263     case Y2Title:
1264       myY2TitleEnabled = enabled;
1265       myY2Title = title;
1266       myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString::null );
1267       break;
1268   }
1269   if ( update )
1270     myPlot->replot();
1271 }
1272 /*!
1273   Sets title for some axis
1274 */
1275 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
1276 {
1277   QString title = "";
1278   switch (type) {
1279     case MainTitle:
1280       title = myTitle;   break;
1281     case XTitle:
1282       title = myXTitle;  break;
1283     case YTitle:
1284       title = myYTitle;  break;
1285     case Y2Title:
1286       title = myY2Title; break;
1287   }
1288   return title;
1289 }
1290 /*!
1291   Sets font for Plot2d object : title or axis
1292 */
1293 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
1294 {
1295   switch (type) {
1296     case MainTitle:
1297       myPlot->setTitleFont(font);
1298       break;
1299     case XTitle:
1300       myPlot->setAxisTitleFont(QwtPlot::xBottom, font); break;
1301     case YTitle:
1302       myPlot->setAxisTitleFont(QwtPlot::yLeft, font);   break;
1303     case Y2Title:
1304       myPlot->setAxisTitleFont(QwtPlot::yRight, font);  break;
1305     case XAxis:
1306       myPlot->setAxisFont(QwtPlot::xBottom, font);      break;
1307     case YAxis:
1308       myPlot->setAxisFont(QwtPlot::yLeft, font);        break;
1309     case Y2Axis:
1310       myPlot->setAxisFont(QwtPlot::yRight, font);       break;
1311   }
1312   if ( update )
1313     myPlot->replot();
1314 }
1315 /*!
1316   Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1317 */
1318 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1319 {
1320   myXMode = mode;
1321   if ( myXMode == 0 ) // linear
1322     myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1323   else                // logarithmic
1324     myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
1325
1326   if ( update )
1327     fitAll();
1328   emit vpModeHorChanged();
1329 }
1330 /*!
1331   Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1332 */
1333 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1334 {
1335   myYMode = mode;
1336   if ( myYMode == 0 ) { // linear
1337     myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1338     if (mySecondY)
1339       myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1340   }
1341   else {               // logarithmic
1342     myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
1343     if (mySecondY)
1344       myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, true );
1345   }
1346   if ( update )
1347     fitAll();
1348   emit vpModeVerChanged();
1349 }
1350
1351 /*!
1352   Return, scale mode for horizontal axis
1353 */
1354 bool Plot2d_ViewFrame::isModeHorLinear()
1355 {
1356   return (myXMode == 0 ? true : false);
1357 }
1358
1359 /*!
1360   Return, scale mode for vertical axis
1361 */
1362 bool Plot2d_ViewFrame::isModeVerLinear()
1363 {
1364   return (myYMode == 0 ? true : false);
1365 }
1366 /*!
1367   Slot, called when user presses mouse button
1368 */
1369 void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
1370 {
1371   ((Plot2d_ViewWindow*)parent())->putInfo(getInfo(me.pos()));
1372   if ( myOperation == NoOpId )
1373     myOperation = testOperation( me );
1374   if ( myOperation != NoOpId ) {
1375     myPnt = me.pos();
1376     if ( myOperation == FitAreaId ) {
1377       myPlot->setOutlineStyle( Qwt::Rect );
1378     }
1379     else if ( myOperation == GlPanId ) {
1380       myPlot->setAxisScale( QwtPlot::yLeft,
1381           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2, 
1382           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1383       myPlot->setAxisScale( QwtPlot::xBottom, 
1384           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2, 
1385           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1386       if (mySecondY)
1387         myPlot->setAxisScale( QwtPlot::yRight,
1388           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2, 
1389           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1390       myPlot->replot();
1391     }
1392   }
1393   else {
1394     int btn = me.button() | me.state();
1395     if (btn == RightButton) {
1396       QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1397                                             me.pos(), btn, me.state());
1398       // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1399       parent()->eventFilter(this, aEvent);
1400     }
1401   }
1402 }
1403 /*!
1404   Slot, called when user moves mouse
1405 */
1406 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1407 {
1408   int    dx = me.pos().x() - myPnt.x();
1409   int    dy = me.pos().y() - myPnt.y();
1410
1411   if ( myOperation != NoOpId) {
1412     if ( myOperation == ZoomId ) {
1413       QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1414       QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1415
1416       myPlot->setAxisScale( QwtPlot::yLeft, 
1417           myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
1418           myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1419       myPlot->setAxisScale( QwtPlot::xBottom, 
1420           myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ), 
1421           myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1422       if (mySecondY) {
1423         QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1424         myPlot->setAxisScale( QwtPlot::yRight, 
1425           myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
1426           myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1427       }
1428       myPlot->replot();
1429       myPnt = me.pos();
1430     }
1431     else if ( myOperation == PanId ) {
1432       QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1433       QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1434
1435       myPlot->setAxisScale( QwtPlot::yLeft, 
1436           myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ), 
1437           myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1438       myPlot->setAxisScale( QwtPlot::xBottom, 
1439           myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1440           myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) ); 
1441       if (mySecondY) {
1442         QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1443         myPlot->setAxisScale( QwtPlot::yRight,
1444           myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ), 
1445           myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1446       }
1447       myPlot->replot();
1448       myPnt = me.pos();
1449     }
1450   }
1451   else {
1452     ((Plot2d_ViewWindow*)parent())->putInfo(getInfo(me.pos()));
1453   }
1454 }
1455 /*!
1456   Slot, called when user releases mouse
1457 */
1458 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1459 {
1460   if ( myOperation == NoOpId && me.button() == RightButton )
1461   {
1462     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1463                               me.pos(), me.globalPos(),
1464                               me.state() );
1465     emit contextMenuRequested( &aEvent );
1466   }
1467   if ( myOperation == FitAreaId ) {
1468     QRect rect( myPnt, me.pos() );
1469     fitArea( rect );
1470   }
1471   myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1472   myPlot->setOutlineStyle( Qwt::Triangle );
1473
1474   ((Plot2d_ViewWindow*)parent())->putInfo(tr("INF_READY"));
1475   myOperation = NoOpId;
1476 }
1477 /*!
1478   Slot, called when user wheeling mouse
1479 */
1480 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1481
1482   double aDelta = event->delta();
1483   double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
1484
1485   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1486   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1487
1488   myPlot->setAxisScale( QwtPlot::yLeft,
1489     myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
1490     myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1491   myPlot->setAxisScale( QwtPlot::xBottom, 
1492     myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1493     myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1494   if (mySecondY) {
1495     QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1496     myPlot->setAxisScale( QwtPlot::yRight,
1497       myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
1498       myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1499   }
1500   myPlot->replot();
1501   myPnt = event->pos();
1502 }
1503 /*!
1504   View operations : Pan view
1505 */
1506 void Plot2d_ViewFrame::onViewPan()
1507
1508   myPlot->canvas()->setCursor( panCursor );
1509   myOperation = PanId;
1510   qApp->installEventFilter( this );
1511 }
1512 /*!
1513   View operations : Zoom view
1514 */
1515 void Plot2d_ViewFrame::onViewZoom() 
1516 {
1517   myPlot->canvas()->setCursor( zoomCursor );
1518   myOperation = ZoomId;
1519   qApp->installEventFilter( this );
1520 }
1521 /*!
1522   View operations : Fot All
1523 */
1524 void Plot2d_ViewFrame::onViewFitAll() 
1525
1526   fitAll();
1527 }
1528 /*!
1529   View operations : Fit Area
1530 */
1531 void Plot2d_ViewFrame::onViewFitArea() 
1532 {
1533   myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1534   myOperation = FitAreaId;
1535   qApp->installEventFilter( this );
1536 }
1537 /*!
1538   View operations : Global panning
1539 */
1540 void Plot2d_ViewFrame::onViewGlobalPan() 
1541 {
1542   myPlot->canvas()->setCursor( glPanCursor );
1543   myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1544   myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1545   if (mySecondY)
1546     myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1547   myPlot->replot();
1548   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1549   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1550
1551   myXDistance = xMap.d2() - xMap.d1();
1552   myYDistance = yMap.d2() - yMap.d1();
1553
1554   if (mySecondY) {
1555     QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1556     myYDistance2 = yMap2.d2() - yMap2.d1();
1557   }
1558   fitAll();
1559   myOperation = GlPanId;
1560   qApp->installEventFilter( this );
1561 }
1562
1563 //=================================================================================
1564 // Plot2d_Plot2d implementation
1565 //=================================================================================
1566 /*!
1567   Constructor
1568 */
1569 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1570      : QwtPlot( parent )
1571 {
1572   // outline
1573   enableOutline( true );
1574   setOutlineStyle( Qwt::Triangle );
1575   setOutlinePen( green );
1576   // legend
1577   setAutoLegend( false );
1578   setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1579   enableLegend( false );
1580   // grid
1581   enableGridX( false );
1582   enableGridXMin( false );
1583   enableGridY( false );
1584   enableGridYMin( false );
1585   // auto scaling by default
1586   setAxisAutoScale( QwtPlot::yLeft );
1587   setAxisAutoScale( QwtPlot::yRight );
1588   setAxisAutoScale( QwtPlot::xBottom );
1589 }
1590 /*!
1591   Recalculates and redraws Plot 2d view 
1592 */
1593 void Plot2d_Plot2d::replot()
1594 {
1595   updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
1596   QwtPlot::replot(); 
1597 }
1598
1599 /*!
1600   Checks if two colors are close to each other [ static ]
1601   uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1602 */
1603 const long COLOR_DISTANCE = 100;
1604 const int  MAX_ATTEMPTS   = 10;
1605 static bool closeColors( const QColor& color1, const QColor& color2 )
1606 {
1607   long tol = abs( color2.red()   - color1.red() ) + 
1608              abs( color2.green() - color1.green() ) +
1609        abs( color2.blue()  - color1.blue() );
1610
1611   return ( tol <= COLOR_DISTANCE );
1612 }
1613 /*!
1614   Gets new unique marker for item if possible
1615 */
1616 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine ) 
1617 {
1618   bool bOk = false;
1619   int cnt = 1;
1620   while ( !bOk ) {
1621     int aRed    = (int)( 256.0 * rand() / RAND_MAX);    // generate random color
1622     int aGreen  = (int)( 256.0 * rand() / RAND_MAX);    // ...
1623     int aBlue   = (int)( 256.0 * rand() / RAND_MAX);    // ...
1624     int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1;  // 9 markers types ( not including empty )
1625     int aLine   = (int)( 5.0 * rand() / RAND_MAX) + 1;  // 5 line types ( not including empty )
1626
1627     typeMarker = ( QwtSymbol::Style )aMarker;
1628     color      = QColor( aRed, aGreen, aBlue );
1629     typeLine   = ( Qt::PenStyle )aLine;
1630
1631     cnt++;
1632     if ( cnt == MAX_ATTEMPTS )
1633       bOk = true;
1634     else
1635       bOk = !existMarker( typeMarker, color, typeLine );
1636   }
1637 /*
1638   static int aMarker = -1;
1639   static int aColor  = -1;
1640   static int aLine   = -1;
1641
1642   if ( myColors.isEmpty() ) {
1643     // creating colors list
1644     myColors.append( Qt::white );
1645     myColors.append( Qt::blue );
1646     myColors.append( Qt::gray );
1647     myColors.append( Qt::darkGreen );
1648     myColors.append( Qt::magenta );
1649     myColors.append( Qt::darkGray );
1650     myColors.append( Qt::red );
1651     myColors.append( Qt::darkBlue );
1652     myColors.append( Qt::darkYellow );
1653     myColors.append( Qt::cyan );
1654     myColors.append( Qt::darkRed );
1655     myColors.append( Qt::darkCyan );
1656     myColors.append( Qt::yellow );
1657     myColors.append( Qt::darkMagenta );
1658     myColors.append( Qt::green );
1659     myColors.append( Qt::black );
1660   }
1661
1662   int nbMarkers = 11;                   // QwtSymbol supports 11 marker types
1663   int nbLines   = 6;                    // Qt supports 6 line types
1664   int nbColors  = myColors.count();     // number of default colors supported
1665
1666   aMarker = ( aMarker + 1 ) % nbMarkers;  
1667   if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1668   aColor  = ( aColor  + 1 ) % nbColors;
1669   aLine   = ( aLine   + 1 ) % nbLines;    
1670   if ( aLine == Qt::NoPen ) aLine++;             
1671
1672   typeMarker = ( QwtSymbol::Style )aMarker;
1673   color      = myColors[ aColor ];
1674   typeLine   = ( Qt::PenStyle )aLine;
1675   if ( !existMarker( typeMarker, color, typeLine ) )
1676     return;
1677
1678   int i, j, k;
1679   for ( i = 0; i < nbMarkers; i++ ) {
1680     aMarker = ( aMarker + 1 ) % nbMarkers;
1681     if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1682     for ( j = 0; j < nbColors; j++ ) {
1683       aColor  = ( aColor  + 1 ) % nbColors;
1684       for ( k = 0; k < nbLines; k++ ) {
1685         aLine = ( aLine + 1 ) % nbLines;
1686   if ( aLine == Qt::NoPen ) aLine++;             
1687         if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1688           typeMarker = ( QwtSymbol::Style )aMarker;
1689           color      = myColors[ aColor ];
1690           typeLine   = ( Qt::PenStyle )aLine;
1691           return;
1692         }
1693       }
1694     }
1695   }
1696 */
1697 }
1698
1699 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1700 {
1701   return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1702 }
1703
1704 QSize Plot2d_Plot2d::sizeHint() const
1705 {
1706   return QwtPlot::minimumSizeHint();
1707 }
1708
1709 /*!
1710   return minimum size for qwt plot
1711 */
1712 QSize Plot2d_Plot2d::minimumSizeHint() const
1713 {
1714   return QSize( 0, 0 );
1715 //  QSize aSize = QwtPlot::minimumSizeHint();
1716 //  return QSize(aSize.width()*3/4, aSize.height());
1717 }
1718 /*!
1719   Checks if marker belongs to any enitity
1720 */
1721 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine ) 
1722 {
1723   // getting all curves
1724   QArray<long> keys = curveKeys();
1725   //QColor aRgbColor;
1726
1727   if ( closeColors( color, backgroundColor() ) )
1728       return true;
1729   for ( int i = 0; i < (int)keys.count(); i++ )
1730   {
1731     QwtPlotCurve* crv = curve( keys[i] );
1732     if ( crv ) {
1733       QwtSymbol::Style aStyle = crv->symbol().style();
1734       QColor           aColor = crv->pen().color();
1735       Qt::PenStyle     aLine  = crv->pen().style();
1736 //      if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1737       if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1738   return true;
1739     }
1740   }
1741   return false;
1742 }
1743
1744 // TEMPORARY SOLUTION!!!  TO BE IMPLEMENTED!!!
1745 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1746 {
1747   return 0;
1748 }
1749
1750 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1751 {
1752   if( !vf )
1753     return;
1754
1755   myCurveType = vf->myCurveType;
1756   myShowLegend = vf->myShowLegend;
1757   myLegendPos = vf->myLegendPos;
1758   myMarkerSize = vf->myMarkerSize;
1759   myBackground = vf->myBackground;
1760   myTitle = vf->myTitle; 
1761   myXTitle = vf->myXTitle;
1762   myYTitle = vf->myYTitle;
1763   myY2Title = vf->myY2Title;
1764   myTitleEnabled = vf->myTitleEnabled;
1765   myXTitleEnabled = vf->myXTitleEnabled;
1766   myYTitleEnabled = vf->myYTitleEnabled;
1767   myY2TitleEnabled = vf->myY2TitleEnabled;
1768   myXGridMajorEnabled = vf->myXGridMajorEnabled;
1769   myYGridMajorEnabled = vf->myYGridMajorEnabled;
1770   myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1771   myXGridMinorEnabled = vf->myXGridMinorEnabled;
1772   myYGridMinorEnabled = vf->myYGridMinorEnabled;
1773   myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1774   myXGridMaxMajor = vf->myXGridMaxMajor;
1775   myYGridMaxMajor = vf->myYGridMaxMajor;
1776   myY2GridMaxMajor = vf->myY2GridMaxMajor;
1777   myXGridMaxMinor = vf->myXGridMaxMinor;
1778   myYGridMaxMinor = vf->myYGridMaxMinor;
1779   myY2GridMaxMinor = vf->myY2GridMaxMinor;
1780   myXMode = vf->myXMode;
1781   myYMode = vf->myYMode;
1782   mySecondY = vf->mySecondY;
1783 }
1784
1785 /*!
1786   Updates titles according to curves
1787 */
1788 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1789 void Plot2d_ViewFrame::updateTitles() 
1790 {
1791   QIntDictIterator<Plot2d_Curve> it( myCurves );
1792   QStringList aXTitles;
1793   QStringList aYTitles;
1794   QStringList aXUnits;
1795   QStringList aYUnits;
1796   QStringList aTables;
1797   int i = 0;
1798   while ( it.current() ) {
1799     // collect titles and units from all curves...
1800     QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1801     QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1802     QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1803     QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1804     
1805     aYTitles.append( yTitle );
1806     if ( aXTitles.find( xTitle ) == aXTitles.end() )
1807       aXTitles.append( xTitle );
1808     if ( aXUnits.find( xUnits ) == aXUnits.end() )
1809       aXUnits.append( xUnits );
1810     if ( aYUnits.find( yUnits ) == aYUnits.end() )
1811       aYUnits.append( yUnits );
1812
1813     QString aName = it.current()->getTableTitle();
1814     if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1815       aTables.append( aName );
1816
1817     ++it;
1818     ++i;
1819   }
1820   // ... and update plot 2d view
1821   QString xUnits, yUnits;
1822   if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1823     xUnits = BRACKETIZE( aXUnits[0] );
1824   if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1825     yUnits = BRACKETIZE( aYUnits[0] );
1826   QString xTitle, yTitle;
1827   if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1828     xTitle = aXTitles[0];
1829   if ( aYTitles.count() == 1 )
1830     yTitle = aYTitles[0];
1831
1832   if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1833     xTitle += " ";
1834   if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1835     yTitle += " ";
1836
1837   setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1838   setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1839   setTitle( true, aTables.join("; "), MainTitle, true );
1840 }
1841
1842 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
1843 {
1844 #ifdef WIN32
1845   return false;
1846
1847 #else
1848   bool res = false;
1849   if( myPlot )
1850   {
1851     QPaintDevice* pd = 0;
1852     if( format=="PS" )
1853     {
1854       QPrinter* pr = new QPrinter( QPrinter::HighResolution );
1855       pr->setPageSize( QPrinter::A4 );
1856       pr->setOutputToFile( true );
1857       pr->setOutputFileName( file );
1858       pr->setPrintProgram( "" );
1859       pd = pr;
1860     }
1861
1862     if( pd )
1863     {
1864       myPlot->print( *pd );
1865       res = true;
1866       delete pd;
1867     }
1868   }
1869   return res;
1870 #endif
1871 }