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