Salome HOME
PAL9764 - names and units aren't displayed in Plot2d
[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 <qwt_legend.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   updateTitles();
622   if ( update )
623     myPlot->replot();
624 }
625
626 /*!
627   Adds curves into view
628 */
629 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
630 {
631   myPlot->setUpdatesEnabled( false );
632   QPtrListIterator<Plot2d_Curve> it(curves);
633   Plot2d_Curve* aCurve;
634   while( (aCurve = it.current()) ) {
635     displayCurve( aCurve, false );
636     ++it;
637   }
638
639   fitAll();
640   myPlot->setUpdatesEnabled( true );
641   if ( update )
642     myPlot->replot();
643 }
644
645 /*!
646   Erases curve
647 */
648 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
649 {
650   if ( !curve )
651     return;
652   int curveKey = hasCurve( curve );
653   if ( curveKey ) {
654     myPlot->removeCurve( curveKey );
655     myCurves.remove( curveKey );
656     if ( update )
657       myPlot->replot();
658   }
659 }
660
661 /*!
662   Erases curves
663 */
664 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
665 {
666   QPtrListIterator<Plot2d_Curve> it(curves);
667   Plot2d_Curve* aCurve;
668   while( (aCurve = it.current()) ) {
669     eraseCurve( aCurve, false );
670     ++it;
671   }
672 //  fitAll();
673   if ( update )
674     myPlot->replot();
675 }
676
677 /*!
678   Updates curves attributes
679 */
680 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
681 {
682   if ( !curve )
683     return;
684   int curveKey = hasCurve( curve );
685   if ( curveKey ) {
686     if ( !curve->isAutoAssign() ) {
687       Qt::PenStyle     ps = plot2qwtLine( curve->getLine() );
688       QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
689       myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
690       myPlot->setCurveSymbol( curveKey, QwtSymbol( ms, 
691                QBrush( curve->getColor() ), 
692                QPen( curve->getColor() ), 
693                QSize( myMarkerSize, myMarkerSize ) ) );
694       myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
695     }
696     myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
697     myPlot->curve( curveKey )->setEnabled( true );
698     if ( update )
699       myPlot->replot();
700   }
701 }
702
703 /*!
704   Returns curve key if is is displayed in the viewer and 0 otherwise
705 */
706 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
707 {
708   QIntDictIterator<Plot2d_Curve> it( myCurves );
709   for ( ; it.current(); ++it ) {
710     if ( it.current() == curve )
711       return it.currentKey();
712   }
713   return 0;
714 }
715
716 /*!
717   Gets lsit of displayed curves
718 */
719 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
720 {
721   clist.clear();
722   clist.setAutoDelete( false );
723   QIntDictIterator<Plot2d_Curve> it( myCurves );
724   for ( ; it.current(); ++it ) {
725     clist.append( it.current() );
726   }
727   return clist.count();
728 }
729
730 /*!
731   Returns true if the curve is visible
732 */
733 bool Plot2d_ViewFrame::isVisible( Plot2d_Curve* curve )
734 {
735   if(curve) {
736     int key = hasCurve( curve );
737     if ( key )
738       return myPlot->curve( key )->enabled();
739   }
740   return false;
741
742
743 /*!
744   update legend
745 */
746 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
747 {
748   if ( !prs || prs->IsNull() )
749     return;
750   curveList aCurves = prs->getCurves();
751
752   QPtrListIterator<Plot2d_Curve> it(aCurves);
753   Plot2d_Curve* aCurve;
754   while( (aCurve = it.current()) ) {
755     int curveKey = hasCurve( aCurve );
756     if ( curveKey )
757       myPlot->setCurveTitle( curveKey, aCurve->getVerTitle() );
758     ++it;
759   }
760 }
761
762 /*!
763   Fits the view to see all data
764 */
765 void Plot2d_ViewFrame::fitAll()
766 {
767   QwtDiMap xMap1 = myPlot->canvasMap( QwtPlot::xBottom );
768
769   myPlot->setAxisAutoScale( QwtPlot::yLeft );
770   myPlot->setAxisAutoScale( QwtPlot::xBottom );
771   myPlot->replot();
772
773   // for existing grid
774   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
775   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
776
777   myPlot->setAxisScale( QwtPlot::xBottom, 
778       myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ), 
779       myPlot->invTransform( QwtPlot::xBottom, xMap.i2() ) );
780   myPlot->setAxisScale( QwtPlot::yLeft, 
781       myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
782       myPlot->invTransform( QwtPlot::yLeft, yMap.i2() ) );
783
784   if (mySecondY) {
785     myPlot->setAxisAutoScale( QwtPlot::yRight );
786     myPlot->replot();
787     QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
788     myPlot->setAxisScale( QwtPlot::yRight, 
789         myPlot->invTransform( QwtPlot::yRight, yMap2.i1() ), 
790         myPlot->invTransform( QwtPlot::yRight, yMap2.i2() ) );
791   }
792   myPlot->replot();
793 }
794
795 /*!
796   Fits the view to rectangle area (pixels)
797 */
798 void Plot2d_ViewFrame::fitArea( const QRect& area )
799 {
800   QRect rect = area.normalize();
801   if ( rect.width() < MIN_RECT_SIZE ) {
802     rect.setWidth( MIN_RECT_SIZE );
803     rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
804   }
805   if ( rect.height() < MIN_RECT_SIZE ) {
806     rect.setHeight( MIN_RECT_SIZE );
807     rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
808   }
809   myPlot->setAxisScale( QwtPlot::yLeft, 
810             myPlot->invTransform( QwtPlot::yLeft, rect.top() ), 
811             myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
812   if (mySecondY)
813     myPlot->setAxisScale( QwtPlot::yRight, 
814             myPlot->invTransform( QwtPlot::yRight, rect.top() ), 
815             myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
816   myPlot->setAxisScale( QwtPlot::xBottom, 
817             myPlot->invTransform( QwtPlot::xBottom, rect.left() ), 
818             myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
819   myPlot->replot();
820 }
821
822 /*!
823   "Fit Data" command for TUI interface
824 */
825 void Plot2d_ViewFrame::fitData(const int mode,
826                                const double xMin, const double xMax,
827                                const double yMin, const double yMax,
828                                double y2Min, double y2Max)
829 {
830   if ( mode == 0 || mode == 2 ) {
831     myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
832     if (mySecondY)
833       myPlot->setAxisScale( QwtPlot::yRight, y2Max, y2Min );
834   }
835   if ( mode == 0 || mode == 1 ) 
836     myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax ); 
837   myPlot->replot();
838 }
839
840 /*!
841   Gets current fit ranges for view frame
842 */
843 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
844                                     double& yMin, double& yMax,
845                                     double& y2Min, double& y2Max)
846 {
847   int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
848   int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
849   int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
850   int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
851   xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
852   xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
853   yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
854   yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
855   y2Min = 0;
856   y2Max = 0;
857   if (mySecondY) {
858     int iyMin = myPlot->canvasMap( QwtPlot::yRight ).i1();
859     int iyMax = myPlot->canvasMap( QwtPlot::yRight ).i2();
860     y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
861     y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
862   }
863 }
864
865 /*!
866   Tests if it is necessary to start operation on mouse action
867 */
868 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
869 {
870   int btn = me.button() | me.state();
871   const int zoomBtn = ControlButton | LeftButton;
872   const int panBtn  = ControlButton | MidButton;
873   const int fitBtn  = ControlButton | RightButton;
874
875   switch (btn)
876   {
877   case zoomBtn:
878     myPlot->canvas()->setCursor( zoomCursor );
879     return ZoomId;
880   case panBtn:
881     myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
882     return PanId;
883   case fitBtn:
884     myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
885     return FitAreaId;
886   default :
887     return NoOpId;
888   }
889 }
890
891 /*!
892   "Settings" toolbar action slot
893 */
894 void Plot2d_ViewFrame::onSettings()
895 {
896 #ifdef TEST_AUTOASSIGN
897   typedef QMap<int,int> IList;
898   typedef QMap<QString,int> SList;
899   IList mars, lins;
900   SList cols;
901   cols[ "red-min" ]   = 1000;
902   cols[ "red-max" ]   = -1;
903   cols[ "green-min" ] = 1000;
904   cols[ "green-max" ] = -1;
905   cols[ "blue-min" ]  = 1000;
906   cols[ "blue-max" ]  = -1;
907   for ( unsigned i = 0; i < 10000; i++ ) {
908     QwtSymbol::Style typeMarker;
909     QColor           color;
910     Qt::PenStyle     typeLine;
911     myPlot->getNextMarker( typeMarker, color, typeLine );
912     if ( mars.contains(typeMarker) )
913       mars[ typeMarker ] = mars[ typeMarker ]+1;
914     else
915       mars[ typeMarker ] = 0;
916     if ( lins.contains(typeLine) )
917       lins[ typeLine ] = lins[ typeLine ]+1;
918     else
919       lins[ typeLine ] = 0;
920     if ( cols[ "red-max" ] < color.red() )
921       cols[ "red-max" ] = color.red();
922     if ( cols[ "red-min" ] > color.red() )
923       cols[ "red-min" ] = color.red();
924     if ( cols[ "green-max" ] < color.green() )
925       cols[ "green-max" ] = color.green();
926     if ( cols[ "green-min" ] > color.green() )
927       cols[ "green-min" ] = color.green();
928     if ( cols[ "blue-max" ] < color.blue() )
929       cols[ "blue-max" ] = color.blue();
930     if ( cols[ "blue-min" ] > color.blue() )
931       cols[ "blue-min" ] = color.blue();
932   }
933 #endif
934   
935   Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
936   dlg->setMainTitle( myTitleEnabled, myTitle );
937   dlg->setXTitle( myXTitleEnabled, myXTitle );
938   dlg->setYTitle( myYTitleEnabled, myYTitle );
939   if (mySecondY)
940     dlg->setY2Title( myY2TitleEnabled, myY2Title );
941   dlg->setCurveType( myCurveType );
942   dlg->setLegend( myShowLegend, myLegendPos );
943   dlg->setMarkerSize( myMarkerSize );
944   dlg->setBackgroundColor( myBackground );
945   dlg->setScaleMode(myXMode, myYMode);
946   //
947   dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
948          myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
949          myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
950   dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
951          myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
952          myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
953   if ( dlg->exec() == QDialog::Accepted ) {
954     // horizontal axis title
955     setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
956     // vertical left axis title
957     setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
958     if (mySecondY) // vertical right axis title
959       setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
960
961     // main title
962     setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
963     // curve type
964     if ( myCurveType != dlg->getCurveType() ) {
965       setCurveType( dlg->getCurveType(), false );
966     }
967     // legend
968     if ( myShowLegend != dlg->isLegendEnabled() ) {
969       showLegend( dlg->isLegendEnabled(), false );
970     }
971     if ( myLegendPos != dlg->getLegendPos() ) {
972       setLegendPos( dlg->getLegendPos() );
973     }
974     // marker size
975     if ( myMarkerSize != dlg->getMarkerSize() ) {
976       setMarkerSize( dlg->getMarkerSize(), false );
977     }
978     // background color
979     if ( myBackground != dlg->getBackgroundColor() ) {
980       setBackgroundColor( dlg->getBackgroundColor() );
981     }
982     // grid
983     bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
984          aY2GridMajorEnabled, aY2GridMinorEnabled;
985     int  aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
986          aY2GridMaxMajor, aY2GridMaxMinor;
987     dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
988                        aY2GridMajorEnabled, aY2GridMaxMajor);
989     dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
990                        aY2GridMinorEnabled, aY2GridMaxMinor);
991     setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
992     setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
993               aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
994     if ( myXMode != dlg->getXScaleMode() ) {
995       setHorScaleMode( dlg->getXScaleMode() );
996     }
997     if ( myYMode != dlg->getYScaleMode() ) {
998       setVerScaleMode( dlg->getYScaleMode() );
999     }
1000     // update view
1001     myPlot->replot();
1002     // update preferences
1003     if ( dlg->isSetAsDefault() ) 
1004       writePreferences();
1005   }
1006   delete dlg;
1007 }
1008
1009 /*!
1010   "Fit Data" command slot
1011 */
1012 void Plot2d_ViewFrame::onFitData()
1013 {
1014   Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
1015   double xMin,xMax,yMin,yMax,y2Min,y2Max;
1016   getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
1017   
1018   dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1019   if ( dlg->exec() == QDialog::Accepted ) {
1020     int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1021     fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
1022   }
1023   delete dlg;
1024 }
1025
1026 /*!
1027   Change background color
1028 */
1029 void Plot2d_ViewFrame::onChangeBackground()
1030 {
1031   QColor selColor = QColorDialog::getColor ( backgroundColor(), this ); 
1032   if ( selColor.isValid() ) {
1033     setBackgroundColor( selColor );
1034   }
1035 }
1036
1037 /*!
1038   Sets curve type
1039 */
1040 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1041 {
1042   myCurveType = curveType;
1043   QArray<long> keys = myPlot->curveKeys();
1044   for ( int i = 0; i < (int)keys.count(); i++ ) {
1045     if ( myCurveType == 0 )
1046       myPlot->setCurveStyle( keys[i], QwtCurve::Dots );//QwtCurve::NoCurve
1047     else if ( myCurveType == 1 )
1048       myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1049     else if ( myCurveType == 2 )
1050       myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1051   }
1052   if ( update )
1053     myPlot->replot();
1054   emit vpCurveChanged();
1055 }
1056
1057 void Plot2d_ViewFrame::setCurveTitle( int curveKey, const QString& title ) 
1058
1059   if(myPlot) myPlot->setCurveTitle(curveKey, title); 
1060 }   
1061
1062 /*!
1063   Shows/hides legend
1064 */
1065 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1066 {
1067   myShowLegend = show;
1068   myPlot->setAutoLegend( myShowLegend );
1069   myPlot->enableLegend( myShowLegend );
1070   if ( update )
1071     myPlot->replot();
1072 }
1073
1074 /*!
1075   Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1076 */
1077 void Plot2d_ViewFrame::setLegendPos( int pos )
1078 {
1079   myLegendPos = pos;
1080   switch( pos ) {
1081   case 0:
1082     myPlot->setLegendPos( Qwt::Left );
1083     break;
1084   case 1:
1085     myPlot->setLegendPos( Qwt::Right );
1086     break;
1087   case 2:
1088     myPlot->setLegendPos( Qwt::Top );
1089     break;
1090   case 3:
1091     myPlot->setLegendPos( Qwt::Bottom );
1092     break;
1093   }
1094 }
1095
1096 /*!
1097   Sets new marker size
1098 */
1099 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1100 {
1101   if ( myMarkerSize != size )
1102   {
1103     myMarkerSize = size;
1104     QArray<long> keys = myPlot->curveKeys();
1105     for ( int i = 0; i < (int)keys.count(); i++ )
1106     {
1107       QwtPlotCurve* crv = myPlot->curve( keys[i] );
1108       if ( crv )
1109       {
1110         QwtSymbol aSymbol = crv->symbol();
1111         aSymbol.setSize( myMarkerSize, myMarkerSize );
1112         myPlot->setCurveSymbol( keys[i], aSymbol );
1113       }
1114     }
1115     if ( update )
1116       myPlot->replot();
1117   }
1118 }
1119
1120 /*!
1121   Sets background color
1122 */
1123 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1124 {
1125   myBackground = color;
1126   //myPlot->setCanvasBackground( myBackground );
1127   myPlot->canvas()->setPalette( myBackground );
1128   myPlot->setPalette( myBackground );
1129   QPalette aPal = myPlot->getLegend()->palette();
1130   for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1131     QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1132     aPal.setColor( cg, QColorGroup::Base, myBackground );
1133     aPal.setColor( cg, QColorGroup::Background, myBackground );
1134   }
1135   myPlot->getLegend()->setPalette( aPal );
1136   Repaint();
1137 }
1138 /*!
1139   Gets background color
1140 */
1141 QColor Plot2d_ViewFrame::backgroundColor() const
1142 {
1143   return myBackground;
1144 }
1145 /*!
1146   Sets hor.axis grid parameters
1147 */
1148 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax, 
1149          bool xMinorEnabled, const int xMinorMax, 
1150          bool update )
1151 {
1152   if( xMinorMax>=xMajorMax )
1153     return;
1154
1155   myXGridMajorEnabled = xMajorEnabled;
1156   myXGridMinorEnabled = xMinorEnabled;
1157   myXGridMaxMajor = xMajorMax;
1158   myXGridMaxMinor = xMinorMax;
1159   myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1160   myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1161   myPlot->setGridXAxis(QwtPlot::xBottom);
1162   myPlot->enableGridX( myXGridMajorEnabled );
1163   myPlot->enableGridXMin( myXGridMinorEnabled );
1164   if ( update )
1165     myPlot->replot();
1166 }
1167 /*!
1168   Sets ver.axis grid parameters
1169 */
1170 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax, 
1171                                  bool yMinorEnabled, const int yMinorMax,
1172                                  bool y2MajorEnabled, const int y2MajorMax, 
1173                                  bool y2MinorEnabled, const int y2MinorMax, 
1174                                  bool update )
1175 {
1176   myYGridMajorEnabled = yMajorEnabled;
1177   myYGridMinorEnabled = yMinorEnabled;
1178   myYGridMaxMajor = yMajorMax;
1179   myYGridMaxMinor = yMinorMax;
1180
1181   if (mySecondY) {
1182     myY2GridMajorEnabled = y2MajorEnabled;
1183     myY2GridMinorEnabled = y2MinorEnabled;
1184     myY2GridMaxMajor = y2MajorMax;
1185     myY2GridMaxMinor = y2MinorMax;
1186   }
1187   myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1188   myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1189
1190   if (mySecondY) {
1191     myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
1192     myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
1193   }
1194
1195   myPlot->setGridYAxis(QwtPlot::yLeft);
1196
1197   if (mySecondY) {
1198     if (myYGridMajorEnabled) {
1199       myPlot->enableGridYMin(myYGridMinorEnabled);
1200       myPlot->enableGridY( myYGridMajorEnabled);
1201     }
1202     else if (myY2GridMajorEnabled) {
1203       myPlot->setGridYAxis(QwtPlot::yRight);
1204       myPlot->enableGridYMin(myY2GridMinorEnabled);
1205       myPlot->enableGridY(myY2GridMajorEnabled);
1206     }
1207     else {
1208       myPlot->enableGridYMin(false);
1209       myPlot->enableGridY(false);
1210     }
1211   }
1212   else {
1213     myPlot->enableGridY( myYGridMajorEnabled );
1214     myPlot->enableGridYMin( myYGridMinorEnabled );
1215   }
1216   if ( update )
1217     myPlot->replot();
1218 }
1219
1220 /*!
1221   Sets title for some axis
1222 */
1223 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
1224                                  ObjectType type, bool update )
1225 {
1226   switch (type) {
1227     case MainTitle:
1228       myTitleEnabled = enabled;
1229       myTitle = title;
1230       myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1231       break;
1232     case XTitle:
1233       myXTitleEnabled = enabled;
1234       myXTitle = title;
1235       myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1236       break;
1237     case YTitle:
1238       myYTitleEnabled = enabled;
1239       myYTitle = title;
1240       myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1241       break;
1242     case Y2Title:
1243       myY2TitleEnabled = enabled;
1244       myY2Title = title;
1245       myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString::null );
1246       break;
1247   }
1248   if ( update )
1249     myPlot->replot();
1250 }
1251 /*!
1252   Sets title for some axis
1253 */
1254 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
1255 {
1256   QString title = "";
1257   switch (type) {
1258     case MainTitle:
1259       title = myTitle;   break;
1260     case XTitle:
1261       title = myXTitle;  break;
1262     case YTitle:
1263       title = myYTitle;  break;
1264     case Y2Title:
1265       title = myY2Title; break;
1266   }
1267   return title;
1268 }
1269 /*!
1270   Sets font for Plot2d object : title or axis
1271 */
1272 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
1273 {
1274   switch (type) {
1275     case MainTitle:
1276       myPlot->setTitleFont(font);
1277       break;
1278     case XTitle:
1279       myPlot->setAxisTitleFont(QwtPlot::xBottom, font); break;
1280     case YTitle:
1281       myPlot->setAxisTitleFont(QwtPlot::yLeft, font);   break;
1282     case Y2Title:
1283       myPlot->setAxisTitleFont(QwtPlot::yRight, font);  break;
1284     case XAxis:
1285       myPlot->setAxisFont(QwtPlot::xBottom, font);      break;
1286     case YAxis:
1287       myPlot->setAxisFont(QwtPlot::yLeft, font);        break;
1288     case Y2Axis:
1289       myPlot->setAxisFont(QwtPlot::yRight, font);       break;
1290   }
1291   if ( update )
1292     myPlot->replot();
1293 }
1294 /*!
1295   Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1296 */
1297 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1298 {
1299   myXMode = mode;
1300   if ( myXMode == 0 ) // linear
1301     myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1302   else                // logarithmic
1303     myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
1304
1305   if ( update )
1306     fitAll();
1307   emit vpModeHorChanged();
1308 }
1309 /*!
1310   Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1311 */
1312 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1313 {
1314   myYMode = mode;
1315   if ( myYMode == 0 ) { // linear
1316     myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1317     if (mySecondY)
1318       myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1319   }
1320   else {               // logarithmic
1321     myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
1322     if (mySecondY)
1323       myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, true );
1324   }
1325   if ( update )
1326     fitAll();
1327   emit vpModeVerChanged();
1328 }
1329
1330 /*!
1331   Return, scale mode for horizontal axis
1332 */
1333 bool Plot2d_ViewFrame::isModeHorLinear()
1334 {
1335   return (myXMode == 0 ? true : false);
1336 }
1337
1338 /*!
1339   Return, scale mode for vertical axis
1340 */
1341 bool Plot2d_ViewFrame::isModeVerLinear()
1342 {
1343   return (myYMode == 0 ? true : false);
1344 }
1345 /*!
1346   Slot, called when user presses mouse button
1347 */
1348 void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
1349 {
1350   ((Plot2d_ViewWindow*)parent())->putInfo(getInfo(me.pos()));
1351   if ( myOperation == NoOpId )
1352     myOperation = testOperation( me );
1353   if ( myOperation != NoOpId ) {
1354     myPnt = me.pos();
1355     if ( myOperation == FitAreaId ) {
1356       myPlot->setOutlineStyle( Qwt::Rect );
1357     }
1358     else if ( myOperation == GlPanId ) {
1359       myPlot->setAxisScale( QwtPlot::yLeft,
1360           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2, 
1361           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1362       myPlot->setAxisScale( QwtPlot::xBottom, 
1363           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2, 
1364           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1365       if (mySecondY)
1366         myPlot->setAxisScale( QwtPlot::yRight,
1367           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2, 
1368           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1369       myPlot->replot();
1370     }
1371   }
1372   else {
1373     int btn = me.button() | me.state();
1374     if (btn == RightButton) {
1375       QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1376                                             me.pos(), btn, me.state());
1377       // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1378       parent()->eventFilter(this, aEvent);
1379     }
1380   }
1381 }
1382 /*!
1383   Slot, called when user moves mouse
1384 */
1385 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1386 {
1387   int    dx = me.pos().x() - myPnt.x();
1388   int    dy = me.pos().y() - myPnt.y();
1389
1390   if ( myOperation != NoOpId) {
1391     if ( myOperation == ZoomId ) {
1392       QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1393       QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1394
1395       myPlot->setAxisScale( QwtPlot::yLeft, 
1396           myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
1397           myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1398       myPlot->setAxisScale( QwtPlot::xBottom, 
1399           myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ), 
1400           myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1401       if (mySecondY) {
1402         QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1403         myPlot->setAxisScale( QwtPlot::yRight, 
1404           myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
1405           myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1406       }
1407       myPlot->replot();
1408       myPnt = me.pos();
1409     }
1410     else if ( myOperation == PanId ) {
1411       QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1412       QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1413
1414       myPlot->setAxisScale( QwtPlot::yLeft, 
1415           myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ), 
1416           myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1417       myPlot->setAxisScale( QwtPlot::xBottom, 
1418           myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1419           myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) ); 
1420       if (mySecondY) {
1421         QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1422         myPlot->setAxisScale( QwtPlot::yRight,
1423           myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ), 
1424           myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1425       }
1426       myPlot->replot();
1427       myPnt = me.pos();
1428     }
1429   }
1430   else {
1431     ((Plot2d_ViewWindow*)parent())->putInfo(getInfo(me.pos()));
1432   }
1433 }
1434 /*!
1435   Slot, called when user releases mouse
1436 */
1437 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1438 {
1439   if ( myOperation == NoOpId && me.button() == RightButton )
1440   {
1441     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1442                               me.pos(), me.globalPos(),
1443                               me.state() );
1444     emit contextMenuRequested( &aEvent );
1445   }
1446   if ( myOperation == FitAreaId ) {
1447     QRect rect( myPnt, me.pos() );
1448     fitArea( rect );
1449   }
1450   myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1451   myPlot->setOutlineStyle( Qwt::Triangle );
1452
1453   ((Plot2d_ViewWindow*)parent())->putInfo(tr("INF_READY"));
1454   myOperation = NoOpId;
1455 }
1456 /*!
1457   Slot, called when user wheeling mouse
1458 */
1459 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1460
1461   double aDelta = event->delta();
1462   double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
1463
1464   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1465   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1466
1467   myPlot->setAxisScale( QwtPlot::yLeft,
1468     myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
1469     myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1470   myPlot->setAxisScale( QwtPlot::xBottom, 
1471     myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1472     myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1473   if (mySecondY) {
1474     QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1475     myPlot->setAxisScale( QwtPlot::yRight,
1476       myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
1477       myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1478   }
1479   myPlot->replot();
1480   myPnt = event->pos();
1481 }
1482 /*!
1483   View operations : Pan view
1484 */
1485 void Plot2d_ViewFrame::onViewPan()
1486
1487   myPlot->canvas()->setCursor( panCursor );
1488   myOperation = PanId;
1489   qApp->installEventFilter( this );
1490 }
1491 /*!
1492   View operations : Zoom view
1493 */
1494 void Plot2d_ViewFrame::onViewZoom() 
1495 {
1496   myPlot->canvas()->setCursor( zoomCursor );
1497   myOperation = ZoomId;
1498   qApp->installEventFilter( this );
1499 }
1500 /*!
1501   View operations : Fot All
1502 */
1503 void Plot2d_ViewFrame::onViewFitAll() 
1504
1505   fitAll();
1506 }
1507 /*!
1508   View operations : Fit Area
1509 */
1510 void Plot2d_ViewFrame::onViewFitArea() 
1511 {
1512   myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1513   myOperation = FitAreaId;
1514   qApp->installEventFilter( this );
1515 }
1516 /*!
1517   View operations : Global panning
1518 */
1519 void Plot2d_ViewFrame::onViewGlobalPan() 
1520 {
1521   myPlot->canvas()->setCursor( glPanCursor );
1522   myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1523   myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1524   if (mySecondY)
1525     myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1526   myPlot->replot();
1527   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1528   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1529
1530   myXDistance = xMap.d2() - xMap.d1();
1531   myYDistance = yMap.d2() - yMap.d1();
1532
1533   if (mySecondY) {
1534     QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1535     myYDistance2 = yMap2.d2() - yMap2.d1();
1536   }
1537   fitAll();
1538   myOperation = GlPanId;
1539   qApp->installEventFilter( this );
1540 }
1541
1542 //=================================================================================
1543 // Plot2d_Plot2d implementation
1544 //=================================================================================
1545 /*!
1546   Constructor
1547 */
1548 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1549      : QwtPlot( parent )
1550 {
1551   // outline
1552   enableOutline( true );
1553   setOutlineStyle( Qwt::Triangle );
1554   setOutlinePen( green );
1555   // legend
1556   setAutoLegend( false );
1557   setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1558   enableLegend( false );
1559   // grid
1560   enableGridX( false );
1561   enableGridXMin( false );
1562   enableGridY( false );
1563   enableGridYMin( false );
1564   // auto scaling by default
1565   setAxisAutoScale( QwtPlot::yLeft );
1566   setAxisAutoScale( QwtPlot::yRight );
1567   setAxisAutoScale( QwtPlot::xBottom );
1568 }
1569 /*!
1570   Recalculates and redraws Plot 2d view 
1571 */
1572 void Plot2d_Plot2d::replot()
1573 {
1574   updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
1575   QwtPlot::replot(); 
1576 }
1577
1578 /*!
1579   Checks if two colors are close to each other [ static ]
1580   uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1581 */
1582 const long COLOR_DISTANCE = 100;
1583 const int  MAX_ATTEMPTS   = 10;
1584 static bool closeColors( const QColor& color1, const QColor& color2 )
1585 {
1586   long tol = abs( color2.red()   - color1.red() ) + 
1587              abs( color2.green() - color1.green() ) +
1588        abs( color2.blue()  - color1.blue() );
1589
1590   return ( tol <= COLOR_DISTANCE );
1591 }
1592 /*!
1593   Gets new unique marker for item if possible
1594 */
1595 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine ) 
1596 {
1597   bool bOk = false;
1598   int cnt = 1;
1599   while ( !bOk ) {
1600     int aRed    = (int)( 256.0 * rand() / RAND_MAX);    // generate random color
1601     int aGreen  = (int)( 256.0 * rand() / RAND_MAX);    // ...
1602     int aBlue   = (int)( 256.0 * rand() / RAND_MAX);    // ...
1603     int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1;  // 9 markers types ( not including empty )
1604     int aLine   = (int)( 5.0 * rand() / RAND_MAX) + 1;  // 5 line types ( not including empty )
1605
1606     typeMarker = ( QwtSymbol::Style )aMarker;
1607     color      = QColor( aRed, aGreen, aBlue );
1608     typeLine   = ( Qt::PenStyle )aLine;
1609
1610     cnt++;
1611     if ( cnt == MAX_ATTEMPTS )
1612       bOk = true;
1613     else
1614       bOk = !existMarker( typeMarker, color, typeLine );
1615   }
1616 /*
1617   static int aMarker = -1;
1618   static int aColor  = -1;
1619   static int aLine   = -1;
1620
1621   if ( myColors.isEmpty() ) {
1622     // creating colors list
1623     myColors.append( Qt::white );
1624     myColors.append( Qt::blue );
1625     myColors.append( Qt::gray );
1626     myColors.append( Qt::darkGreen );
1627     myColors.append( Qt::magenta );
1628     myColors.append( Qt::darkGray );
1629     myColors.append( Qt::red );
1630     myColors.append( Qt::darkBlue );
1631     myColors.append( Qt::darkYellow );
1632     myColors.append( Qt::cyan );
1633     myColors.append( Qt::darkRed );
1634     myColors.append( Qt::darkCyan );
1635     myColors.append( Qt::yellow );
1636     myColors.append( Qt::darkMagenta );
1637     myColors.append( Qt::green );
1638     myColors.append( Qt::black );
1639   }
1640
1641   int nbMarkers = 11;                   // QwtSymbol supports 11 marker types
1642   int nbLines   = 6;                    // Qt supports 6 line types
1643   int nbColors  = myColors.count();     // number of default colors supported
1644
1645   aMarker = ( aMarker + 1 ) % nbMarkers;  
1646   if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1647   aColor  = ( aColor  + 1 ) % nbColors;
1648   aLine   = ( aLine   + 1 ) % nbLines;    
1649   if ( aLine == Qt::NoPen ) aLine++;             
1650
1651   typeMarker = ( QwtSymbol::Style )aMarker;
1652   color      = myColors[ aColor ];
1653   typeLine   = ( Qt::PenStyle )aLine;
1654   if ( !existMarker( typeMarker, color, typeLine ) )
1655     return;
1656
1657   int i, j, k;
1658   for ( i = 0; i < nbMarkers; i++ ) {
1659     aMarker = ( aMarker + 1 ) % nbMarkers;
1660     if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1661     for ( j = 0; j < nbColors; j++ ) {
1662       aColor  = ( aColor  + 1 ) % nbColors;
1663       for ( k = 0; k < nbLines; k++ ) {
1664         aLine = ( aLine + 1 ) % nbLines;
1665   if ( aLine == Qt::NoPen ) aLine++;             
1666         if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1667           typeMarker = ( QwtSymbol::Style )aMarker;
1668           color      = myColors[ aColor ];
1669           typeLine   = ( Qt::PenStyle )aLine;
1670           return;
1671         }
1672       }
1673     }
1674   }
1675 */
1676 }
1677
1678 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1679 {
1680   return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1681 }
1682
1683 QSize Plot2d_Plot2d::sizeHint() const
1684 {
1685   return QwtPlot::minimumSizeHint();
1686 }
1687
1688 /*!
1689   return minimum size for qwt plot
1690 */
1691 QSize Plot2d_Plot2d::minimumSizeHint() const
1692 {
1693   return QSize( 0, 0 );
1694 //  QSize aSize = QwtPlot::minimumSizeHint();
1695 //  return QSize(aSize.width()*3/4, aSize.height());
1696 }
1697 /*!
1698   Checks if marker belongs to any enitity
1699 */
1700 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine ) 
1701 {
1702   // getting all curves
1703   QArray<long> keys = curveKeys();
1704   //QColor aRgbColor;
1705
1706   if ( closeColors( color, backgroundColor() ) )
1707       return true;
1708   for ( int i = 0; i < (int)keys.count(); i++ )
1709   {
1710     QwtPlotCurve* crv = curve( keys[i] );
1711     if ( crv ) {
1712       QwtSymbol::Style aStyle = crv->symbol().style();
1713       QColor           aColor = crv->pen().color();
1714       Qt::PenStyle     aLine  = crv->pen().style();
1715 //      if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1716       if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1717   return true;
1718     }
1719   }
1720   return false;
1721 }
1722
1723 // TEMPORARY SOLUTION!!!  TO BE IMPLEMENTED!!!
1724 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1725 {
1726   return 0;
1727 }
1728
1729 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1730 {
1731   if( !vf )
1732     return;
1733
1734   myCurveType = vf->myCurveType;
1735   myShowLegend = vf->myShowLegend;
1736   myLegendPos = vf->myLegendPos;
1737   myMarkerSize = vf->myMarkerSize;
1738   myBackground = vf->myBackground;
1739   myTitle = vf->myTitle; 
1740   myXTitle = vf->myXTitle;
1741   myYTitle = vf->myYTitle;
1742   myY2Title = vf->myY2Title;
1743   myTitleEnabled = vf->myTitleEnabled;
1744   myXTitleEnabled = vf->myXTitleEnabled;
1745   myYTitleEnabled = vf->myYTitleEnabled;
1746   myY2TitleEnabled = vf->myY2TitleEnabled;
1747   myXGridMajorEnabled = vf->myXGridMajorEnabled;
1748   myYGridMajorEnabled = vf->myYGridMajorEnabled;
1749   myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1750   myXGridMinorEnabled = vf->myXGridMinorEnabled;
1751   myYGridMinorEnabled = vf->myYGridMinorEnabled;
1752   myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1753   myXGridMaxMajor = vf->myXGridMaxMajor;
1754   myYGridMaxMajor = vf->myYGridMaxMajor;
1755   myY2GridMaxMajor = vf->myY2GridMaxMajor;
1756   myXGridMaxMinor = vf->myXGridMaxMinor;
1757   myYGridMaxMinor = vf->myYGridMaxMinor;
1758   myY2GridMaxMinor = vf->myY2GridMaxMinor;
1759   myXMode = vf->myXMode;
1760   myYMode = vf->myYMode;
1761   mySecondY = vf->mySecondY;
1762 }
1763
1764 /*!
1765   Updates titles according to curves
1766 */
1767 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1768 void Plot2d_ViewFrame::updateTitles() 
1769 {
1770   QIntDictIterator<Plot2d_Curve> it( myCurves );
1771   QStringList aXTitles;
1772   QStringList aYTitles;
1773   QStringList aXUnits;
1774   QStringList aYUnits;
1775   QStringList aTables;
1776   int i = 0;
1777   while ( it.current() ) {
1778     // collect titles and units from all curves...
1779     QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1780     QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1781     QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1782     QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1783     
1784     aYTitles.append( yTitle );
1785     if ( aXTitles.find( xTitle ) == aXTitles.end() )
1786       aXTitles.append( xTitle );
1787     if ( aXUnits.find( xUnits ) == aXUnits.end() )
1788       aXUnits.append( xUnits );
1789     if ( aYUnits.find( yUnits ) == aYUnits.end() )
1790       aYUnits.append( yUnits );
1791
1792     QString aName = it.current()->getTableTitle();
1793     if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1794       aTables.append( aName );
1795
1796     ++it;
1797     ++i;
1798   }
1799   // ... and update plot 2d view
1800   QString xUnits, yUnits;
1801   if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1802     xUnits = BRACKETIZE( aXUnits[0] );
1803   if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1804     yUnits = BRACKETIZE( aYUnits[0] );
1805   QString xTitle, yTitle;
1806   if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1807     xTitle = aXTitles[0];
1808   if ( aYTitles.count() == 1 )
1809     yTitle = aYTitles[0];
1810
1811   if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1812     xTitle += " ";
1813   if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1814     yTitle += " ";
1815
1816   setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1817   setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1818   setTitle( true, aTables.join("; "), MainTitle, true );
1819 }