]> SALOME platform Git repositories - modules/gui.git/blob - src/Plot2d/Plot2d_ViewFrame.cxx
Salome HOME
35f4b5888cd7f093b7c22010c49e02da74c52153
[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
597   // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
598   // it crashes if switched to X/Y logarithmic mode, when one or more points have
599   // non-positive X/Y coordinate
600   if ( myXMode && curve->getMinX() <= 0. )
601     setHorScaleMode( 0, false );
602   if ( myYMode && curve->getMinY() <= 0. )
603     setVerScaleMode( 0, false );
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
1334   myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, myXMode != 0 );
1335
1336   if ( update )
1337     fitAll();
1338   emit vpModeHorChanged();
1339 }
1340 /*!
1341   Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1342 */
1343 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1344 {
1345   // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
1346   // it crashes if switched to X/Y logarithmic mode, when one or more points have
1347   // non-positive X/Y coordinate
1348   if ( mode && !isYLogEnabled() ){
1349     SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"), tr("BUT_OK"));
1350     return;
1351   }
1352
1353   myYMode = mode;
1354   myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, myYMode != 0 );
1355   if (mySecondY)
1356     myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, myYMode != 0 );
1357
1358   if ( update )
1359     fitAll();
1360   emit vpModeVerChanged();
1361 }
1362
1363 /*!
1364   Return, scale mode for horizontal axis
1365 */
1366 bool Plot2d_ViewFrame::isModeHorLinear()
1367 {
1368   return (myXMode == 0 ? true : false);
1369 }
1370
1371 /*!
1372   Return, scale mode for vertical axis
1373 */
1374 bool Plot2d_ViewFrame::isModeVerLinear()
1375 {
1376   return (myYMode == 0 ? true : false);
1377 }
1378 /*!
1379   Slot, called when user presses mouse button
1380 */
1381 void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
1382 {
1383   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1384    if (aParent)
1385      aParent->putInfo(getInfo(me.pos()));
1386   if ( myOperation == NoOpId )
1387     myOperation = testOperation( me );
1388   if ( myOperation != NoOpId ) {
1389     myPnt = me.pos();
1390     if ( myOperation == FitAreaId ) {
1391       myPlot->setOutlineStyle( Qwt::Rect );
1392     }
1393     else if ( myOperation == GlPanId ) {
1394       myPlot->setAxisScale( QwtPlot::yLeft,
1395           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2, 
1396           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1397       myPlot->setAxisScale( QwtPlot::xBottom, 
1398           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2, 
1399           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1400       if (mySecondY)
1401         myPlot->setAxisScale( QwtPlot::yRight,
1402           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2, 
1403           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1404       myPlot->replot();
1405     }
1406   }
1407   else {
1408     int btn = me.button() | me.state();
1409     if (btn == RightButton) {
1410       QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1411                                             me.pos(), btn, me.state());
1412       // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1413       parent()->eventFilter(this, aEvent);
1414     }
1415   }
1416 }
1417 /*!
1418   Slot, called when user moves mouse
1419 */
1420 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1421 {
1422   int    dx = me.pos().x() - myPnt.x();
1423   int    dy = me.pos().y() - myPnt.y();
1424
1425   if ( myOperation != NoOpId) {
1426     if ( myOperation == ZoomId ) {
1427       QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1428       QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1429
1430       myPlot->setAxisScale( QwtPlot::yLeft, 
1431           myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
1432           myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1433       myPlot->setAxisScale( QwtPlot::xBottom, 
1434           myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ), 
1435           myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1436       if (mySecondY) {
1437         QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1438         myPlot->setAxisScale( QwtPlot::yRight, 
1439           myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
1440           myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1441       }
1442       myPlot->replot();
1443       myPnt = me.pos();
1444     }
1445     else if ( myOperation == PanId ) {
1446       QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1447       QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1448
1449       myPlot->setAxisScale( QwtPlot::yLeft, 
1450           myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ), 
1451           myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1452       myPlot->setAxisScale( QwtPlot::xBottom, 
1453           myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1454           myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) ); 
1455       if (mySecondY) {
1456         QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1457         myPlot->setAxisScale( QwtPlot::yRight,
1458           myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ), 
1459           myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1460       }
1461       myPlot->replot();
1462       myPnt = me.pos();
1463     }
1464   }
1465   else {
1466      Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1467      if (aParent)
1468        aParent->putInfo(getInfo(me.pos()));
1469   }
1470 }
1471 /*!
1472   Slot, called when user releases mouse
1473 */
1474 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1475 {
1476   if ( myOperation == NoOpId && me.button() == RightButton )
1477   {
1478     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1479                               me.pos(), me.globalPos(),
1480                               me.state() );
1481     emit contextMenuRequested( &aEvent );
1482   }
1483   if ( myOperation == FitAreaId ) {
1484     QRect rect( myPnt, me.pos() );
1485     fitArea( rect );
1486   }
1487   myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1488   myPlot->setOutlineStyle( Qwt::Triangle );
1489
1490   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1491    if (aParent)
1492      aParent->putInfo(tr("INF_READY"));
1493   myOperation = NoOpId;
1494 }
1495 /*!
1496   Slot, called when user wheeling mouse
1497 */
1498 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1499
1500   double aDelta = event->delta();
1501   double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
1502
1503   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1504   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1505
1506   myPlot->setAxisScale( QwtPlot::yLeft,
1507     myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ), 
1508     myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1509   myPlot->setAxisScale( QwtPlot::xBottom, 
1510     myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1511     myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1512   if (mySecondY) {
1513     QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1514     myPlot->setAxisScale( QwtPlot::yRight,
1515       myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ), 
1516       myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1517   }
1518   myPlot->replot();
1519   myPnt = event->pos();
1520 }
1521 /*!
1522   View operations : Pan view
1523 */
1524 void Plot2d_ViewFrame::onViewPan()
1525
1526   QCursor panCursor (Qt::SizeAllCursor);
1527   myPlot->canvas()->setCursor( panCursor );
1528   myOperation = PanId;
1529   qApp->installEventFilter( this );
1530 }
1531 /*!
1532   View operations : Zoom view
1533 */
1534 void Plot2d_ViewFrame::onViewZoom() 
1535 {
1536   QPixmap zoomPixmap (imageZoomCursor);
1537   QCursor zoomCursor (zoomPixmap);
1538   myPlot->canvas()->setCursor( zoomCursor );
1539   myOperation = ZoomId;
1540   qApp->installEventFilter( this );
1541 }
1542 /*!
1543   View operations : Fot All
1544 */
1545 void Plot2d_ViewFrame::onViewFitAll() 
1546
1547   fitAll();
1548 }
1549 /*!
1550   View operations : Fit Area
1551 */
1552 void Plot2d_ViewFrame::onViewFitArea() 
1553 {
1554   myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1555   myOperation = FitAreaId;
1556   qApp->installEventFilter( this );
1557 }
1558 /*!
1559   View operations : Global panning
1560 */
1561 void Plot2d_ViewFrame::onViewGlobalPan() 
1562 {
1563   QPixmap globalPanPixmap (imageCrossCursor);
1564   QCursor glPanCursor (globalPanPixmap);
1565   myPlot->canvas()->setCursor( glPanCursor );
1566   myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1567   myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1568   if (mySecondY)
1569     myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1570   myPlot->replot();
1571   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1572   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1573
1574   myXDistance = xMap.d2() - xMap.d1();
1575   myYDistance = yMap.d2() - yMap.d1();
1576
1577   if (mySecondY) {
1578     QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1579     myYDistance2 = yMap2.d2() - yMap2.d1();
1580   }
1581   fitAll();
1582   myOperation = GlPanId;
1583   qApp->installEventFilter( this );
1584 }
1585
1586 /*!
1587   Precaution for logarithmic X scale
1588 */
1589 bool Plot2d_ViewFrame::isXLogEnabled() const
1590 {
1591   bool allPositive = true;
1592   QIntDictIterator<Plot2d_Curve> it( myCurves );
1593   for ( ; allPositive && it.current(); ++it ) {
1594     allPositive = ( it.current()->getMinX() > 0. );
1595   }
1596   return allPositive;
1597 }
1598
1599 /*!
1600   Precaution for logarithmic Y scale
1601 */
1602 bool Plot2d_ViewFrame::isYLogEnabled() const
1603 {
1604   bool allPositive = true;
1605   QIntDictIterator<Plot2d_Curve> it( myCurves );
1606   for ( ; allPositive && it.current(); ++it ) {
1607     allPositive = ( it.current()->getMinY() > 0. );
1608   }
1609   return allPositive;
1610 }
1611
1612 //=================================================================================
1613 // Plot2d_Plot2d implementation
1614 //=================================================================================
1615 /*!
1616   Constructor
1617 */
1618 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1619      : QwtPlot( parent )
1620 {
1621   // outline
1622   enableOutline( true );
1623   setOutlineStyle( Qwt::Triangle );
1624   setOutlinePen( green );
1625   // legend
1626   setAutoLegend( false );
1627   setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1628   enableLegend( false );
1629   // grid
1630   enableGridX( false );
1631   enableGridXMin( false );
1632   enableGridY( false );
1633   enableGridYMin( false );
1634   // auto scaling by default
1635   setAxisAutoScale( QwtPlot::yLeft );
1636   setAxisAutoScale( QwtPlot::yRight );
1637   setAxisAutoScale( QwtPlot::xBottom );
1638 }
1639 /*!
1640   Recalculates and redraws Plot 2d view 
1641 */
1642 void Plot2d_Plot2d::replot()
1643 {
1644   updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
1645   QwtPlot::replot(); 
1646 }
1647
1648 /*!
1649   Checks if two colors are close to each other [ static ]
1650   uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1651 */
1652 const long COLOR_DISTANCE = 100;
1653 const int  MAX_ATTEMPTS   = 10;
1654 static bool closeColors( const QColor& color1, const QColor& color2 )
1655 {
1656   long tol = abs( color2.red()   - color1.red() ) + 
1657              abs( color2.green() - color1.green() ) +
1658        abs( color2.blue()  - color1.blue() );
1659
1660   return ( tol <= COLOR_DISTANCE );
1661 }
1662 /*!
1663   Gets new unique marker for item if possible
1664 */
1665 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine ) 
1666 {
1667   bool bOk = false;
1668   int cnt = 1;
1669   while ( !bOk ) {
1670     int aRed    = (int)( 256.0 * rand() / RAND_MAX);    // generate random color
1671     int aGreen  = (int)( 256.0 * rand() / RAND_MAX);    // ...
1672     int aBlue   = (int)( 256.0 * rand() / RAND_MAX);    // ...
1673     int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1;  // 9 markers types ( not including empty )
1674     int aLine   = (int)( 5.0 * rand() / RAND_MAX) + 1;  // 5 line types ( not including empty )
1675
1676     typeMarker = ( QwtSymbol::Style )aMarker;
1677     color      = QColor( aRed, aGreen, aBlue );
1678     typeLine   = ( Qt::PenStyle )aLine;
1679
1680     cnt++;
1681     if ( cnt == MAX_ATTEMPTS )
1682       bOk = true;
1683     else
1684       bOk = !existMarker( typeMarker, color, typeLine );
1685   }
1686 /*
1687   static int aMarker = -1;
1688   static int aColor  = -1;
1689   static int aLine   = -1;
1690
1691   if ( myColors.isEmpty() ) {
1692     // creating colors list
1693     myColors.append( Qt::white );
1694     myColors.append( Qt::blue );
1695     myColors.append( Qt::gray );
1696     myColors.append( Qt::darkGreen );
1697     myColors.append( Qt::magenta );
1698     myColors.append( Qt::darkGray );
1699     myColors.append( Qt::red );
1700     myColors.append( Qt::darkBlue );
1701     myColors.append( Qt::darkYellow );
1702     myColors.append( Qt::cyan );
1703     myColors.append( Qt::darkRed );
1704     myColors.append( Qt::darkCyan );
1705     myColors.append( Qt::yellow );
1706     myColors.append( Qt::darkMagenta );
1707     myColors.append( Qt::green );
1708     myColors.append( Qt::black );
1709   }
1710
1711   int nbMarkers = 11;                   // QwtSymbol supports 11 marker types
1712   int nbLines   = 6;                    // Qt supports 6 line types
1713   int nbColors  = myColors.count();     // number of default colors supported
1714
1715   aMarker = ( aMarker + 1 ) % nbMarkers;  
1716   if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1717   aColor  = ( aColor  + 1 ) % nbColors;
1718   aLine   = ( aLine   + 1 ) % nbLines;    
1719   if ( aLine == Qt::NoPen ) aLine++;             
1720
1721   typeMarker = ( QwtSymbol::Style )aMarker;
1722   color      = myColors[ aColor ];
1723   typeLine   = ( Qt::PenStyle )aLine;
1724   if ( !existMarker( typeMarker, color, typeLine ) )
1725     return;
1726
1727   int i, j, k;
1728   for ( i = 0; i < nbMarkers; i++ ) {
1729     aMarker = ( aMarker + 1 ) % nbMarkers;
1730     if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1731     for ( j = 0; j < nbColors; j++ ) {
1732       aColor  = ( aColor  + 1 ) % nbColors;
1733       for ( k = 0; k < nbLines; k++ ) {
1734         aLine = ( aLine + 1 ) % nbLines;
1735   if ( aLine == Qt::NoPen ) aLine++;             
1736         if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1737           typeMarker = ( QwtSymbol::Style )aMarker;
1738           color      = myColors[ aColor ];
1739           typeLine   = ( Qt::PenStyle )aLine;
1740           return;
1741         }
1742       }
1743     }
1744   }
1745 */
1746 }
1747
1748 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1749 {
1750   return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1751 }
1752
1753 QSize Plot2d_Plot2d::sizeHint() const
1754 {
1755   return QwtPlot::minimumSizeHint();
1756 }
1757
1758 /*!
1759   return minimum size for qwt plot
1760 */
1761 QSize Plot2d_Plot2d::minimumSizeHint() const
1762 {
1763   return QSize( 0, 0 );
1764 //  QSize aSize = QwtPlot::minimumSizeHint();
1765 //  return QSize(aSize.width()*3/4, aSize.height());
1766 }
1767 /*!
1768   Checks if marker belongs to any enitity
1769 */
1770 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine ) 
1771 {
1772   // getting all curves
1773   QArray<long> keys = curveKeys();
1774   //QColor aRgbColor;
1775
1776   if ( closeColors( color, backgroundColor() ) )
1777       return true;
1778   for ( int i = 0; i < (int)keys.count(); i++ )
1779   {
1780     QwtPlotCurve* crv = curve( keys[i] );
1781     if ( crv ) {
1782       QwtSymbol::Style aStyle = crv->symbol().style();
1783       QColor           aColor = crv->pen().color();
1784       Qt::PenStyle     aLine  = crv->pen().style();
1785 //      if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1786       if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1787   return true;
1788     }
1789   }
1790   return false;
1791 }
1792
1793 // TEMPORARY SOLUTION!!!  TO BE IMPLEMENTED!!!
1794 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1795 {
1796   return 0;
1797 }
1798
1799 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1800 {
1801   if( !vf )
1802     return;
1803
1804   myCurveType = vf->myCurveType;
1805   myShowLegend = vf->myShowLegend;
1806   myLegendPos = vf->myLegendPos;
1807   myMarkerSize = vf->myMarkerSize;
1808   myBackground = vf->myBackground;
1809   myTitle = vf->myTitle; 
1810   myXTitle = vf->myXTitle;
1811   myYTitle = vf->myYTitle;
1812   myY2Title = vf->myY2Title;
1813   myTitleEnabled = vf->myTitleEnabled;
1814   myXTitleEnabled = vf->myXTitleEnabled;
1815   myYTitleEnabled = vf->myYTitleEnabled;
1816   myY2TitleEnabled = vf->myY2TitleEnabled;
1817   myXGridMajorEnabled = vf->myXGridMajorEnabled;
1818   myYGridMajorEnabled = vf->myYGridMajorEnabled;
1819   myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1820   myXGridMinorEnabled = vf->myXGridMinorEnabled;
1821   myYGridMinorEnabled = vf->myYGridMinorEnabled;
1822   myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1823   myXGridMaxMajor = vf->myXGridMaxMajor;
1824   myYGridMaxMajor = vf->myYGridMaxMajor;
1825   myY2GridMaxMajor = vf->myY2GridMaxMajor;
1826   myXGridMaxMinor = vf->myXGridMaxMinor;
1827   myYGridMaxMinor = vf->myYGridMaxMinor;
1828   myY2GridMaxMinor = vf->myY2GridMaxMinor;
1829   myXMode = vf->myXMode;
1830   myYMode = vf->myYMode;
1831   mySecondY = vf->mySecondY;
1832 }
1833
1834 /*!
1835   Updates titles according to curves
1836 */
1837 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1838 void Plot2d_ViewFrame::updateTitles() 
1839 {
1840   QIntDictIterator<Plot2d_Curve> it( myCurves );
1841   QStringList aXTitles;
1842   QStringList aYTitles;
1843   QStringList aXUnits;
1844   QStringList aYUnits;
1845   QStringList aTables;
1846   int i = 0;
1847   while ( it.current() ) {
1848     // collect titles and units from all curves...
1849     QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1850     QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1851     QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1852     QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1853     
1854     aYTitles.append( yTitle );
1855     if ( aXTitles.find( xTitle ) == aXTitles.end() )
1856       aXTitles.append( xTitle );
1857     if ( aXUnits.find( xUnits ) == aXUnits.end() )
1858       aXUnits.append( xUnits );
1859     if ( aYUnits.find( yUnits ) == aYUnits.end() )
1860       aYUnits.append( yUnits );
1861
1862     QString aName = it.current()->getTableTitle();
1863     if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1864       aTables.append( aName );
1865
1866     ++it;
1867     ++i;
1868   }
1869   // ... and update plot 2d view
1870   QString xUnits, yUnits;
1871   if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1872     xUnits = BRACKETIZE( aXUnits[0] );
1873   if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1874     yUnits = BRACKETIZE( aYUnits[0] );
1875   QString xTitle, yTitle;
1876   if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1877     xTitle = aXTitles[0];
1878   if ( aYTitles.count() == 1 )
1879     yTitle = aYTitles[0];
1880
1881   if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1882     xTitle += " ";
1883   if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1884     yTitle += " ";
1885
1886   setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1887   setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1888   setTitle( true, aTables.join("; "), MainTitle, true );
1889 }
1890
1891 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
1892 {
1893 #ifdef WIN32
1894   return false;
1895
1896 #else
1897   bool res = false;
1898   if( myPlot )
1899   {
1900     QPaintDevice* pd = 0;
1901     if( format=="PS" )
1902     {
1903       QPrinter* pr = new QPrinter( QPrinter::HighResolution );
1904       pr->setPageSize( QPrinter::A4 );
1905       pr->setOutputToFile( true );
1906       pr->setOutputFileName( file );
1907       pr->setPrintProgram( "" );
1908       pd = pr;
1909     }
1910
1911     if( pd )
1912     {
1913       myPlot->print( *pd );
1914       res = true;
1915       delete pd;
1916     }
1917   }
1918   return res;
1919 #endif
1920 }
1921
1922 QString Plot2d_ViewFrame::getVisualParameters()
1923 {
1924   double xmin, xmax, ymin, ymax, y2min, y2max;
1925   getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
1926   QString retStr;
1927   retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e", myXMode,
1928                   myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max );
1929   return retStr; 
1930 }
1931
1932 void Plot2d_ViewFrame::setVisualParameters( const QString& parameters )
1933 {
1934   QStringList paramsLst = QStringList::split( '*', parameters, true );
1935   if ( paramsLst.size() == 9 ) {
1936     double xmin, xmax, ymin, ymax, y2min, y2max;
1937     myXMode = paramsLst[0].toInt();
1938     myYMode = paramsLst[1].toInt();
1939     mySecondY = (bool)paramsLst[2].toInt();
1940     xmin =  paramsLst[3].toDouble();
1941     xmax =  paramsLst[4].toDouble();
1942     ymin =  paramsLst[5].toDouble();
1943     ymax =  paramsLst[6].toDouble();
1944     y2min = paramsLst[7].toDouble();
1945     y2max = paramsLst[8].toDouble();
1946
1947     if (mySecondY)
1948       setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
1949     setHorScaleMode( myXMode, /*update=*/false );
1950     setVerScaleMode( myYMode, /*update=*/false );
1951     
1952     if (mySecondY) {
1953       QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1954       myYDistance2 = yMap2.d2() - yMap2.d1();
1955     }
1956
1957     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
1958     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
1959   }  
1960 }