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