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