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