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