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