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