Salome HOME
Merge from branch mpa/qwt6_porting
[modules/gui.git] / src / Plot2d / Plot2d_ViewFrame.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "Plot2d_ViewFrame.h"
24
25 #include "Plot2d_Prs.h"
26 #include "Plot2d_Curve.h"
27 #include "Plot2d_PlotItems.h"
28 #include "Plot2d_FitDataDlg.h"
29 #ifndef NO_SUIT
30 #include "Plot2d_ViewWindow.h"
31 #endif
32 #include "Plot2d_SetupViewDlg.h"
33 #ifndef NO_ANALYTICAL_CURVES
34 #include "Plot2d_AnalyticalCurveDlg.h"
35 #include "Plot2d_AnalyticalCurve.h"
36 #endif
37 #include "Plot2d_ToolTip.h"
38
39 #ifndef NO_SUIT
40 #include "SUIT_Tools.h"
41 #include "SUIT_Session.h"
42 #include "SUIT_MessageBox.h"
43 #include "SUIT_ResourceMgr.h"
44 #include "SUIT_Application.h"
45 #else
46 #include <QMessageBox>
47 #endif
48
49 #include <QApplication>
50 #include <QToolBar>
51 #include <QToolButton>
52 #include <QCursor>
53 #include <QColorDialog>
54 #include <QLayout>
55 #include <QMap>
56 #include <QPainter>
57 #include <QPaintDevice>
58 #include <QEvent>
59 #include <QMouseEvent>
60 #include <QContextMenuEvent>
61 #include <QPrinter>
62 #include <QPalette>
63 #include <QLocale>
64 #include <QXmlStreamWriter>
65 #include <QXmlStreamReader>
66
67 #include <qwt_math.h>
68 #include <qwt_plot_layout.h>
69 #include <qwt_plot_canvas.h>
70 #include <qwt_scale_div.h>
71 #include <qwt_plot_marker.h>
72 #include <qwt_plot_curve.h>
73 #include <qwt_plot_grid.h>
74 #include <qwt_scale_engine.h>
75 #include <qwt_plot_zoomer.h>
76 #include <qwt_curve_fitter.h>
77 #include <qwt_plot_renderer.h>
78
79 #include <stdlib.h>
80 #include <limits>
81 #include <qprinter.h>
82
83 #include <qwt_legend.h>
84 #include <qwt_scale_widget.h>
85
86 #define DEFAULT_LINE_WIDTH     0     // (default) line width
87 #define DEFAULT_MARKER_SIZE    9     // default marker size
88 #define MIN_RECT_SIZE          11    // min sensibility area size
89
90 #define FITALL_EVENT           ( QEvent::User + 9999 )
91
92 const char* imageZoomCursor[] = {
93 "32 32 3 1",
94 ". c None",
95 "a c #000000",
96 "# c #ffffff",
97 "................................",
98 "................................",
99 ".#######........................",
100 "..aaaaaaa.......................",
101 "................................",
102 ".............#####..............",
103 "...........##.aaaa##............",
104 "..........#.aa.....a#...........",
105 ".........#.a.........#..........",
106 ".........#a..........#a.........",
107 "........#.a...........#.........",
108 "........#a............#a........",
109 "........#a............#a........",
110 "........#a............#a........",
111 "........#a............#a........",
112 ".........#...........#.a........",
113 ".........#a..........#a.........",
114 ".........##.........#.a.........",
115 "........#####.....##.a..........",
116 ".......###aaa#####.aa...........",
117 "......###aa...aaaaa.......#.....",
118 ".....###aa................#a....",
119 "....###aa.................#a....",
120 "...###aa...............#######..",
121 "....#aa.................aa#aaaa.",
122 ".....a....................#a....",
123 "..........................#a....",
124 "...........................a....",
125 "................................",
126 "................................",
127 "................................",
128 "................................"};
129
130 const char* imageCrossCursor[] = {
131   "32 32 3 1",
132   ". c None",
133   "a c #000000",
134   "# c #ffffff",
135   "................................",
136   "................................",
137   "................................",
138   "................................",
139   "................................",
140   "................................",
141   "................................",
142   "...............#................",
143   "...............#a...............",
144   "...............#a...............",
145   "...............#a...............",
146   "...............#a...............",
147   "...............#a...............",
148   "...............#a...............",
149   "...............#a...............",
150   ".......#################........",
151   "........aaaaaaa#aaaaaaaaa.......",
152   "...............#a...............",
153   "...............#a...............",
154   "...............#a...............",
155   "...............#a...............",
156   "...............#a...............",
157   "...............#a...............",
158   "...............#a...............",
159   "................a...............",
160   "................................",
161   "................................",
162   "................................",
163   "................................",
164   "................................",
165   "................................",
166   "................................"};
167
168 #ifdef WIN32
169   #ifdef max
170     #undef max
171   #endif
172
173   #ifdef min
174     #undef min
175   #endif
176 #endif
177
178 /*!
179   Constructor
180 */
181 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
182      : QWidget (parent, 0),
183        myOperation( NoOpId ),
184        myCurveType( 1 ),
185        myShowLegend( true ), myLegendPos( 1 ), myLegendSymbolType( 0 ), myLegendFont("Helvetic",12),
186        myLegendColor(Qt::black), mySelectedLegendFontColor( Qt::darkBlue ),
187        myMarkerSize( DEFAULT_MARKER_SIZE ),
188        myBackground( Qt::white ),
189        mySelectionColor( Qt::gray ),
190        myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
191        myTitleEnabled( true ), myXTitleEnabled( true ),
192        myYTitleEnabled( true ), myY2TitleEnabled (true),
193        myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ),
194        myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
195        myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
196        myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
197        myXMode( 0 ), myYMode( 0 ),myNormLMin(false), myNormLMax(false), myNormRMin(false), myNormRMax(false),
198        mySecondY( false ), myIsDefTitle( true )
199 {
200   setObjectName( title );
201   myRNormAlgo = new Plot2d_NormalizeAlgorithm(this);
202   myLNormAlgo = new Plot2d_NormalizeAlgorithm(this);
203   /* Plot 2d View */
204   QVBoxLayout* aLayout = new QVBoxLayout( this );
205   aLayout->setMargin(0);
206   myPlot = new Plot2d_Plot2d( this );
207   new Plot2d_ToolTip( this );
208
209   aLayout->addWidget( myPlot );
210
211 #ifndef NO_SUIT
212   Init();
213 #endif
214 }
215 /*!
216   Destructor
217 */
218 Plot2d_ViewFrame::~Plot2d_ViewFrame()
219 {
220 }
221 /*!
222   Performs the initial setup.
223 */
224 void Plot2d_ViewFrame::Init()
225 {
226   /* Initial Setup - get from the preferences */
227   readPreferences();
228
229   setCurveType( myCurveType, false );
230   setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
231   setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
232             myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
233
234   setTitle( myTitleEnabled,  myTitle,  MainTitle, false );
235   setTitle( myXTitleEnabled, myXTitle, XTitle, false );
236   setTitle( myYTitleEnabled, myYTitle, YTitle, false );
237
238   if (mySecondY)
239     setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
240   setHorScaleMode( myXMode, false );
241   setVerScaleMode( myYMode, false );
242   setBackgroundColor( myBackground );
243   setSelectionColor( mySelectionColor );
244   setLegendPos( myLegendPos );
245   setLegendSymbolType( myLegendSymbolType );
246   setLegendFont( myLegendFont );
247   setLegendFontColor( myLegendColor );
248   setSelectedLegendFontColor( mySelectedLegendFontColor );
249   showLegend( myShowLegend, false );
250   myPlot->replot();
251
252   QWidget* aParent = parentWidget();
253   if ( aParent ) {
254     resize( (int)(0.8 * aParent->width()), (int)(0.8 * aParent->height()) );
255   }
256   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
257   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
258   myXDistance = xMap.s2() - xMap.s1();
259   myYDistance = yMap.s2() - yMap.s1();
260   myYDistance2 = 0;
261   if (mySecondY) {
262     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
263     myYDistance2 = yMap2.s2() - yMap2.s1();
264   }
265   myPlot->canvas()->installEventFilter( this );
266 }
267 void Plot2d_ViewFrame::SetPreference()
268 {
269   readPreferences();
270   setBackgroundColor( myBackground );
271   setSelectionColor( mySelectionColor );
272   setCurveType( myCurveType, true );
273   setMarkerSize( myMarkerSize, true );
274   showLegend( myShowLegend, true );
275   setLegendPos( myLegendPos );
276   setLegendSymbolType( myLegendSymbolType );
277   setLegendFont( myLegendFont );
278   setLegendFontColor( myLegendColor );
279   setSelectedLegendFontColor( mySelectedLegendFontColor );
280   myPlot->replot();
281 }
282 /*!
283   Gets window's central widget
284 */
285 QWidget* Plot2d_ViewFrame::getViewWidget()
286 {
287   return (QWidget*)myPlot;
288 }
289 /*!
290   Actually this method just re-displays all curves which are presented in the viewer
291 */
292 void Plot2d_ViewFrame::DisplayAll()
293 {
294   objectList olist;
295   getObjects( olist );
296   foreach ( Plot2d_Object* o, olist )
297     updateObject( o, false );
298   myPlot->replot();
299   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
300 }
301 /*!
302    Removes all curves from the view
303 */
304 void Plot2d_ViewFrame::EraseAll()
305 {
306   objectList anObjects;
307   getObjects( anObjects );
308   eraseObjects( anObjects, false );
309   myObjects.clear();
310
311   // 1)- Erase all the intermittent segments who connect curves
312
313   int nbSeg = myIntermittentSegmentList.size();
314   if (nbSeg > 0)
315   {
316       for (int iseg=0; iseg < nbSeg; iseg++)
317       {
318           QwtPlotCurve *segment = myIntermittentSegmentList[iseg];
319
320           segment->detach();  // erase in QwtPlot window
321           delete segment;
322       }
323       myIntermittentSegmentList.clear();
324   }
325
326   // 3)- Erase all QwtPlotCurve associated with the Plot2d_Curve
327
328   int nbCur1 = myQwtPlotCurveList.size();
329   if (nbCur1 > 0)
330   {
331       for (int icur=0; icur < nbCur1; icur++)
332       {
333           QwtPlotItem *curve0 = myQwtPlotCurveList[icur];
334           QwtPlotCurve *curve = static_cast<QwtPlotCurve*>(curve0);
335
336           if (curve)
337           {
338               delete curve;
339           }
340       }
341       myQwtPlotCurveList.clear();
342   }
343
344   // 4)- Erase all curves Plot2d_Curve
345
346   int nbCur = myPlot2dCurveList.size();
347   if (nbCur > 0)
348   {
349       for (int icur=0; icur < nbCur; icur++)
350       {
351           Plot2d_Curve *curve = myPlot2dCurveList[icur];
352
353           if (curve)
354           {
355               delete curve;
356           }
357       }
358       myPlot2dCurveList.clear();
359   }
360   myPlot->replot();
361   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
362 }
363 /*!
364   Redraws viewframe contents
365 */
366 void Plot2d_ViewFrame::Repaint()
367 {
368   myPlot->replot();
369 }
370 /*!
371   Display presentation
372 */
373 void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
374 {
375   if ( !prs || prs->IsNull() )
376     return;
377
378   setEnableAxis( QwtPlot::yRight, prs->isSecondY() ); // VSR: is it correct? maybe we should only enable second Y axis if required
379
380   // display all objects from presentation
381   objectList anObjects = prs->getObjects();
382   displayObjects( anObjects );
383   setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
384   setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
385             myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
386   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
387 }
388
389 /*!
390   Erase presentation
391 */
392 void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
393 {
394   if ( !prs || prs->IsNull() )
395     return;
396
397   // erase all objects from presentation
398   objectList anObjects = prs->getObjects();
399   eraseObjects( anObjects );
400   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
401 }
402
403 bool Plot2d_ViewFrame::eventFilter( QObject* watched, QEvent* e )
404 {
405   if ( watched == myPlot->canvas() ) {
406     int aType = e->type();
407     switch( aType ) {
408       case QEvent::MouseMove: {
409         QMouseEvent* me = (QMouseEvent*)e;
410         if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
411           QMouseEvent m( QEvent::MouseMove, me->pos(), me->button(),
412                          me->buttons(), me->modifiers() );
413           if ( plotMouseMoved( m ) )
414             return true;
415         }
416         break;
417       }
418       case QEvent::MouseButtonPress: {
419         QMouseEvent* me = (QMouseEvent*)e;
420         if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
421           QMouseEvent m( QEvent::MouseButtonPress, me->pos(), me->button(),
422                           me->buttons(), me->modifiers() );
423           plotMousePressed( m );
424         }
425         break;
426       }
427       case QEvent::MouseButtonRelease: {
428         QMouseEvent* me = (QMouseEvent*)e;
429         if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
430           QMouseEvent m( QEvent::MouseButtonRelease, me->pos(), me->button(),
431                          me->buttons(), me->modifiers() );
432           plotMouseReleased( m );
433         }
434         break;
435       }
436     case QEvent::ContextMenu:
437       // Fix from SLN
438       // Do nothing because context menu is called from MouseRelease
439       return true;
440     }
441   }
442   return QWidget::eventFilter( watched, e );
443 }
444
445 /*!
446   Sets title
447 */
448 void Plot2d_ViewFrame::setTitle( const QString& title )
449 {
450   setTitle( myTitleEnabled, title, MainTitle, true );
451   myIsDefTitle = false;
452 }
453
454 /*!
455   Gets title
456 */
457 QString Plot2d_ViewFrame::getTitle() const
458 {
459   return myTitle;
460 }
461
462 /*!
463   Reads Plot2d view settings from the preferences
464 */
465 void Plot2d_ViewFrame::readPreferences()
466 {
467 #ifndef NO_SUIT
468   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
469
470   myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
471   setCurveType( resMgr->integerValue( "Plot2d", "CurveType", myCurveType ) );
472
473   myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
474   myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
475   myLegendSymbolType = resMgr->integerValue( "Plot2d", "LegendSymbolType", myLegendSymbolType );
476   myLegendFont = resMgr->fontValue( "Plot2d", "LegendFont", myLegendFont );
477   myLegendColor = resMgr->colorValue( "Plot2d", "LegendFontColor", myLegendColor );
478   mySelectedLegendFontColor = resMgr->colorValue( "Plot2d", "SelectedLegendFontColor", mySelectedLegendFontColor );
479   myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
480   myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
481   mySelectionColor = resMgr->colorValue( "Plot2d", "SelectionColor", mySelectionColor );
482
483   myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
484   myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
485   myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
486   myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
487
488   myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
489   myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
490   myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
491
492   myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
493   myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
494   myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
495
496   myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
497   myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
498   if ( mySecondY )
499     myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
500
501   myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
502   myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
503   if ( mySecondY )
504     myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
505
506   setHorScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode ) ) ), false );
507   setVerScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode ) ) ), false );
508   setNormLMinMode( resMgr->booleanValue( "Plot2d", "VerNormLMinMode", myNormLMin ) );
509   setNormLMaxMode( resMgr->booleanValue( "Plot2d", "VerNormLMaxMode", myNormLMax ) );
510   setNormRMinMode( resMgr->booleanValue( "Plot2d", "VerNormRMinMode", myNormRMin ) );
511   setNormRMaxMode( resMgr->booleanValue( "Plot2d", "VerNormRMaxMode", myNormRMax ) );
512   QColor c = resMgr->colorValue( "Plot2d", "DeviationMarkerColor", QColor(255,0,0));
513   myPlot->setProperty(PLOT2D_DEVIATION_COLOR, c);
514   myPlot->setProperty(PLOT2D_DEVIATION_LW,
515                       resMgr->integerValue( "Plot2d", "DeviationMarkerLineWidth", 1));
516   myPlot->setProperty(PLOT2D_DEVIATION_TS,
517                       resMgr->integerValue( "Plot2d", "DeviationMarkerTickSize", 2));
518 #endif
519 }
520
521 /*!
522   Writes Plot2d view settings to the preferences
523 */
524 void Plot2d_ViewFrame::writePreferences()
525 {
526 #ifndef NO_SUIT
527   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
528
529   resMgr->setValue( "Plot2d", "CurveType", myCurveType );
530   resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
531   resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
532   resMgr->setValue( "Plot2d", "LegendSymbolType", myLegendSymbolType );
533   resMgr->setValue( "Plot2d", "LegendFont", myLegendFont );
534   resMgr->setValue( "Plot2d", "LegendFontColor", myLegendColor );
535   resMgr->setValue( "Plot2d", "SelectedLegendFontColor", mySelectedLegendFontColor );
536   resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
537   resMgr->setValue( "Plot2d", "Background", myBackground );
538   resMgr->setValue( "Plot2d", "SelectionColor", mySelectionColor );
539   resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
540   resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
541   resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
542   resMgr->setValue( "Plot2d", "DeviationMarkerColor", myPlot->property(PLOT2D_DEVIATION_COLOR).value<QColor>() );
543   resMgr->setValue( "Plot2d", "DeviationMarkerLineWidth", myPlot->property(PLOT2D_DEVIATION_LW).toInt() );
544   resMgr->setValue( "Plot2d", "DeviationMarkerTickSize", myPlot->property(PLOT2D_DEVIATION_TS).toInt() );
545   if ( mySecondY )
546     resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
547
548   resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
549   resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
550   resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
551   resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
552
553   resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
554   resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
555
556   resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
557   resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
558
559   resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
560
561   if ( mySecondY )
562   {
563     resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
564     resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
565     resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
566     resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
567   }
568
569   resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
570   resMgr->setValue( "Plot2d", "VerNormLMinMode", myNormLMin );
571   resMgr->setValue( "Plot2d", "VerNormLMaxMode", myNormLMax );
572   resMgr->setValue( "Plot2d", "VerNormRMinMode", myNormRMin );
573   resMgr->setValue( "Plot2d", "VerNormRMaxMode", myNormRMax );
574 #endif
575 }
576
577 /*!
578   Prints mouse cursor coordinates into string
579 */
580 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt )
581 {
582   int i;
583   QwtValueList aTicks;
584   bool xFound = false, yFound = false;
585   double xCoord, yCoord;
586   const QwtScaleDiv& aXscale = myPlot->axisScaleDiv( QwtPlot::xBottom );
587   aTicks = aXscale.ticks( QwtScaleDiv::MajorTick );
588   for ( i = 0; i < aTicks.count(); i++ ) {
589     double majXmark = aTicks[i];
590     int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
591     if ( xmark-2 == pnt.x() ) {
592       xCoord = majXmark;
593       xFound = true;
594       break;
595     }
596   }
597   if ( !xFound ) {
598     aTicks = aXscale.ticks( QwtScaleDiv::MinorTick );
599     for ( i = 0; i < aTicks.count(); i++ ) {
600       double minXmark = aTicks[i];
601       int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
602       if ( xmark-2 == pnt.x() ) {
603         xCoord = minXmark;
604         xFound = true;
605         break;
606       }
607     }
608   }
609   const QwtScaleDiv& aYscale = myPlot->axisScaleDiv( QwtPlot::yLeft );
610   aTicks = aYscale.ticks( QwtScaleDiv::MajorTick );
611   for ( i = 0; i < aTicks.count(); i++ ) {
612     double majYmark = aTicks[i];
613     int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
614     if ( ymark-2 == pnt.y() ) {
615       yCoord = majYmark;
616       yFound = true;
617       break;
618     }
619   }
620   if ( !yFound ) {
621     aTicks = aYscale.ticks( QwtScaleDiv::MinorTick );
622     for ( i = 0; i < aTicks.count(); i++ ) {
623       double minYmark = aTicks[i];
624       int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
625       if ( ymark-2 == pnt.y() ) {
626         yCoord = minYmark;
627         yFound = true;
628         break;
629       }
630     }
631   }
632
633   QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).trimmed();
634   if ( strX == "-0" )
635     strX = "0";
636   QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).trimmed();
637   if ( strY == "-0" )
638     strY = "0";
639   QString info = "";
640
641   if (mySecondY) {
642     bool yFound2 = false;
643     double yCoord2;
644
645     const QwtScaleDiv& aYscale2 = myPlot->axisScaleDiv( QwtPlot::yRight );
646     aTicks = aYscale2.ticks( QwtScaleDiv::MajorTick );
647     for ( i = 0; i < aTicks.count(); i++ ) {
648       double majYmark = aTicks[i];
649       int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
650       if ( ymark-2 == pnt.y() ) {
651         yCoord2 = majYmark;
652         yFound2 = true;
653         break;
654       }
655     }
656     if ( !yFound2 ) {
657       aTicks = aYscale2.ticks( QwtScaleDiv::MinorTick );
658       for ( i = 0; i < aTicks.count(); i++ ) {
659         double minYmark = aTicks[i];
660         int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
661         if ( ymark-2 == pnt.y() ) {
662           yCoord2 = minYmark;
663           yFound2 = true;
664           break;
665         }
666       }
667     }
668     QString strY2 = QString::number( yFound2 ? yCoord2 :
669                       myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).trimmed();
670     if ( strY2 == "-0" )
671     strY2 = "0";
672     info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
673   }
674   else
675     info = tr("INF_COORDINATES").arg( strX ).arg( strY );
676
677   return info;
678 }
679
680 /*!
681  * Display curves of the list of lists by systems and components
682  * - the first level list contains NbSytems lists of second level
683  * - a second level list contains NbComponents curves
684  * |         system 1         |         system 2         | ..... |          system N        |
685  * | compo1 compo2 ... compoM | compo1 compo2 ... compoM | ..... | compo1 compo2 ... compoM |
686  *
687  * Draw points markers and create associated tooltips.
688  * Draw connection segments (intermittent line) between all the curves of a component.
689  * \return the list of underlying plot curve that defines the complex cuve at once. In case of success the vector is at least of size 1. The first one is the curve used by the legend.
690  */
691 QVector< QVector<QwtPlotCurve *> > Plot2d_ViewFrame::displayPlot2dCurveList( const QList< QList<Plot2d_Curve*> >& sysCoCurveList,
692                                                                              bool                          displayLegend,
693                                                                              const QList< QList<bool> >&   sides)
694 {
695   //std::cout << "Plot2d_ViewFrame::displayPlot2dCurveList() 1" << std::endl;
696
697   // Systems number
698   int nbSystem = sysCoCurveList.size();
699
700   // Composants number by system
701   int nbComponent = (sysCoCurveList.at(0)).size();
702
703   // Total number of curves
704
705    // 1)- Construction of a list by component and by system
706
707    // |      component 1      |      component 2      | ..... |      component M      |
708    // | syst1 syst2 ... systN | syst1 syst2 ... systN | ..... | syst1 syst2 ... systN |
709
710   QList<Plot2d_Curve*> plot2dCurveCoSysList;
711   QList<bool>          sidesList;
712   for (int icom = 0; icom < nbComponent; icom++)
713   {
714       for (int isys = 0; isys < nbSystem; isys++)
715       {
716           // The system curves list
717           const QList<Plot2d_Curve*>& sysCurveList=sysCoCurveList.at(isys);
718           plot2dCurveCoSysList.append(sysCurveList.at(icom));
719           //
720           const QList<bool>& sysSideList=sides.at(isys);
721           sidesList.append(sysSideList.at(icom));
722       }
723   }
724   // 2)- Display list curves by a component's curves group
725   //     Draw connection segments (intermittent line) between the curves
726   QVector< QVector<QwtPlotCurve *> > ret=displayPlot2dCurveList( plot2dCurveCoSysList, nbSystem, displayLegend, sidesList);
727   // 3)- Size of graduations labels and texts under X axis
728   QwtScaleWidget *wid = myPlot->axisWidget( QwtPlot::xBottom);
729   wid->setTitle("  "); // to make the names readable under X axis.
730   QFont xFont = myPlot->axisFont(QwtPlot::xBottom);
731   xFont.setPointSize(8);
732   myPlot->setAxisFont(QwtPlot::xBottom, xFont);
733   return ret;
734 }
735
736
737 /*!
738  * Display list of curves by group of consecutive curves.
739  *
740  * Draw points markers and create associated tooltips
741  * Draw connection segments (intermittent line) between the curves
742  * \param [in] sides sorted as in \b curveList. If true->right if false->left
743  * \return the list of underlying plot curve that defines the complex cuve at once. In case of success the vector is at least of size 1. The first one is the curve used by the legend.
744  */
745 QVector< QVector<QwtPlotCurve *> > Plot2d_ViewFrame::displayPlot2dCurveList( const QList<Plot2d_Curve*>& curveList,
746                                                                              int  groupSize,
747                                                                              bool  displayLegend, const QList< bool >& sides)
748 {
749   // Consider the new legend's entries
750   // (PB: to update the legend we must remove it and put a new QwtAbstractLegend in the QwtPlot)
751   myPlot->insertLegend( (QwtAbstractLegend*)NULL); // we remove here, we shall put at the end
752
753   int nbAllCurves = curveList.size();
754   int nbGroups    = nbAllCurves / groupSize;
755   QVector< QVector<QwtPlotCurve *> > vectCurve(nbGroups);
756   int ig, icur;
757   int icur1, icur2;  // curves indices in a group
758
759   // I)- Compute X range and Y range for all the curves' points of all groups
760   //     In the graphic view, set the Y range 's bounds for all groups of curves
761
762   // For all groups of curves
763   double XallGroupMin=std::numeric_limits<double>::max(), XallGroupMax=-std::numeric_limits<double>::max();
764   double YRightallGroupMin=std::numeric_limits<double>::max(), YRightallGroupMax=-std::numeric_limits<double>::max();
765   double YLeftallGroupMin=std::numeric_limits<double>::max(), YLeftallGroupMax=-std::numeric_limits<double>::max();
766   icur1 = 0;
767   for (ig=0; ig < nbGroups; ig++)  //*1*
768   {
769       icur2 = icur1 + groupSize -1;
770
771       // For all curves in one group
772       double XgroupMin, XgroupMax;
773       double YgroupMin, YgroupMax;
774
775       // For one curve
776       double XcurveMin, XcurveMax;
777       double YcurveMin, YcurveMax;
778       double *Xval;
779       double *Yval;
780       int nbPoints;
781
782       // Compute X range and Y range for all the curves' points in the group
783       bool side=false;
784       for (icur=icur1; icur <= icur2; icur++)  //*2*
785       {
786           Plot2d_Curve *plot2dCurve = curveList.at(icur);
787           side=sides.at(icur);
788           // Curve points
789           nbPoints = plot2dCurve->getData( &Xval, &Yval);  // dynamic allocation
790
791           for (int ip=0; ip < nbPoints; ip++)
792           {
793               if (ip == 0)  // first point
794               {
795                   XcurveMin = Xval[ip];  XcurveMax = Xval[ip];
796                   YcurveMin = Yval[ip];  YcurveMax = Yval[ip];
797               }
798               else
799               {
800                   if      (Xval[ip] < XcurveMin)  XcurveMin = Xval[ip];
801                   else if (Xval[ip] > XcurveMax)  XcurveMax = Xval[ip];
802                   if      (Yval[ip] < YcurveMin)  YcurveMin = Yval[ip];
803                   else if (Yval[ip] > YcurveMax)  YcurveMax = Yval[ip];
804               }
805           }
806           delete [] Xval;
807           delete [] Yval;
808
809           if (icur == icur1)  // first curve
810           {
811               XgroupMin = XcurveMin;  XgroupMax = XcurveMax;
812               YgroupMin = YcurveMin;  YgroupMax = YcurveMax;
813           }
814           else
815           {
816               if (XcurveMin < XgroupMin)  XgroupMin = XcurveMin;
817               if (XcurveMax > XgroupMax)  XgroupMax = XcurveMax;
818               if (YcurveMin < YgroupMin)  YgroupMin = YcurveMin;
819               if (YcurveMax > YgroupMax)  YgroupMax = YcurveMax;
820           }
821       } //*2*
822
823       if (XgroupMin < XallGroupMin)  XallGroupMin = XgroupMin;
824       if (XgroupMax > XallGroupMax)  XallGroupMax = XgroupMax;
825       if(side)
826         {
827           if (YgroupMin < YRightallGroupMin)  YRightallGroupMin = YgroupMin;
828           if (YgroupMax > YRightallGroupMax)  YRightallGroupMax = YgroupMax;
829         }
830       else
831         {
832           if (YgroupMin < YLeftallGroupMin)  YLeftallGroupMin = YgroupMin;
833           if (YgroupMax > YLeftallGroupMax)  YLeftallGroupMax = YgroupMax;
834         }
835       // First curve of the following group
836       icur1 = icur2 + 1;
837   } //*1*
838   // Set the XY range 's bounds for all groups of curves
839   if(YRightallGroupMin!=std::numeric_limits<double>::max())
840     {
841       double deltaY = YRightallGroupMax - YRightallGroupMin;
842       YRightallGroupMin-=0.05*deltaY; YRightallGroupMax+= 0.05*deltaY;
843       myPlot->setAxisScale( QwtPlot::yRight, YRightallGroupMin,YRightallGroupMax);
844     }
845   if(YLeftallGroupMin!=std::numeric_limits<double>::max())
846     {
847       double deltaY = YLeftallGroupMax - YLeftallGroupMin;
848       YLeftallGroupMin-=0.05*deltaY; YLeftallGroupMax+= 0.05*deltaY;
849       myPlot->setAxisScale( QwtPlot::yLeft, YLeftallGroupMin, YLeftallGroupMax);
850     }
851   // II)- Drawing curves, points markers and connection segments
852
853   icur1 = 0;
854   for (ig=0; ig < nbGroups; ig++)
855   {
856       // 1)- Graphical attributs of group's curves
857
858       // Graphical attributes of the first group's curve
859       //
860       Plot2d_Curve *plot2dCurve1 = curveList.at(icur1);
861       //
862       QColor color1 = plot2dCurve1->getColor();
863       Plot2d::LineType linetype1 = plot2dCurve1->getLine();
864       int lineWidth1 = plot2dCurve1->getLineWidth();
865       QwtSymbol::Style symbolStyle1 = plot2dCurve1->getMarkerStyle();
866       // We attribute to the current group's curve, the color, the line's kind
867       // and the marker's kind of the first group's curve
868
869       for (icur=icur1+1; icur<icur1+groupSize; icur++)
870         {
871           Plot2d_Curve *plot2dCurve = curveList.at(icur);
872           //
873           plot2dCurve->setColor(color1);
874           plot2dCurve->setLine(linetype1,lineWidth1);
875           plot2dCurve->setMarkerStyle(symbolStyle1);
876         }
877
878       // 2)- Display the group's curves
879
880       for (icur=icur1; icur<icur1+groupSize; icur++)
881       {
882           Plot2d_Curve *plot2dCurve = curveList.at(icur);
883
884           QString title = plot2dCurve->getVerTitle();
885           std::string std_title = title.toStdString();
886           // Create the graphic curve (QwtPlotCurve) et display it in the drawing zone
887           // (Qwtplot)
888           displayCurve(plot2dCurve);
889
890           // Get the graphic curve
891           QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>(getPlotObject(plot2dCurve));
892           vectCurve[ig].push_back(plotCurve);
893           // Modify the points' markers
894           QwtSymbol* symbol = new QwtSymbol(plotCurve->symbol()->style(), plotCurve->symbol()->brush(),
895                                             plotCurve->symbol()->pen(), plotCurve->symbol()->size()) ;
896           symbol->setStyle(symbolStyle1);
897           symbol->setPen(QPen(color1,lineWidth1));
898           //symbol.setBrush( QBrush( color1));
899           //QSize size = 0.5*(symbol.size());
900           //symbol.setSize(size);
901           //
902           plotCurve->setPen(QPen(color1,lineWidth1));
903           plotCurve->setSymbol(symbol);
904
905           if (icur > icur1)
906           {
907               //std::cout << "  courbe d'indice " << icur << " sans entree dans la legende" << std::endl;
908
909               // The curve must not have legend's entry
910               plotCurve->setItemAttribute( QwtPlotItem::Legend, false);
911           }
912           else
913           {
914               plotCurve->setItemAttribute( QwtPlotItem::Legend, true);
915           }
916       }
917
918       // 3)- Intermittent segments to connect all the group's curves
919
920       if (groupSize > 1)
921       {
922           double *Xval;
923           double *Yval;
924           int nbPoints;
925           double Xseg[2], Yseg[2];
926           Plot2d_Curve *plot2dCurve1 = curveList.at(icur1);
927           bool side = sides.at(icur1);
928           // Last point of the first curve
929           nbPoints = plot2dCurve1->getData( &Xval, &Yval);  // dynamic allocation
930           Xseg[0] = Xval[ nbPoints -1];
931           Yseg[0] = Yval[ nbPoints -1];
932           delete [] Xval;
933           delete [] Yval;
934
935           for (icur=icur1+1; icur<icur1+groupSize; icur++)
936           {
937               Plot2d_Curve *plot2dCurve = curveList.at(icur);
938
939               // First curve's point
940               nbPoints = plot2dCurve->getData( &Xval, &Yval);
941               Xseg[1] = Xval[0];
942               Yseg[1] = Yval[0];
943
944               vectCurve[ig].push_back(createSegment(Xseg,Yseg,2,Qt::DotLine,lineWidth1,color1,QwtSymbol::NoSymbol,side));
945
946               // Last curve's point
947               Xseg[0] = Xval[ nbPoints -1];
948               Yseg[0] = Yval[ nbPoints -1];
949               delete [] Xval;
950               delete [] Yval;
951           }
952       }
953       // First curve of the following group
954       icur1 += groupSize;
955   }
956
957   if (displayLegend)
958     {
959       // Consider the new legend's entries
960       if(!curveList.empty())
961         showLegend( true, true);  // show, update
962     }
963   return vectCurve;
964 }
965
966
967 /*!
968  * Create and display an y=f(x) curve of points
969  * Parameters :
970  *   toDraw : true => Display the created curve
971  *                    Draw the points'markers and create associated tooltips
972  */
973 Plot2d_Curve* Plot2d_ViewFrame::createPlot2dCurve( QString & title,
974                                                    QString & unit,
975                                                    QList<double> & xList,
976                                                    QList<double> & yList,
977                                                    QList<QString> & tooltipList,
978                                                    Plot2d::LineType lineKind,
979                                                    int lineWidth,
980                                                    QColor & lineColor,
981                                                    QwtSymbol::Style markerKind,
982                                                    Plot2d_QwtPlotPicker* picker,
983                                                    bool toDraw,
984                                                    bool displayLegend)
985 {
986   //std::cout << "Plot2d_ViewFrame::createPlot2dCurve()" << std::endl;
987
988   // Mathematical curve
989   Plot2d_Curve* plot2dCurve = new Plot2d_Curve();
990
991   // To deallocate in EraseAll()
992   myPlot2dCurveList.append( plot2dCurve);
993
994   int nbPoint = xList.size();
995   double xVal, yVal;
996   QString tooltip;
997
998   for (int ip=0; ip < nbPoint; ip++)
999   {
1000       xVal = xList.at(ip);
1001       yVal = yList.at(ip);
1002       tooltip = tooltipList.at(ip);
1003
1004       plot2dCurve->addPoint( xVal, yVal, tooltip);
1005   }
1006
1007   plot2dCurve->setVerTitle( title);
1008   plot2dCurve->setVerUnits( unit);
1009   if (lineColor.isValid())
1010   {
1011       plot2dCurve->setColor( lineColor);
1012   }
1013   plot2dCurve->setLine( lineKind, lineWidth);
1014   plot2dCurve->setMarkerStyle( markerKind);
1015   plot2dCurve->setMarkerSize(1);
1016
1017   // Graphical curve (QwtPlotCurve) in the drawing zone (QwtPlot) myPlot
1018   if (toDraw)
1019   {
1020       if (!displayLegend)
1021         {
1022           myPlot->insertLegend( (QwtAbstractLegend*)NULL);
1023         }
1024       displayCurve( plot2dCurve);
1025
1026       // Get the graphical curve
1027       QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>( getPlotObject( plot2dCurve));
1028
1029       QColor theColor;
1030
1031       if (lineColor.isValid())
1032       {
1033         //std::cout << "  valid color" << std::endl;
1034           theColor = lineColor;
1035       }
1036       else
1037       {
1038         //std::cout << "  valid color" << std::endl;
1039           QPen pen = plotCurve->pen();
1040           theColor = pen.color();
1041       }
1042
1043       // Modify points' markers
1044       QwtSymbol* symbol = new QwtSymbol( plotCurve->symbol()->style(), plotCurve->symbol()->brush(),
1045                                              plotCurve->symbol()->pen(), plotCurve->symbol()->size() ) ;
1046       symbol->setStyle( markerKind );
1047       //
1048       if (markerKind != QwtSymbol::NoSymbol)
1049       {
1050         symbol->setPen( QPen( theColor, lineWidth));
1051         symbol->setBrush( QBrush( theColor));
1052         QSize size = 2.0*(symbol->size()); //0.5
1053         symbol->setSize(size);
1054       }
1055
1056       plotCurve->setSymbol( symbol);
1057       plotCurve->setStyle( QwtPlotCurve::Lines);
1058       plotCurve->setPen( QPen( theColor, lineWidth));
1059
1060       // The curve must not have legend's entry
1061       plotCurve->setItemAttribute( QwtPlotItem::Legend, false);
1062   }
1063   return plot2dCurve;
1064 }
1065
1066
1067 /*!
1068  * Get curve's color
1069  */
1070 QColor Plot2d_ViewFrame::getPlot2dCurveColor( Plot2d_Curve* plot2dCurve)
1071 {
1072
1073   // Get graphical curve
1074   QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>( getPlotObject( plot2dCurve));
1075
1076   QPen pen = plotCurve->pen();
1077   QColor color = pen.color();
1078
1079   return color;
1080 }
1081
1082
1083 /*!
1084  * Create and display a segment with nbPoint=2 points
1085  */
1086 QwtPlotCurve *Plot2d_ViewFrame::createSegment( double *X, double *Y, int nbPoint,
1087                                                Qt::PenStyle lineKind,
1088                                                int lineWidth,
1089                                                QColor & lineColor,
1090                                                QwtSymbol::Style markerKind, bool side)
1091 {
1092   QwtPlotCurve* aPCurve = new QwtPlotCurve( QString::null );
1093
1094   aPCurve->setSamples( X, Y, nbPoint);
1095
1096   aPCurve->setPen( QPen( lineColor, lineWidth, lineKind));
1097   QwtSymbol* aSymbol;
1098   aSymbol->setStyle( markerKind );
1099   aPCurve->setSymbol( aSymbol );
1100
1101   // The segment must not have legend's entry
1102   aPCurve->setItemAttribute( QwtPlotItem::Legend, false);
1103
1104   aPCurve->attach(myPlot);
1105   aPCurve->setYAxis(side ? QwtPlot::yRight : QwtPlot::yLeft);
1106   // To deallocate in EraseAll()
1107   myIntermittentSegmentList.append(aPCurve);
1108   return aPCurve;
1109 }
1110
1111 /*!
1112   Adds curve into view
1113 */
1114 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
1115 {
1116   QwtPlotItem* anItem = displayObject( curve, update );
1117   // To deallocate in EraseAll()
1118   myQwtPlotCurveList.append( anItem);
1119 }
1120
1121 /*!
1122   Adds curves into view
1123 */
1124 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
1125 {
1126   objectList objects;
1127   foreach ( Plot2d_Curve* curve, curves )
1128     objects << curve;
1129   displayObjects( objects, update );
1130 }
1131
1132 /*!
1133   Erases curve
1134 */
1135 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
1136 {
1137   eraseObject( curve, update );
1138 }
1139
1140 /*!
1141   Erases curves
1142 */
1143 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
1144 {
1145   objectList objects;
1146   foreach ( Plot2d_Curve* curve, curves )
1147     objects << curve;
1148   eraseObjects( objects, update );
1149 }
1150
1151 /*!
1152   Updates curves attributes
1153 */
1154 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
1155 {
1156   updateObject( curve, update );
1157 }
1158
1159 void Plot2d_ViewFrame::processFiltering(bool update)
1160 {
1161   CurveDict aCurves = getCurves();
1162   AlgoPlot2dInputData aLData, aRData;
1163   CurveDict::iterator it;
1164   for ( it = aCurves.begin(); it != aCurves.end(); it++ ) {
1165     Plot2d_Object* objItem = it.value();
1166     if (objItem->getYAxis() == QwtPlot::yRight)
1167       aRData.append(objItem);
1168     else
1169       aLData.append(objItem);
1170   }
1171
1172 // Normalization by left Y axis
1173   if (!myNormLMin && !myNormLMax)
1174     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeNone);
1175   if(myNormLMin && myNormLMax)
1176     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMinMax);
1177   else if(myNormLMin)
1178     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMin);
1179   else if(myNormLMax)
1180     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMax);
1181
1182   myLNormAlgo->setInput(aLData);
1183   myLNormAlgo->execute();
1184
1185 // Normalization by right Y axis
1186   if (!myNormRMin && !myNormRMax)
1187     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeNone);
1188   if(myNormRMin && myNormRMax)
1189     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMinMax);
1190   else if(myNormRMin)
1191     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMin);
1192   else if(myNormRMax)
1193     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMax);
1194
1195   myRNormAlgo->setInput(aRData);
1196   myRNormAlgo->execute();
1197
1198   for ( it = aCurves.begin(); it != aCurves.end(); it++) {
1199     QwtPlotCurve* item = it.key();
1200     Plot2d_Object* objItem = it.value();
1201     updatePlotItem(objItem, item);
1202   }
1203   if(update)
1204   myPlot->replot();
1205 }
1206
1207 /*!
1208   Gets lsit of displayed curves
1209 */
1210 int Plot2d_ViewFrame::getCurves( curveList& curves ) const
1211 {
1212   curves.clear();
1213
1214   CurveDict aCurves = getCurves();
1215   CurveDict::iterator it;
1216   for ( it = aCurves.begin(); it != aCurves.end(); it++ )
1217     curves << it.value();
1218   return curves.count();
1219 }
1220
1221 CurveDict Plot2d_ViewFrame::getCurves() const
1222 {
1223   CurveDict curves;
1224   ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end();
1225   for ( ; it != aLast; it++ ) {
1226     QwtPlotItem* anItem = it.key();
1227     if ( anItem && anItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) {
1228       QwtPlotCurve* aPCurve = dynamic_cast<QwtPlotCurve*>( anItem );
1229       Plot2d_Curve* aCurve = dynamic_cast<Plot2d_Curve*>( it.value() );
1230       if ( aPCurve && aCurve )
1231         curves.insert( aPCurve, aCurve );
1232     }
1233   }
1234   return curves;
1235 }
1236
1237 /*!
1238   Adds object into view
1239 */
1240 QwtPlotItem* Plot2d_ViewFrame::displayObject( Plot2d_Object* object, bool update )
1241 {
1242   QwtPlotItem* anItem = 0;
1243   if ( !object )
1244     return anItem;
1245
1246   if ( object->getYAxis() == QwtPlot::yRight )
1247     mySecondY = true;
1248
1249   // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1250   // it crashes if switched to X/Y logarithmic mode, when one or more points have
1251   // non-positive X/Y coordinate
1252   if ( myXMode && object->getMinX() <= 0. )
1253     setHorScaleMode( 0, false );
1254   if ( myYMode && object->getMinY() <= 0. )
1255     setVerScaleMode( 0, false );
1256
1257   if ( object->isAutoAssign() )
1258     object->autoFill( myPlot );
1259
1260   if ( hasPlotObject( object ) ) {
1261     processFiltering(update);
1262     updateObject( object, update );
1263   }
1264   else {
1265     anItem = object->createPlotItem();
1266     anItem->attach( myPlot );
1267     myObjects.insert( anItem, object );
1268     //myPlot->setCurveYAxis(curveKey, curve->getYAxis());
1269
1270     if ( object->rtti() == QwtPlotItem::Rtti_PlotCurve )
1271     {
1272       Plot2d_Curve* aCurve = dynamic_cast<Plot2d_Curve*>( object );
1273       if ( aCurve )
1274       {
1275         if ( aCurve->getMarkerSize() == 0 )
1276           aCurve->setMarkerSize( myMarkerSize );
1277
1278         processFiltering(update);
1279         updatePlotItem( aCurve, anItem );
1280         setCurveType( getPlotCurve( aCurve ), myCurveType );
1281       }
1282     }
1283   }
1284   updateTitles( false );
1285   myPlot->updateYAxisIdentifiers();
1286   if ( update ) {
1287     myPlot->replot();
1288     if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(false);
1289   }
1290   return anItem;
1291 }
1292
1293 /*!
1294   Adds objects into view
1295 */
1296 void Plot2d_ViewFrame::displayObjects( const objectList& objects, bool update )
1297 {
1298   //myPlot->setUpdatesEnabled( false ); // call this function deprecate update of legend
1299   foreach ( Plot2d_Object* object, objects )
1300     displayObject( object, false );
1301   fitAll();
1302   //myPlot->setUpdatesEnabled( true );
1303   // update legend
1304   if ( update )
1305     myPlot->replot();
1306 }
1307
1308 /*!
1309   Erases object
1310 */
1311 void Plot2d_ViewFrame::eraseObject( Plot2d_Object* object, bool update )
1312 {
1313   if ( !object )
1314     return;
1315
1316   if ( hasPlotObject( object ) ) {
1317     QwtPlotItem* anObject = getPlotObject( object );
1318     eraseBasicObject(anObject,update);
1319   }
1320   if (update) {
1321     if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1322   }
1323 }
1324
1325 void Plot2d_ViewFrame::eraseBasicObject( QwtPlotItem *object, bool update )
1326 {
1327   if(!object)
1328     return;
1329   object->hide();
1330   object->detach();
1331   myObjects.remove(object);
1332   updateTitles(update);
1333   myPlot->updateYAxisIdentifiers();
1334   if ( update )
1335     myPlot->replot();
1336 }
1337
1338 /*!
1339   Erases objects
1340 */
1341 void Plot2d_ViewFrame::eraseObjects( const objectList& objects, bool update )
1342 {
1343   foreach ( Plot2d_Object* object, objects )
1344     eraseObject( object, false );
1345
1346   //  fitAll();
1347   if ( update )
1348     myPlot->replot();
1349   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1350 }
1351
1352 void Plot2d_ViewFrame::eraseBasicObjects( const QList<QwtPlotItem*> &objects, bool update)
1353 {
1354   foreach ( QwtPlotItem* object, objects )
1355     eraseBasicObject( object, false );
1356   //  fitAll();
1357   if ( update )
1358     myPlot->replot();
1359   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1360 }
1361
1362 /*!
1363   Updates objects attributes
1364 */
1365 void Plot2d_ViewFrame::updateObject( Plot2d_Object* object, bool update )
1366 {
1367   if ( !object )
1368     return;
1369   if ( hasPlotObject( object ) ) {
1370     QwtPlotItem* anItem = getPlotObject( object );
1371     if ( !anItem )
1372       return;
1373     updatePlotItem(object, anItem );
1374     anItem->setVisible( true );
1375     if ( update ) {
1376       myPlot->replot();
1377       if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(false);
1378     }
1379   }
1380 }
1381
1382 /*!
1383   Gets lsit of displayed curves
1384 */
1385 int Plot2d_ViewFrame::getObjects( objectList& objects ) const
1386 {
1387   objects.clear();
1388
1389   ObjectDict::const_iterator it;
1390   for ( it = myObjects.begin(); it != myObjects.end(); it++ )
1391     objects << it.value();
1392   return objects.count();
1393 }
1394
1395 /*!
1396   Returns true if the curve is visible
1397 */
1398 bool Plot2d_ViewFrame::isVisible( Plot2d_Object* object ) const
1399 {
1400   return object && hasPlotObject( object ) && getPlotObject( object )->isVisible();
1401 }
1402
1403 /*!
1404   update legend
1405 */
1406 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
1407 {
1408   if ( !prs || prs->IsNull() )
1409     return;
1410
1411   ObjectDict::iterator it = myObjects.begin();
1412   Plot2d_Object* anObj;
1413   for (; it != myObjects.end(); ++it ) {
1414     anObj = *it;
1415     if ( hasPlotObject( anObj ) )
1416       getPlotObject( anObj )->setTitle( !anObj->getName().isEmpty() ?
1417                             anObj->getName() : anObj->getVerTitle() );
1418   }
1419 }
1420
1421 /*!
1422   update legend
1423 */
1424 void Plot2d_ViewFrame::updateLegend() {
1425   const QwtPlotItemList& items = myPlot->itemList();
1426   QwtPlotItemIterator it;
1427   for ( it = items.begin(); it != items.end(); it++ ) {
1428     QwtPlotItem* item = *it;
1429     if ( item )
1430       item->updateLegend( item, item->legendData() );
1431   }
1432 }
1433
1434
1435 /*!
1436   Fits the view to see all data
1437 */
1438 void Plot2d_ViewFrame::fitAll()
1439 {
1440   // no need to set auto scaling, it will be disabled by setAxisScale() method call
1441   // myPlot->setAxisAutoScale( QwtPlot::yLeft );
1442   // myPlot->setAxisAutoScale( QwtPlot::xBottom );
1443   // myPlot->replot();
1444
1445   double xmin, xmax, y1min, y1max, y2min, y2max;
1446   getFitRangeByCurves(xmin, xmax, y1min, y1max, y2min, y2max);
1447   getFitRangeByMarkers(xmin, xmax, y1min, y1max, y2min, y2max);
1448
1449   myPlot->setAxisScale( QwtPlot::xBottom, xmin, xmax );
1450   myPlot->setAxisScale( QwtPlot::yLeft, y1min, y1max );
1451
1452   if (mySecondY) {
1453     myPlot->setAxisAutoScale( QwtPlot::yRight );
1454     myPlot->replot();
1455     myPlot->setAxisScale( QwtPlot::yRight, y2min, y2max );
1456   }
1457   myPlot->replot();
1458   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(false);
1459 }
1460
1461 /*!
1462   Fits the view to rectangle area (pixels)
1463 */
1464 void Plot2d_ViewFrame::fitArea( const QRect& area )
1465 {
1466   QRect rect = area.normalized();
1467   if ( rect.width() < MIN_RECT_SIZE ) {
1468     rect.setWidth( MIN_RECT_SIZE );
1469     rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
1470   }
1471   if ( rect.height() < MIN_RECT_SIZE ) {
1472     rect.setHeight( MIN_RECT_SIZE );
1473     rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
1474   }
1475   myPlot->setAxisScale( QwtPlot::yLeft,
1476             myPlot->invTransform( QwtPlot::yLeft, rect.top() ),
1477             myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
1478   if (mySecondY)
1479     myPlot->setAxisScale( QwtPlot::yRight,
1480             myPlot->invTransform( QwtPlot::yRight, rect.top() ),
1481             myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
1482   myPlot->setAxisScale( QwtPlot::xBottom,
1483             myPlot->invTransform( QwtPlot::xBottom, rect.left() ),
1484             myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
1485   myPlot->replot();
1486   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1487 }
1488
1489 /*!
1490   "Fit Data" command for TUI interface
1491 */
1492 void Plot2d_ViewFrame::fitData(const int mode,
1493                                const double xMin, const double xMax,
1494                                const double yMin, const double yMax,
1495                                double y2Min, double y2Max)
1496 {
1497   if ( mode == 0 || mode == 2 ) {
1498     myPlot->setAxisScale( QwtPlot::yLeft, yMin, yMax );
1499     if (mySecondY)
1500       myPlot->setAxisScale( QwtPlot::yRight, y2Min, y2Max );
1501   }
1502   if ( mode == 0 || mode == 1 )
1503     myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax );
1504   myPlot->replot();
1505   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1506 }
1507
1508 /*!
1509   Gets current fit ranges for view frame
1510 */
1511 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
1512                                     double& yMin, double& yMax,
1513                                     double& y2Min, double& y2Max)
1514 {
1515   int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).transform( myPlot->canvasMap( QwtPlot::xBottom ).s1() );
1516   int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).transform( myPlot->canvasMap( QwtPlot::xBottom ).s2() );
1517   int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).transform( myPlot->canvasMap( QwtPlot::yLeft ).s1() );
1518   int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).transform( myPlot->canvasMap( QwtPlot::yLeft ).s2() );
1519   xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
1520   xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
1521   yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
1522   yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
1523   y2Min = 0;
1524   y2Max = 0;
1525   if (mySecondY) {
1526     int iyMin = myPlot->canvasMap( QwtPlot::yRight ).transform( myPlot->canvasMap( QwtPlot::yRight ).s1() );
1527     int iyMax = myPlot->canvasMap( QwtPlot::yRight ).transform( myPlot->canvasMap( QwtPlot::yRight ).s2() );
1528     y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
1529     y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
1530   }
1531 }
1532
1533 /*!
1534   Gets current fit ranges by Curves
1535 */
1536 void Plot2d_ViewFrame::getFitRangeByCurves(double& xMin,  double& xMax,
1537                                            double& yMin,  double& yMax,
1538                                            double& y2Min, double& y2Max)
1539 {
1540   bool emptyV1 = true, emptyV2 = true;
1541   if ( !myObjects.isEmpty() ) {
1542     ObjectDict::const_iterator it = myObjects.begin();
1543     for ( ; it != myObjects.end(); it++ ) {
1544       bool isV2 = it.value()->getYAxis() == QwtPlot::yRight;
1545       if ( !it.value()->isEmpty() ) {
1546         if ( emptyV1 && emptyV2 ) {
1547           xMin = 1e150;
1548           xMax = -1e150;
1549         }
1550         if ( emptyV1 ) {
1551           yMin = 1e150;
1552           yMax = -1e150;
1553         }
1554         if ( emptyV2 ) {
1555           y2Min = 1e150;
1556           y2Max = -1e150;
1557         }
1558         isV2 ? emptyV2 = false : emptyV1 = false;
1559         xMin = qMin( xMin, it.value()->getMinX() );
1560         xMax = qMax( xMax, it.value()->getMaxX() );
1561         if ( isV2 ) {
1562           y2Min = qMin( y2Min, it.value()->getMinY() );
1563           y2Max = qMax( y2Max, it.value()->getMaxY() );
1564         }
1565         else {
1566           yMin = qMin( yMin, it.value()->getMinY() );
1567           yMax = qMax( yMax, it.value()->getMaxY() );
1568         }
1569       }
1570     }
1571     if ( xMin == xMax ) {
1572       xMin = xMin == 0. ? -1. : xMin - xMin/10.;
1573       xMax = xMax == 0. ?  1. : xMax + xMax/10.;
1574     }
1575     if ( yMin == yMax ) {
1576       yMin = yMin == 0. ? -1. : yMin - yMin/10.;
1577       yMax = yMax == 0. ?  1  : yMax + yMax/10.;
1578     }
1579     if ( y2Min == y2Max ) {
1580       y2Min = y2Min == 0. ? -1. : y2Min - y2Min/10.;
1581       y2Max = y2Max == 0. ?  1  : y2Max + y2Max/10.;
1582     }
1583   }
1584   // default values
1585   if ( emptyV1 && emptyV2 ) {
1586     xMin = isModeHorLinear() ? 0.    : 1.;
1587     xMax = isModeHorLinear() ? 1000. : 1e5;
1588   }
1589   if ( emptyV1  ) {
1590     yMin = isModeVerLinear() ? 0.    : 1.;
1591     yMax = isModeVerLinear() ? 1000. : 1e5;
1592   }
1593   if ( emptyV2  ) {
1594     y2Min = isModeVerLinear() ? 0.    : 1.;
1595     y2Max = isModeVerLinear() ? 1000. : 1e5;
1596   }
1597 }
1598
1599 /*!
1600   Gets current fit ranges by Markers
1601   All parameters are inout.
1602 */
1603 void Plot2d_ViewFrame::getFitRangeByMarkers(double& xMin,  double& xMax,
1604                                             double& yMin,  double& yMax,
1605                                             double& y2Min, double& y2Max)
1606 {
1607   Plot2d_QwtPlotPicker *picker=myPlot->getPicker();
1608   if(!picker)
1609     return;
1610   if(picker->pMarkers.empty())
1611     return;
1612   foreach(QwtPlotMarker *mrker,picker->pMarkers)
1613     {
1614       bool isV2 = mrker->yAxis() == QwtPlot::yRight;
1615       xMin = qMin( xMin, mrker->xValue() );
1616       xMax = qMax( xMax, mrker->xValue() );
1617       if ( isV2 ) {
1618         y2Min = qMin( y2Min, mrker->yValue() );
1619         y2Max = qMax( y2Max, mrker->yValue() );
1620       }
1621       else {
1622         yMin = qMin( yMin, mrker->yValue() );
1623         yMax = qMax( yMax, mrker->yValue() );
1624       }
1625       if ( xMin == xMax ) {
1626         xMin = xMin == 0. ? -1. : xMin - xMin/10.;
1627         xMax = xMax == 0. ?  1. : xMax + xMax/10.;
1628       }
1629       if ( yMin == yMax ) {
1630         yMin = yMin == 0. ? -1. : yMin - yMin/10.;
1631         yMax = yMax == 0. ?  1  : yMax + yMax/10.;
1632       }
1633       if ( y2Min == y2Max ) {
1634         y2Min = y2Min == 0. ? -1. : y2Min - y2Min/10.;
1635         y2Max = y2Max == 0. ?  1  : y2Max + y2Max/10.;
1636       }
1637     }
1638 }
1639
1640 /*!
1641   Tests if it is necessary to start operation on mouse action
1642 */
1643 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
1644 {
1645   int btn = me.button() | me.modifiers();
1646   const int zoomBtn = Qt::ControlModifier | Qt::LeftButton;
1647   const int panBtn  = Qt::ControlModifier | Qt::MidButton;
1648   const int fitBtn  = Qt::ControlModifier | Qt::RightButton;
1649
1650   int op = NoOpId;
1651   if ( btn == zoomBtn ) {
1652     QPixmap zoomPixmap (imageZoomCursor);
1653     QCursor zoomCursor (zoomPixmap);
1654     myPlot->canvas()->setCursor( zoomCursor );
1655     op = ZoomId;
1656   }
1657   else if ( btn == panBtn ) {
1658     myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
1659     op = PanId;
1660   }
1661   else if ( btn == fitBtn ) {
1662     myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1663     op = FitAreaId;
1664   }
1665   return op;
1666 }
1667
1668 /*!
1669   "Settings" toolbar action slot
1670 */
1671 void Plot2d_ViewFrame::onSettings()
1672 {
1673 #ifdef TEST_AUTOASSIGN
1674   typedef QMap<int,int> IList;
1675   typedef QMap<QString,int> SList;
1676   IList mars, lins;
1677   SList cols;
1678   cols[ "red-min" ]   = 1000;
1679   cols[ "red-max" ]   = -1;
1680   cols[ "green-min" ] = 1000;
1681   cols[ "green-max" ] = -1;
1682   cols[ "blue-min" ]  = 1000;
1683   cols[ "blue-max" ]  = -1;
1684   for ( unsigned i = 0; i < 10000; i++ ) {
1685     QwtSymbol::Style typeMarker;
1686     QColor           color;
1687     Qt::PenStyle     typeLine;
1688     myPlot->getNextMarker( typeMarker, color, typeLine );
1689     if ( mars.contains(typeMarker) )
1690       mars[ typeMarker ] = mars[ typeMarker ]+1;
1691     else
1692       mars[ typeMarker ] = 0;
1693     if ( lins.contains(typeLine) )
1694       lins[ typeLine ] = lins[ typeLine ]+1;
1695     else
1696       lins[ typeLine ] = 0;
1697     if ( cols[ "red-max" ] < color.red() )
1698       cols[ "red-max" ] = color.red();
1699     if ( cols[ "red-min" ] > color.red() )
1700       cols[ "red-min" ] = color.red();
1701     if ( cols[ "green-max" ] < color.green() )
1702       cols[ "green-max" ] = color.green();
1703     if ( cols[ "green-min" ] > color.green() )
1704       cols[ "green-min" ] = color.green();
1705     if ( cols[ "blue-max" ] < color.blue() )
1706       cols[ "blue-max" ] = color.blue();
1707     if ( cols[ "blue-min" ] > color.blue() )
1708       cols[ "blue-min" ] = color.blue();
1709   }
1710 #endif
1711
1712   Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
1713   dlg->setMainTitle( myTitleEnabled, myTitle );
1714   dlg->setXTitle( myXTitleEnabled, myXTitle );
1715   dlg->setYTitle( myYTitleEnabled, myYTitle );
1716   if (mySecondY)
1717     dlg->setY2Title( myY2TitleEnabled, myY2Title );
1718   dlg->setCurveType( myCurveType );
1719   dlg->setLegend( myShowLegend, myLegendPos, myLegendSymbolType, myLegendFont,
1720                   myLegendColor, mySelectedLegendFontColor );
1721   dlg->setMarkerSize( myMarkerSize );
1722   dlg->setBackgroundColor( myBackground );
1723   dlg->setSelectionColor( mySelectionColor );
1724   dlg->setScaleMode(myXMode, myYMode);
1725   dlg->setLMinNormMode(myNormLMin);
1726   dlg->setLMaxNormMode(myNormLMax);
1727   dlg->setRMinNormMode(myNormRMin);
1728   dlg->setRMaxNormMode(myNormRMax);
1729
1730   QVariant v = myPlot->property(PLOT2D_DEVIATION_LW);
1731   int lw = v.isValid() ? v.toInt() : 1;
1732
1733   v = myPlot->property(PLOT2D_DEVIATION_TS);
1734   int ts = v.isValid() ? v.toInt() : 2;
1735
1736   v = myPlot->property(PLOT2D_DEVIATION_COLOR);
1737   QColor cl =  v.isValid() ? v.value<QColor>() : QColor(255,0,0);
1738
1739   dlg->setDeviationMarkerLw(lw);
1740   dlg->setDeviationMarkerTs(ts);
1741   dlg->setDeviationMarkerCl(cl);
1742
1743   //
1744   dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
1745          myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
1746          myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
1747   dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
1748          myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
1749          myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
1750   if ( dlg->exec() == QDialog::Accepted ) {
1751     // horizontal axis title
1752     setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
1753     // vertical left axis title
1754     setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
1755     if (mySecondY) // vertical right axis title
1756       setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
1757
1758     // main title
1759     if( dlg->isMainTitleEnabled() && myTitle != dlg->getMainTitle() )
1760       myIsDefTitle = false;
1761     setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
1762     // curve type
1763     if ( myCurveType != dlg->getCurveType() ) {
1764       setCurveType( dlg->getCurveType(), false );
1765     }
1766     // legend
1767     if ( myShowLegend != dlg->isLegendEnabled() ) {
1768       showLegend( dlg->isLegendEnabled(), false );
1769     }
1770     if ( myLegendPos != dlg->getLegendPos() ) {
1771       setLegendPos( dlg->getLegendPos() );
1772     }
1773     if ( myLegendSymbolType != dlg->getLegendSymbolType() ) {
1774       setLegendSymbolType( dlg->getLegendSymbolType() );
1775     }
1776         if ( myLegendFont != dlg->getLegendFont() ) {
1777       setLegendFont( dlg->getLegendFont() );
1778     }
1779         if ( myLegendColor != dlg->getLegendColor() ) {
1780       setLegendFontColor( dlg->getLegendColor() );
1781     }
1782     if ( mySelectedLegendFontColor != dlg->getSelectedLegendColor() ) {
1783       setSelectedLegendFontColor( dlg->getSelectedLegendColor() );
1784     }
1785
1786     // marker size
1787     if ( myMarkerSize != dlg->getMarkerSize() ) {
1788       setMarkerSize( dlg->getMarkerSize(), false );
1789     }
1790     // background color
1791     if ( myBackground != dlg->getBackgroundColor() ) {
1792       setBackgroundColor( dlg->getBackgroundColor() );
1793     }
1794     // selection color
1795     if ( mySelectionColor != dlg->getSelectionColor() ) {
1796       setSelectionColor( dlg->getSelectionColor() );
1797     }
1798     // grid
1799     bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
1800          aY2GridMajorEnabled, aY2GridMinorEnabled;
1801     int  aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
1802          aY2GridMaxMajor, aY2GridMaxMinor;
1803     dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
1804                        aY2GridMajorEnabled, aY2GridMaxMajor);
1805     dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
1806                        aY2GridMinorEnabled, aY2GridMaxMinor);
1807     setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1808     setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
1809               aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
1810     if ( myXMode != dlg->getXScaleMode() ) {
1811       setHorScaleMode( dlg->getXScaleMode() );
1812     }
1813     if ( myYMode != dlg->getYScaleMode() ) {
1814       setVerScaleMode( dlg->getYScaleMode() );
1815     }
1816     if ( myNormLMin != dlg->getLMinNormMode() ) {
1817       setNormLMinMode( dlg->getLMinNormMode() );
1818     }
1819     if ( myNormLMax != dlg->getLMaxNormMode() ) {
1820       setNormLMaxMode( dlg->getLMaxNormMode() );
1821     }
1822     if ( myNormRMin != dlg->getRMinNormMode() ) {
1823       setNormRMinMode( dlg->getRMinNormMode() );
1824     }
1825     if ( myNormRMax != dlg->getRMaxNormMode() ) {
1826       setNormRMaxMode( dlg->getRMaxNormMode() );
1827     }
1828
1829     myPlot->setProperty(PLOT2D_DEVIATION_COLOR,
1830                         dlg->getDeviationMarkerCl());
1831     myPlot->setProperty(PLOT2D_DEVIATION_LW,
1832                         dlg->getDeviationMarkerLw());
1833     myPlot->setProperty(PLOT2D_DEVIATION_TS,
1834                          dlg->getDeviationMarkerTs());
1835
1836
1837     // update view
1838     myPlot->replot();
1839     // update preferences
1840     if ( dlg->isSetAsDefault() )
1841       writePreferences();
1842   }
1843   delete dlg;
1844 }
1845
1846 #ifndef NO_ANALYTICAL_CURVES
1847 /*!
1848   "Analytical Curves" toolbar action slot
1849 */
1850 void Plot2d_ViewFrame::onAnalyticalCurve()
1851 {
1852 #ifndef DISABLE_PYCONSOLE
1853   Plot2d_AnalyticalCurveDlg dlg( this, this );
1854   dlg.exec();
1855   updateAnalyticalCurves();
1856 #endif
1857 }
1858
1859 void Plot2d_ViewFrame::addAnalyticalCurve( Plot2d_AnalyticalCurve* theCurve)
1860 {
1861 #ifndef DISABLE_PYCONSOLE
1862         myAnalyticalCurves.append(theCurve);
1863 #endif
1864 }
1865
1866 void Plot2d_ViewFrame::removeAnalyticalCurve( Plot2d_AnalyticalCurve* theCurve)
1867 {
1868 #ifndef DISABLE_PYCONSOLE
1869         theCurve->setAction(Plot2d_AnalyticalCurve::ActRemoveFromView);
1870 #endif
1871 }
1872
1873 /*
1874   Update Analytical curve
1875 */
1876 void Plot2d_ViewFrame::updateAnalyticalCurve(Plot2d_AnalyticalCurve* c, bool updateView)
1877 {
1878 #ifndef DISABLE_PYCONSOLE
1879   if(!c) return;
1880   QwtScaleDiv div = myPlot->axisScaleDiv(QwtPlot::xBottom);
1881   c->setRangeBegin(div.lowerBound());
1882   c->setRangeEnd(div.upperBound());
1883   c->calculate();
1884   c->setMarkerSize(myMarkerSize);
1885   QwtPlotItem* item = c->plotItem();
1886
1887   switch( c->getAction() ) {
1888   case Plot2d_AnalyticalCurve::ActAddInView:
1889     if( c->isActive() ) {
1890       c->updatePlotItem();
1891       item->attach( myPlot );
1892       item->itemChanged();
1893       item->show();
1894     }
1895     c->setAction(Plot2d_AnalyticalCurve::ActNothing);
1896     break;
1897
1898   case Plot2d_AnalyticalCurve::ActUpdateInView:
1899     if(c->isActive()) {
1900       c->updatePlotItem();
1901       item->show();
1902     } else {
1903       item->hide();
1904       item->detach();
1905     }
1906
1907     c->setAction(Plot2d_AnalyticalCurve::ActNothing);
1908     break;
1909   case Plot2d_AnalyticalCurve::ActRemoveFromView:
1910     item->hide();
1911     item->detach();
1912     myAnalyticalCurves.removeAll(c);
1913     delete c;
1914     break;
1915   }
1916
1917   if(updateView)
1918     myPlot->replot();
1919 #endif
1920 }
1921
1922 /*
1923   Update Analytical curves
1924 */
1925 void Plot2d_ViewFrame::updateAnalyticalCurves()
1926 {
1927 #ifndef DISABLE_PYCONSOLE
1928   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
1929   for( ; it != myAnalyticalCurves.end(); it++) {
1930     updateAnalyticalCurve(*it);
1931   }
1932   myPlot->replot();
1933 #endif
1934 }
1935
1936 /*!
1937   Return list of the alalytical curves.
1938 */
1939 AnalyticalCurveList Plot2d_ViewFrame::getAnalyticalCurves() const
1940 {
1941   return myAnalyticalCurves;
1942 }
1943
1944 /*!
1945   Get analytical curve by plot item.
1946 */
1947 Plot2d_AnalyticalCurve* Plot2d_ViewFrame::getAnalyticalCurve(QwtPlotItem * theItem) {
1948 #ifndef DISABLE_PYCONSOLE
1949   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
1950   for( ; it != myAnalyticalCurves.end(); it++) {
1951     if((*it)->plotItem() == theItem);
1952                 return (*it);
1953   }
1954   return 0;
1955 #endif
1956 }
1957 #endif
1958
1959 /*!
1960   "Fit Data" command slot
1961 */
1962 void Plot2d_ViewFrame::onFitData()
1963 {
1964   Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
1965   double xMin,xMax,yMin,yMax,y2Min,y2Max;
1966   getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
1967
1968   dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1969   if ( dlg->exec() == QDialog::Accepted ) {
1970     int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1971     fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
1972   }
1973   delete dlg;
1974 #ifndef NO_ANALYTICAL_CURVES
1975   updateAnalyticalCurves();
1976 #endif
1977 }
1978
1979 /*!
1980   Change background color
1981 */
1982 void Plot2d_ViewFrame::onChangeBackground()
1983 {
1984   QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
1985   if ( selColor.isValid() ) {
1986     setBackgroundColor( selColor );
1987   }
1988 }
1989
1990 /*!
1991   Sets curve type
1992 */
1993 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1994 {
1995   myCurveType = curveType;
1996   CurveDict aCurves = getCurves();
1997   CurveDict::iterator it = aCurves.begin();
1998   for ( ; it != aCurves.end(); it++ ) {
1999     QwtPlotCurve* crv = it.key();
2000     if ( crv )
2001       setCurveType( crv, myCurveType );
2002   }
2003   if ( update )
2004     myPlot->replot();
2005   emit vpCurveChanged();
2006 }
2007
2008 /*!
2009   Gets curve type
2010 */
2011 int Plot2d_ViewFrame::getCurveType() const
2012 {
2013   return myCurveType;
2014 }
2015
2016 /*!
2017   Sets curve title
2018   \param curveKey - curve id
2019   \param title - new title
2020 */
2021 void Plot2d_ViewFrame::setCurveTitle( Plot2d_Curve* curve, const QString& title )
2022 {
2023   setObjectTitle( curve, title );
2024 }
2025
2026 /*!
2027   Sets object title
2028   \param object - object id
2029   \param title - new title
2030 */
2031 void Plot2d_ViewFrame::setObjectTitle( Plot2d_Object* object, const QString& title )
2032 {
2033   if ( object && hasPlotObject( object ) )
2034     getPlotObject( object )->setTitle( title );
2035 }
2036
2037 /*!
2038   Shows/hides legend
2039 */
2040 void Plot2d_ViewFrame::showLegend( bool show, bool update )
2041 {
2042   myShowLegend = show;
2043   if ( myShowLegend ) {
2044     QwtAbstractLegend* absLegend = myPlot->legend();
2045     QwtLegend* legend = 0;
2046     if ( !absLegend ) {
2047       legend = new Plot2d_QwtLegend( myPlot );
2048       legend->setDefaultItemMode(QwtLegendData::Clickable);
2049       connect( legend, SIGNAL( clicked (const QVariant&, int) ),
2050                this, SIGNAL( clicked (const QVariant&, int) ) );
2051       legend->setFrameStyle( QFrame::Box | QFrame::Sunken );
2052     }
2053     else {
2054       legend = dynamic_cast<QwtLegend*>(absLegend);
2055     }
2056     if(legend) {
2057       myPlot->insertLegend( legend );
2058       setLegendPos( myLegendPos );
2059       setLegendFont( myLegendFont );
2060       setLegendFontColor( myLegendColor );
2061     }
2062   }
2063   else
2064     myPlot->insertLegend( 0 );
2065
2066   if( show && update )
2067     updateLegend();
2068
2069   if ( update )
2070     myPlot->replot();
2071 }
2072
2073 /*!
2074   Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
2075 */
2076 void Plot2d_ViewFrame::setLegendPos( int pos )
2077 {
2078   myLegendPos = pos;
2079   QwtAbstractLegend* legend = myPlot->legend();
2080   if ( legend ) {
2081     switch( pos ) {
2082     case 0:
2083       myPlot->insertLegend( legend, QwtPlot::LeftLegend );
2084       break;
2085     case 1:
2086       myPlot->insertLegend( legend, QwtPlot::RightLegend );
2087       break;
2088     case 2:
2089       myPlot->insertLegend( legend, QwtPlot::TopLegend );
2090       break;
2091     case 3:
2092       myPlot->insertLegend( legend, QwtPlot::BottomLegend );
2093       break;
2094     }
2095   }
2096 }
2097
2098 /*!
2099   Gets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
2100 */
2101 int Plot2d_ViewFrame::getLegendPos() const
2102 {
2103   return myLegendPos;
2104 }
2105
2106 /*!
2107   Sets legend symbol type : 0 - marker on line, 1 - marker above line
2108 */
2109 void Plot2d_ViewFrame::setLegendSymbolType( int type )
2110 {
2111   myLegendSymbolType = type;
2112   myPlot->setLegendSymbolType( type );
2113   updateLegend();
2114 }
2115
2116 /*!
2117   Gets legend symbol type : 0 - marker on line, 1 - marker above line
2118 */
2119 int Plot2d_ViewFrame::getLegendSymbolType() const
2120 {
2121   return myLegendSymbolType;
2122 }
2123
2124 /*!
2125   Sets legend font
2126 */
2127 void Plot2d_ViewFrame::setLegendFont( const QFont& fnt )
2128 {
2129   myLegendFont = fnt;
2130   QwtAbstractLegend* legend = myPlot->legend();
2131   if ( legend ) {
2132     legend->setFont(fnt);
2133   }
2134 }
2135
2136 /*!
2137   Gets legend font
2138 */
2139 QFont Plot2d_ViewFrame::getLegendFont() const
2140 {
2141   return myLegendFont;
2142 }
2143
2144 /*!
2145   Sets legend font color
2146 */
2147 void Plot2d_ViewFrame::setLegendFontColor( const QColor& col )
2148 {
2149   myLegendColor = col;
2150   QwtAbstractLegend* legend = myPlot->legend();
2151   if ( legend ) {
2152     QPalette pal = legend->palette();
2153     pal.setColor( QPalette::Text, col );
2154     legend->setPalette( pal );
2155   }
2156 }
2157
2158 /*!
2159   Gets legend font color
2160 */
2161 QColor Plot2d_ViewFrame::getLegendFontColor() const
2162 {
2163   return myLegendColor;
2164 }
2165
2166 /*!
2167   Sets selected legend font color
2168 */
2169 void Plot2d_ViewFrame::setSelectedLegendFontColor( const QColor& col )
2170 {
2171   mySelectedLegendFontColor = col;
2172   Plot2d_Object::setHighlightedLegendTextColor( col );
2173 }
2174
2175 /*!
2176   Gets selected legend font color
2177 */
2178 QColor Plot2d_ViewFrame::getSelectedLegendFontColor() const
2179 {
2180   return mySelectedLegendFontColor;
2181 }
2182
2183 /*!
2184   Sets new marker size
2185 */
2186 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
2187 {
2188   if ( myMarkerSize != size )
2189   {
2190     myMarkerSize = size;
2191     CurveDict aCurves = getCurves();
2192     CurveDict::iterator it = aCurves.begin();
2193     for ( ; it != aCurves.end(); it++ ) {
2194       QwtPlotCurve* crv = it.key();
2195       if ( crv )
2196       {
2197         QwtSymbol* aSymbol = new QwtSymbol( crv->symbol()->style(), crv->symbol()->brush(),
2198                                                     crv->symbol()->pen(), QSize( myMarkerSize, myMarkerSize ) );
2199         crv->setSymbol( aSymbol );
2200         if( it.value() )
2201               it.value()->setMarkerSize( myMarkerSize );
2202       }
2203     }
2204     if ( update )
2205       myPlot->replot();
2206   }
2207 }
2208
2209 /*!
2210   Gets new marker size
2211 */
2212 int Plot2d_ViewFrame::getMarkerSize() const
2213 {
2214   return myMarkerSize;
2215 }
2216
2217 /*!
2218   Sets background color
2219 */
2220 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
2221 {
2222   myBackground = color;
2223   myPlot->canvas()->setPalette( myBackground );
2224   myPlot->setPalette( myBackground );
2225   if ( myPlot->getLegend() ) {
2226     QPalette aPal = myPlot->getLegend()->palette();
2227     for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
2228       aPal.setColor( QPalette::Base, myBackground );
2229       aPal.setColor( QPalette::Background, myBackground );
2230     }
2231     myPlot->getLegend()->setPalette( aPal );
2232     updateLegend();
2233   }
2234   Repaint();
2235 }
2236
2237 /*!
2238   Gets background color
2239 */
2240 QColor Plot2d_ViewFrame::backgroundColor() const
2241 {
2242   return myBackground;
2243 }
2244
2245 /*!
2246   Sets selection color
2247 */
2248 void Plot2d_ViewFrame::setSelectionColor( const QColor& color )
2249 {
2250   mySelectionColor = color;
2251   Plot2d_Object::setSelectionColor( color );
2252 }
2253
2254 /*!
2255   Gets selection color
2256 */
2257 QColor Plot2d_ViewFrame::selectionColor() const
2258 {
2259   return mySelectionColor;
2260 }
2261
2262 /*!
2263   Sets hor.axis grid parameters
2264 */
2265 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
2266          bool xMinorEnabled, const int xMinorMax,
2267          bool update )
2268 {
2269   myXGridMajorEnabled = xMajorEnabled;
2270   myXGridMinorEnabled = xMinorEnabled;
2271   myXGridMaxMajor = xMajorMax;
2272   myXGridMaxMinor = xMinorMax;
2273
2274   myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
2275   myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
2276
2277   QwtPlotGrid* grid = myPlot->grid();
2278   if ( !myPlot->axisScaleDiv( QwtPlot::xBottom ).isEmpty() )
2279     grid->setXDiv( myPlot->axisScaleDiv( QwtPlot::xBottom ) );
2280   grid->enableX( myXGridMajorEnabled );
2281   grid->enableXMin( myXGridMinorEnabled );
2282
2283   if ( update )
2284     myPlot->replot();
2285 }
2286 /*!
2287   Sets ver.axis grid parameters
2288 */
2289 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
2290                                  bool yMinorEnabled, const int yMinorMax,
2291                                  bool y2MajorEnabled, const int y2MajorMax,
2292                                  bool y2MinorEnabled, const int y2MinorMax,
2293                                  bool update )
2294 {
2295   myYGridMajorEnabled = yMajorEnabled;
2296   myYGridMinorEnabled = yMinorEnabled;
2297   myYGridMaxMajor = yMajorMax;
2298   myYGridMaxMinor = yMinorMax;
2299
2300   if (mySecondY) {
2301     myY2GridMajorEnabled = y2MajorEnabled;
2302     myY2GridMinorEnabled = y2MinorEnabled;
2303     myY2GridMaxMajor = y2MajorMax;
2304     myY2GridMaxMinor = y2MinorMax;
2305   }
2306   myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
2307   myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
2308
2309   if (mySecondY) {
2310     myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
2311     myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
2312   }
2313
2314   QwtPlotGrid* grid = myPlot->grid();
2315   if ( !myPlot->axisScaleDiv( QwtPlot::yLeft ).isEmpty() )
2316     grid->setYDiv( myPlot->axisScaleDiv( QwtPlot::yLeft ) );
2317
2318   if (mySecondY) {
2319     if (myYGridMajorEnabled) {
2320       grid->enableY( myYGridMajorEnabled );
2321       grid->enableYMin( myYGridMinorEnabled );
2322     }
2323     else if (myY2GridMajorEnabled) {
2324       if ( !myPlot->axisScaleDiv( QwtPlot::yRight ).isEmpty() )
2325         grid->setYDiv( myPlot->axisScaleDiv( QwtPlot::yRight ) );
2326       grid->enableY( myY2GridMajorEnabled );
2327       grid->enableYMin( myY2GridMinorEnabled );
2328     }
2329     else {
2330       grid->enableY( false );
2331       grid->enableYMin( false );
2332     }
2333   }
2334   else {
2335     grid->enableY( myYGridMajorEnabled );
2336     grid->enableYMin( myYGridMinorEnabled );
2337   }
2338   if ( update )
2339     myPlot->replot();
2340 }
2341
2342 /*!
2343   Sets title for some axis
2344 */
2345 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
2346                                  ObjectType type, bool update )
2347 {
2348   switch (type) {
2349     case MainTitle:
2350       myTitleEnabled = enabled;
2351       myTitle = title;
2352       myPlot->setTitle( myTitleEnabled ? myTitle : QString() );
2353       break;
2354     case XTitle:
2355       myXTitleEnabled = enabled;
2356       myXTitle = title;
2357       myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString() );
2358       break;
2359     case YTitle:
2360       myYTitleEnabled = enabled;
2361       myYTitle = title;
2362       myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString() );
2363       break;
2364     case Y2Title:
2365       myY2TitleEnabled = enabled;
2366       myY2Title = title;
2367       myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString() );
2368       break;
2369     default:
2370       break;
2371   }
2372   if ( update )
2373     myPlot->replot();
2374 }
2375 /*!
2376   Sets title for some axis
2377 */
2378 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
2379 {
2380   QString title = "";
2381   switch (type) {
2382     case MainTitle:
2383       title = myTitle;   break;
2384     case XTitle:
2385       title = myXTitle;  break;
2386     case YTitle:
2387       title = myYTitle;  break;
2388     case Y2Title:
2389       title = myY2Title; break;
2390     default:
2391       break;
2392   }
2393   return title;
2394 }
2395 /*!
2396   Sets font for Plot2d object : title or axis
2397 */
2398 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
2399 {
2400   switch (type) {
2401     case MainTitle:
2402       myPlot->title().setFont(font);
2403       break;
2404     case XTitle:
2405        myPlot->axisTitle(QwtPlot::xBottom).setFont(font); break;
2406     case YTitle:
2407       myPlot->axisTitle(QwtPlot::yLeft).setFont(font);    break;
2408     case Y2Title:
2409       myPlot->axisTitle(QwtPlot::yRight).setFont(font);   break;
2410     case XAxis:
2411       myPlot->setAxisFont(QwtPlot::xBottom, font);        break;
2412     case YAxis:
2413       myPlot->setAxisFont(QwtPlot::yLeft, font);          break;
2414     case Y2Axis:
2415       myPlot->setAxisFont(QwtPlot::yRight, font);         break;
2416   }
2417   if ( update )
2418     myPlot->replot();
2419 }
2420
2421 /*!
2422   Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
2423 */
2424 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
2425 {
2426   if ( myXMode == mode )
2427     return;
2428
2429   // san -- Protection against QwtCurve bug in Qwt 0.4.x:
2430   // it crashes if switched to X/Y logarithmic mode, when one or more points have
2431   // non-positive X/Y coordinate
2432   if ( mode && !isXLogEnabled() ){
2433 #ifndef NO_SUIT
2434     SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"));
2435 #else
2436     QMessageBox::warning(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"));
2437 #endif
2438     return;
2439   }
2440
2441   myXMode = mode;
2442
2443   // set bounds of logarithmic scale
2444   if( myXMode != 0 ) {
2445     myPlot->setAxisScale( QwtPlot::xBottom, 1.0, 1e5 );
2446     myPlot->updateAxes();
2447   }
2448
2449   myPlot->setLogScale(QwtPlot::xBottom, myXMode != 0);
2450
2451   if ( update )
2452     fitAll();
2453   emit vpModeHorChanged();
2454 }
2455
2456 /*!
2457   Gets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
2458 */
2459 int Plot2d_ViewFrame::getHorScaleMode() const
2460 {
2461   return myXMode;
2462 }
2463
2464 /*!
2465   Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
2466 */
2467 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
2468 {
2469   if ( myYMode == mode )
2470     return;
2471
2472   // san -- Protection against QwtCurve bug in Qwt 0.4.x:
2473   // it crashes if switched to X/Y logarithmic mode, when one or more points have
2474   // non-positive X/Y coordinate
2475   if ( mode && !isYLogEnabled() ){
2476 #ifndef NO_SUIT
2477     SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"));
2478 #else
2479     QMessageBox::warning(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"));
2480 #endif
2481     return;
2482   }
2483
2484   myYMode = mode;
2485
2486   // set bounds of logarithmic scale
2487   if( myYMode != 0 ){
2488     myPlot->setAxisScale( QwtPlot::yLeft, 1.0, 1e5 );
2489     myPlot->updateAxes();
2490   }
2491
2492   myPlot->setLogScale(QwtPlot::yLeft, myYMode != 0);
2493   if (mySecondY) {
2494     if( myYMode != 0 ){
2495       myPlot->setAxisScale( QwtPlot::yRight, 1.0, 1e5 );
2496       myPlot->updateAxes();
2497     }
2498     myPlot->setLogScale( QwtPlot::yRight, myYMode != 0 );
2499   }
2500
2501   if ( update )
2502     fitAll();
2503   emit vpModeVerChanged();
2504 }
2505
2506 /*!
2507   Gets scale mode for vertical axis: 0 - linear, 1 - logarithmic
2508 */
2509 int Plot2d_ViewFrame::getVerScaleMode() const
2510 {
2511   return myYMode;
2512 }
2513
2514 /*!
2515   Sets normalization mode to the global maximum by left Y axis
2516 */
2517 void Plot2d_ViewFrame::setNormLMaxMode( bool mode, bool update )
2518 {
2519   if ( myNormLMax == mode )
2520     return;
2521
2522   myNormLMax = mode;
2523   processFiltering(true);
2524   if ( update )
2525     fitAll();
2526   emit vpNormLModeChanged();
2527 }
2528
2529 /*!
2530   Gets normalization mode to the global maximum by left Y axis
2531 */
2532 bool Plot2d_ViewFrame::getNormLMaxMode() const
2533 {
2534   return myNormLMax;
2535 }
2536
2537 /*!
2538   Sets normalization mode to the global minimum by left Y axis
2539 */
2540 void Plot2d_ViewFrame::setNormLMinMode( bool mode, bool update )
2541 {
2542   if ( myNormLMin == mode )
2543     return;
2544
2545   myNormLMin = mode;
2546   processFiltering(true);
2547   if ( update )
2548     fitAll();
2549   emit vpNormLModeChanged();
2550 }
2551
2552 /*!
2553   Gets normalization mode to the global minimum by left Y axis
2554 */
2555 bool Plot2d_ViewFrame::getNormLMinMode() const
2556 {
2557   return myNormLMax;
2558 }
2559
2560 /*!
2561   Sets normalization mode to the global maximum by right Y axis
2562 */
2563 void Plot2d_ViewFrame::setNormRMaxMode( bool mode, bool update )
2564 {
2565   if ( myNormRMax == mode )
2566     return;
2567
2568   myNormRMax = mode;
2569   processFiltering(true);
2570   if ( update )
2571     fitAll();
2572   emit vpNormRModeChanged();
2573 }
2574
2575 /*!
2576   Gets normalization mode to the global maximum by right Y axis
2577 */
2578 bool Plot2d_ViewFrame::getNormRMaxMode() const
2579 {
2580   return myNormRMax;
2581 }
2582
2583 /*!
2584   Sets normalization mode to the global minimum by right Y axis
2585 */
2586 void Plot2d_ViewFrame::setNormRMinMode( bool mode, bool update )
2587 {
2588   if ( myNormRMin == mode )
2589     return;
2590
2591   myNormRMin = mode;
2592   processFiltering(true);
2593   if ( update )
2594     fitAll();
2595   emit vpNormRModeChanged();
2596 }
2597
2598 /*!
2599   Gets normalization mode to the global minimum by right Y axis
2600 */
2601 bool Plot2d_ViewFrame::getNormRMinMode() const
2602 {
2603   return myNormRMax;
2604 }
2605
2606 /*!
2607   Return, scale mode for horizontal axis
2608 */
2609 bool Plot2d_ViewFrame::isModeHorLinear()
2610 {
2611   return (myXMode == 0 ? true : false);
2612 }
2613
2614 /*!
2615   Return, scale mode for vertical axis
2616 */
2617 bool Plot2d_ViewFrame::isModeVerLinear()
2618 {
2619   return (myYMode == 0 ? true : false);
2620 }
2621
2622 /*!
2623   Return \c True if curves are normalize to the global maximum by left Y axis
2624 */
2625 bool Plot2d_ViewFrame::isNormLMaxMode()
2626 {
2627   return (myNormLMax ? true : false);
2628 }
2629
2630 /*!
2631   Return \c True if curves are normalize to the global minimum by left Y axis
2632 */
2633 bool Plot2d_ViewFrame::isNormLMinMode()
2634 {
2635   return (myNormLMin ? true : false);
2636 }
2637
2638 /*!
2639   Return \c True if curves are normalize to the global maximum by right Y axis
2640 */
2641 bool Plot2d_ViewFrame::isNormRMaxMode()
2642 {
2643   return (myNormRMax ? true : false);
2644 }
2645
2646 /*!
2647   Return \c True if curves are normalize to the global minimum by right Y axis
2648 */
2649 bool Plot2d_ViewFrame::isNormRMinMode()
2650 {
2651   return (myNormRMin ? true : false);
2652 }
2653
2654 /*!
2655   Return \c True if legend is shown
2656 */
2657 bool Plot2d_ViewFrame::isLegendShow() const
2658 {
2659   return myShowLegend;
2660 }
2661
2662 /*!
2663   Slot, called when user presses mouse button
2664 */
2665 void Plot2d_ViewFrame::plotMousePressed( const QMouseEvent& me )
2666 {
2667 #ifndef NO_SUIT
2668   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2669   if (aParent)
2670      aParent->putInfo(getInfo(me.pos()));
2671 #endif
2672   if ( myOperation == NoOpId )
2673     myOperation = testOperation( me );
2674   if ( myOperation != NoOpId ) {
2675     myPnt = me.pos();
2676     if ( myOperation == GlPanId ) {
2677       myPlot->setAxisScale( QwtPlot::yLeft,
2678           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2,
2679           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2 );
2680       myPlot->setAxisScale( QwtPlot::xBottom,
2681           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
2682           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
2683       if (mySecondY)
2684         myPlot->setAxisScale( QwtPlot::yRight,
2685           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2,
2686           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2 );
2687       myPlot->replot();
2688     }
2689   }
2690   else {
2691     int btn = me.button() | me.modifiers();
2692     if (btn == Qt::RightButton) {
2693       QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
2694                                             me.pos(), me.button(), me.buttons(), me.modifiers() );
2695       // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
2696       parent()->eventFilter(this, aEvent);
2697     }
2698   }
2699   setFocus();
2700 }
2701 /*!
2702   Slot, called when user moves mouse
2703 */
2704 bool Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
2705 {
2706   int    dx = me.pos().x() - myPnt.x();
2707   int    dy = me.pos().y() - myPnt.y();
2708
2709   bool aRes = false;
2710   if ( myOperation != NoOpId) {
2711     if ( myOperation == ZoomId ) {
2712       this->incrementalZoom( dx, dy );
2713       myPnt = me.pos();
2714       aRes = true;
2715     }
2716     else if ( myOperation == PanId ) {
2717       this->incrementalPan( dx, dy );
2718       myPnt = me.pos();
2719       aRes = true;
2720     }
2721   }
2722   else {
2723 #ifndef NO_SUIT
2724      Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2725      if (aParent)
2726        aParent->putInfo(getInfo(me.pos()));
2727 #endif
2728   }
2729   return aRes;
2730 }
2731 /*!
2732   Slot, called when user releases mouse
2733 */
2734 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
2735 {
2736   if ( myOperation == NoOpId && me.button() == Qt::RightButton && me.modifiers() != Qt::ControlModifier )
2737   {
2738     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
2739                               me.pos(), me.globalPos() );
2740     emit contextMenuRequested( &aEvent );
2741   }
2742   else {
2743 #ifndef NO_ANALYTICAL_CURVES
2744     updateAnalyticalCurves();
2745 #endif
2746   }
2747   myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
2748   myPlot->defaultPicker();
2749
2750 #ifndef NO_SUIT
2751   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2752    if (aParent)
2753      aParent->putInfo(tr("INF_READY"));
2754 #endif
2755   myOperation = NoOpId;
2756 }
2757 /*!
2758   Slot, called when user wheeling mouse
2759 */
2760 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
2761 {
2762   QwtPlotLayout* pl = myPlot->plotLayout();
2763
2764   // compute zooming factor
2765   double aDelta = event->delta();
2766   double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
2767
2768   bool scaleXBottom = pl->scaleRect(QwtPlot::xBottom).contains( event->pos() ) ||
2769                       pl->canvasRect().contains( event->pos() );
2770   bool scaleYLeft   = pl->scaleRect(QwtPlot::yLeft).contains( event->pos() ) ||
2771                       pl->canvasRect().contains( event->pos() );
2772   bool scaleYRight  = mySecondY && ( pl->scaleRect(QwtPlot::yRight).contains( event->pos() ) ||
2773                                      pl->canvasRect().contains( event->pos() ) );
2774
2775   // scale x bottom axis
2776   if ( scaleXBottom ) {
2777     QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
2778     if ( xMap.s2() - xMap.s1() > 1.0e-12 || aScale > 1 )
2779       myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(), xMap.s1() + aScale*(xMap.s2() - xMap.s1()) );
2780   }
2781
2782   // scale y left axis
2783   if ( scaleYLeft ) {
2784     QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
2785     if ( yMap.s2() - yMap.s1() > 1.0e-12 || aScale > 1 )
2786       myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(), yMap.s1() + aScale*(yMap.s2() - yMap.s1()) );
2787   }
2788
2789   // scale y right axis (note: mySecondY value is checked above)
2790   if ( scaleYRight ) {
2791     QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yRight );
2792     if ( yMap.s2() - yMap.s1() > 10e-12 || aScale > 1 )
2793       myPlot->setAxisScale( QwtPlot::yRight, yMap.s1(), yMap.s1() + aScale*(yMap.s2() - yMap.s1()) );
2794   }
2795
2796   // redraw
2797   myPlot->replot();
2798   // update zoomer
2799   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
2800   // store current mouse position
2801   myPnt = event->pos();
2802 #ifndef NO_ANALYTICAL_CURVES
2803   // update analytical curves
2804   updateAnalyticalCurves();
2805 #endif
2806 }
2807
2808 /*!
2809   Returns qwt plot curve if it is existed in map of curves and 0 otherwise
2810 */
2811 QwtPlotCurve* Plot2d_ViewFrame::getPlotCurve( Plot2d_Curve* curve ) const
2812 {
2813   return dynamic_cast<QwtPlotCurve*>( getPlotObject( curve ) );
2814 }
2815 /*!
2816   Returns true if qwt plot curve is existed in map of curves and false otherwise
2817 */
2818 bool Plot2d_ViewFrame::hasPlotCurve( Plot2d_Curve* curve ) const
2819 {
2820   return hasPlotObject( curve );
2821 }
2822
2823 /*!
2824   Returns qwt plot curve if it is existed in map of curves and 0 otherwise
2825 */
2826 QwtPlotItem* Plot2d_ViewFrame::getPlotObject( Plot2d_Object* object ) const
2827 {
2828   ObjectDict::const_iterator it = myObjects.begin();
2829   for ( ; it != myObjects.end(); it++ ) {
2830     if ( it.value() == object )
2831       return it.key();
2832   }
2833   return 0;
2834 }
2835 /*!
2836   Returns true if qwt plot curve is existed in map of curves and false otherwise
2837 */
2838 bool Plot2d_ViewFrame::hasPlotObject( Plot2d_Object* object ) const
2839 {
2840   ObjectDict::const_iterator it = myObjects.begin();
2841   for ( ; it != myObjects.end(); it++ ) {
2842     if ( it.value() == object )
2843       return true;
2844   }
2845   return false;
2846 }
2847
2848 /*!
2849   Sets curve type
2850 */
2851 void Plot2d_ViewFrame::setCurveType( QwtPlotCurve* curve, int curveType )
2852 {
2853   if ( !curve )
2854     return;
2855   if ( myCurveType == 0 )
2856     curve->setStyle( QwtPlotCurve::Dots );//QwtCurve::NoCurve
2857   else if ( myCurveType == 1 ) {
2858     curve->setStyle( QwtPlotCurve::Lines );
2859     curve->setCurveAttribute( QwtPlotCurve::Fitted, false );
2860   }
2861   else if ( myCurveType == 2 ) {
2862     curve->setStyle( QwtPlotCurve::Lines );
2863     QwtSplineCurveFitter* fitter = new QwtSplineCurveFitter();
2864     fitter->setSplineSize( 250 );
2865     curve->setCurveAttribute( QwtPlotCurve::Fitted, true );
2866     curve->setCurveFitter( fitter );
2867   }
2868 }
2869
2870 /*!
2871   View operations : Pan view
2872 */
2873 void Plot2d_ViewFrame::onViewPan()
2874 {
2875   // reset the previous operation
2876   myPlot->defaultPicker();
2877
2878   QCursor panCursor (Qt::SizeAllCursor);
2879   myPlot->canvas()->setCursor( panCursor );
2880   myOperation = PanId;
2881 }
2882 /*!
2883   View operations : Zoom view
2884 */
2885 void Plot2d_ViewFrame::onViewZoom()
2886 {
2887   // reset the previous operation
2888   myPlot->defaultPicker();
2889
2890   QPixmap zoomPixmap (imageZoomCursor);
2891   QCursor zoomCursor (zoomPixmap);
2892   myPlot->canvas()->setCursor( zoomCursor );
2893   myOperation = ZoomId;
2894 }
2895 /*!
2896   View operations : Fit All
2897 */
2898 void Plot2d_ViewFrame::onViewFitAll()
2899 {
2900   fitAll();
2901
2902   // reset the previous operation
2903   myPlot->defaultPicker();
2904   myPlot->canvas()->setCursor( QCursor(Qt::CrossCursor) );
2905   myOperation = NoOpId;
2906 }
2907 /*!
2908   View operations : Fit Area
2909 */
2910 void Plot2d_ViewFrame::onViewFitArea()
2911 {
2912   myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
2913   myOperation = FitAreaId;
2914   myPlot->setPickerMousePattern( Qt::LeftButton );
2915 }
2916 /*!
2917   View operations : Global panning
2918 */
2919 void Plot2d_ViewFrame::onViewGlobalPan()
2920 {
2921   // reset the previous operation
2922   myPlot->defaultPicker();
2923
2924   QPixmap globalPanPixmap (imageCrossCursor);
2925   QCursor glPanCursor (globalPanPixmap);
2926   myPlot->canvas()->setCursor( glPanCursor );
2927   myPlot->setLogScale(QwtPlot::xBottom, false);
2928   myPlot->setLogScale(QwtPlot::yLeft, false);
2929   if (mySecondY)
2930     myPlot->setLogScale(QwtPlot::yRight, false);
2931   myPlot->replot();
2932   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
2933   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
2934
2935   myXDistance = xMap.s2() - xMap.s1();
2936   myYDistance = yMap.s2() - yMap.s1();
2937
2938   if (mySecondY) {
2939     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
2940     myYDistance2 = yMap2.s2() - yMap2.s1();
2941   }
2942   // don't make fit all
2943   // fitAll();
2944   myOperation = GlPanId;
2945 }
2946
2947 /*!
2948   Precaution for logarithmic X scale
2949 */
2950 bool Plot2d_ViewFrame::isXLogEnabled() const
2951 {
2952   bool allPositive = true;
2953   ObjectDict::const_iterator it = myObjects.begin();
2954   for ( ; allPositive && it != myObjects.end(); it++ )
2955     allPositive = ( it.value()->getMinX() > 0. );
2956   return allPositive;
2957 }
2958
2959 /*!
2960   Precaution for logarithmic Y scale
2961 */
2962 bool Plot2d_ViewFrame::isYLogEnabled() const
2963 {
2964   bool allPositive = true;
2965   ObjectDict::const_iterator it = myObjects.begin();
2966   for ( ; allPositive && it != myObjects.end(); it++ )
2967     allPositive = ( it.value()->getMinY() > 0. );
2968   return allPositive;
2969 }
2970
2971 /**
2972  *
2973  */
2974 void Plot2d_ViewFrame::setEnableAxis( QwtPlot::Axis theAxis, bool isEnable )
2975 {
2976   if ( myPlot->axisEnabled( theAxis ) == isEnable )
2977     return;
2978   myPlot->enableAxis( theAxis, isEnable );
2979   if ( theAxis == QwtPlot::yRight )
2980     mySecondY = isEnable;
2981 }
2982
2983 class Plot2d_QwtPlotZoomer : public QwtPlotZoomer
2984 {
2985 public:
2986   Plot2d_QwtPlotZoomer( int xAxis, int yAxis, QWidget* canvas )
2987   : QwtPlotZoomer( xAxis, yAxis, canvas )
2988   {
2989     qApp->installEventFilter( this );
2990     // now picker working after only a button pick.
2991     // after click on button FitArea in toolbar of the ViewFrame.
2992   };
2993   ~Plot2d_QwtPlotZoomer() {};
2994 };
2995
2996 /*!
2997   Constructor
2998 */
2999 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
3000   : QwtPlot( parent ),
3001     myPicker( 0 )
3002 {
3003   // Create alternative scales
3004   setAxisScaleDraw( QwtPlot::yLeft,   new Plot2d_ScaleDraw() );
3005   setAxisScaleDraw( QwtPlot::xBottom, new Plot2d_ScaleDraw() );
3006   setAxisScaleDraw( QwtPlot::yRight,  new Plot2d_ScaleDraw() );
3007
3008   myPlotZoomer = new Plot2d_QwtPlotZoomer( QwtPlot::xBottom, QwtPlot::yLeft, canvas() );
3009   myPlotZoomer->setTrackerMode( QwtPicker::AlwaysOff );
3010   myPlotZoomer->setRubberBand( QwtPicker::RectRubberBand );
3011   myPlotZoomer->setRubberBandPen( QColor( Qt::green ) );
3012
3013   defaultPicker();
3014
3015   // auto scaling by default
3016   setAxisAutoScale( QwtPlot::yLeft );
3017   setAxisAutoScale( QwtPlot::yRight );
3018   setAxisAutoScale( QwtPlot::xBottom );
3019
3020   myScaleDraw = NULL;
3021 // grid
3022   myGrid = new QwtPlotGrid();
3023   QPen aMajPen = myGrid->majorPen();
3024   aMajPen.setStyle( Qt::DashLine );
3025   myGrid->setPen( aMajPen );
3026
3027   myGrid->enableX( false );
3028   myGrid->enableXMin( false );
3029   myGrid->enableY( false );
3030   myGrid->enableYMin( false );
3031
3032   myGrid->attach( this );
3033
3034   setMouseTracking( false );
3035   canvas()->setMouseTracking( true );
3036
3037   myPlotZoomer->setEnabled( true );
3038   myPlotZoomer->setZoomBase();
3039
3040   setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
3041 }
3042
3043 Plot2d_Plot2d::~Plot2d_Plot2d()
3044 {
3045 }
3046
3047 /*!
3048   \set axis scale engine - linear or log10
3049 */
3050 void Plot2d_Plot2d::setLogScale( int axisId, bool log10 )
3051 {
3052   if ( log10 )
3053     setAxisScaleEngine( axisId, new QwtLogScaleEngine() );
3054   else
3055     setAxisScaleEngine( axisId, new QwtLinearScaleEngine() );
3056 }
3057
3058 /*!
3059   Recalculates and redraws Plot 2d view
3060 */
3061 void Plot2d_Plot2d::replot()
3062 {
3063   // the following code is intended to enable only axes
3064   // that are really used by displayed objects
3065   bool enableXBottom = false, enableXTop   = false;
3066   bool enableYLeft   = false, enableYRight = false;
3067   const QwtPlotItemList& items = itemList();
3068   QwtPlotItemIterator it;
3069   for ( it = items.begin(); it != items.end(); it++ ) {
3070     QwtPlotItem* item = *it;
3071     if ( item ) {
3072       enableXBottom |= item->xAxis() == QwtPlot::xBottom;
3073       enableXTop    |= item->xAxis() == QwtPlot::xTop;
3074       enableYLeft   |= item->yAxis() == QwtPlot::yLeft;
3075       enableYRight  |= item->yAxis() == QwtPlot::yRight;
3076     }
3077   }
3078   enableAxis( QwtPlot::xBottom, enableXBottom );
3079   enableAxis( QwtPlot::xTop,    enableXTop );
3080   enableAxis( QwtPlot::yLeft,   enableYLeft );
3081   enableAxis( QwtPlot::yRight,  enableYRight );
3082
3083   updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
3084   QwtPlot::replot();
3085 }
3086
3087 /*!
3088   Get legend
3089 */
3090 QwtAbstractLegend* Plot2d_Plot2d::getLegend()
3091 {
3092 #if QWT_VERSION < 0x040200
3093   return d_legend;
3094 #else
3095   return legend(); /* mpv: porting to the Qwt 4.2.0 */
3096 #endif
3097 }
3098
3099 /*!
3100   \return the recommended size for the widget
3101 */
3102 QSize Plot2d_Plot2d::sizeHint() const
3103 {
3104   return QwtPlot::minimumSizeHint();
3105 }
3106
3107 /*!
3108   return minimum size for qwt plot
3109 */
3110 QSize Plot2d_Plot2d::minimumSizeHint() const
3111 {
3112   return QSize( 0, 0 );
3113 //  QSize aSize = QwtPlot::minimumSizeHint();
3114 //  return QSize(aSize.width()*3/4, aSize.height());
3115 }
3116
3117 void Plot2d_Plot2d::defaultPicker()
3118 {
3119   myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1,
3120                                  Qt::RightButton, Qt::ControlModifier ); // zooming button
3121   for ( int i = QwtEventPattern::MouseSelect2; i < QwtEventPattern::MouseSelect6; i++ )
3122     myPlotZoomer->setMousePattern( (QwtEventPattern::MousePatternCode)i, Qt::NoButton,
3123                                        Qt::NoModifier );
3124 }
3125
3126 void Plot2d_Plot2d::setPickerMousePattern( int button, int state )
3127 {
3128   myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1, (Qt::MouseButton)button,
3129                                          (Qt::KeyboardModifiers)state );
3130 }
3131
3132 /*!
3133  * Set the point picker associated with a graphic view
3134  */
3135 void Plot2d_Plot2d::setPicker( Plot2d_QwtPlotPicker *picker)
3136 {
3137   myPicker = picker;
3138 }
3139
3140 /*!
3141  * Create marker and tooltip associed with a point
3142  */
3143 QwtPlotMarker* Plot2d_Plot2d::createMarkerAndTooltip( QwtSymbol* symbol,
3144                                                       double    X,
3145                                                       double    Y,
3146                                                       QString & tooltip,
3147                                                       Plot2d_QwtPlotPicker *picker)
3148 {
3149   QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
3150
3151   aPlotMarker->setSymbol( symbol );  // symbol must have a color
3152   aPlotMarker->setLabelAlignment( Qt::AlignTop);
3153   aPlotMarker->setXValue(X);
3154   aPlotMarker->setYValue(Y);
3155   //
3156   aPlotMarker->attach(this);
3157
3158   // Associate a tooltip with the point's marker
3159   // PB: how to obtain a tooltip with a rectangular frame ?
3160   //QwtText tooltip ("X=" + QString::number(X) + " Y=" + QString::number(Y) );
3161
3162   QwtText text (tooltip);
3163   //QColor tooltipColor( 245, 222, 179);            // Wheat  -RGB (0 a 255)
3164   QColor tooltipColor( 253, 245, 230);            // OldLace
3165   text.setBackgroundBrush( QBrush(tooltipColor)); //, Qt::SolidPattern));
3166   //
3167   if ( picker ) {
3168     picker->pMarkers.append( aPlotMarker);
3169     picker->pMarkersToolTip[ aPlotMarker] = text;
3170   }
3171   return aPlotMarker;
3172 }
3173
3174 QwtPlotGrid* Plot2d_Plot2d::grid() const
3175 {
3176   return myGrid;
3177 };
3178
3179 QwtPlotZoomer* Plot2d_Plot2d::zoomer() const
3180 {
3181   return myPlotZoomer;
3182 }
3183
3184 /*!
3185   Updates identifiers of Y axis type in the legend.
3186 */
3187 void Plot2d_Plot2d::updateYAxisIdentifiers()
3188 {
3189   bool enableYLeft = false, enableYRight = false;
3190   const QwtPlotItemList& items = itemList();
3191   QwtPlotItemIterator it;
3192   for ( it = items.begin(); it != items.end(); it++ ) {
3193     QwtPlotItem* item = *it;
3194     if ( item ) {
3195       enableYLeft  |= item->yAxis() == QwtPlot::yLeft;
3196       enableYRight |= item->yAxis() == QwtPlot::yRight;
3197     }
3198   }
3199
3200   // if several curves are attached to different axes
3201   // display corresponding identifiers in the legend,
3202   // otherwise hide them
3203   for ( it = items.begin(); it != items.end(); it++ ) {
3204     QwtPlotItem* item = *it;
3205     if ( Plot2d_QwtPlotCurve* aPCurve = dynamic_cast<Plot2d_QwtPlotCurve*>( item ) )
3206       aPCurve->setYAxisIdentifierEnabled( enableYLeft && enableYRight );
3207     if ( item && item->isVisible() && legend() )
3208       item->updateLegend( item, item->legendData() );
3209   }
3210 }
3211
3212 // Methods to manage axis graduations
3213
3214 /* Create definition and graduations of axes
3215  */
3216 void Plot2d_Plot2d::createAxisScaleDraw()
3217 {
3218   myScaleDraw = new Plot2d_AxisScaleDraw( this);
3219 }
3220
3221
3222 /* Stock X axis's ticks in the drawing zone
3223 */
3224 void Plot2d_Plot2d::applyTicks()
3225 {
3226   myScaleDraw->applyTicks();
3227 }
3228
3229
3230 /* Unactivate automatic ticks drawing (call to method Plot2d_AxisScaleDraw::draw() )
3231  * Parameters :
3232  * - number call to ticks drawing (for information) : numcall
3233  */
3234 void Plot2d_Plot2d::unactivAxisScaleDraw( int numcall)
3235 {
3236   // Memorize X axis (myScaleDraw already exists) in the drawing zone
3237   //setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw);  // heritage of QwtPlot
3238
3239   myScaleDraw->unactivTicksDrawing( numcall);
3240 }
3241
3242
3243 /* Draw ticks and labels on X axis of the drawing zone
3244  * Draw systems' names under the X axis of the drawing zone
3245  * Draw vertical segments between X axis's intervals of the systems
3246  * Parameters :
3247  * - left and right margins for ticks : XLeftMargin, XRightMargin
3248  * - for each named system :
3249  *     positions and labels for ticks on X axis : devicesPosLabelTicks
3250  *
3251  * The true drawings will be realized by the method Plot2d_AxisScaleDraw::draw()
3252  * PB: who call il ?
3253  */
3254 void Plot2d_Plot2d::displayXTicksAndLabels(
3255                       double XLeftMargin, double XRightMargin,
3256                       const QList< QPair< QString, QMap<double, QString> > > & devicesPosLabelTicks)
3257                       //                    name        position  label
3258                       //                   system         tick    tick
3259 {
3260   //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
3261
3262   int nbDevices = devicesPosLabelTicks.size();
3263   //
3264   //std::cout << "  Nombre de systemes = " << nbDevices << std::endl;
3265   if (nbDevices == 0)  return;
3266
3267   // For drawing systems' names, their positions must be in the allTicks list
3268   // (cf class Plot2d_AxisScaleDraw)
3269
3270   // Liste of ticks' positions and systems' names
3271   QList<double> allTicks;
3272
3273   double devXmin, devXmax;  // X interval of a system
3274   double gapXmin, gapXmax;  // X interval between two systems
3275   double devLabPos;         // Label's position of a system
3276   double segmentPos;  // Position of the vertical segment between current system and the next
3277
3278   // 1)- Search for the system whose X interval is the most to the left
3279
3280   int ileftDev = 0;
3281   double XminMin = 1.e+12;
3282
3283   if (nbDevices > 1)
3284   {
3285       for (int idev=0; idev < nbDevices; idev++)
3286       {
3287           QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
3288
3289           QString deviceLabel = paire.first;
3290
3291           // Ticks' map of the system
3292           QMap<double,QString> devPosLabelTicks = paire.second;
3293
3294           QList<double> posTicks = devPosLabelTicks.keys();
3295
3296           // List's items increasing sorting
3297           qSort( posTicks.begin(), posTicks.end() );  // iterators
3298
3299           // X interval for the system
3300           devXmin = posTicks.first();
3301           devXmax = posTicks.last();
3302
3303           if (devXmin < XminMin)
3304           {
3305               XminMin = devXmin;
3306               ileftDev = idev;
3307           }
3308       }
3309   }
3310
3311   // 2)- Ticks, systems' names, verticals segments
3312
3313   for (int idev=0; idev < nbDevices; idev++)
3314   {
3315       QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
3316
3317       QString deviceLabel = paire.first;
3318
3319       std::string std_label = deviceLabel.toStdString();
3320       //const char *c_label = std_label.c_str();
3321       //std::cout << "  deviceLabel: |" << c_label << "|" << std::endl;
3322
3323       // Ticks' map of the system
3324       QMap<double,QString> devPosLabelTicks = paire.second;
3325
3326       int nbTicks = devPosLabelTicks.size();
3327
3328       QList<double> posTicks = devPosLabelTicks.keys();
3329
3330       // List's items increasing sorting
3331       qSort( posTicks.begin(), posTicks.end() );  // iterators
3332
3333       // X interval for the system
3334       devXmin = posTicks.first();
3335       devXmax = posTicks.last();
3336
3337       // Stock ticks' positions and labels on X axis
3338       double pos;
3339       QString label;
3340       //
3341       for (int itic=0; itic < nbTicks; itic++)
3342       {
3343           pos   = posTicks.at(itic);
3344           label = devPosLabelTicks[pos];
3345
3346           myScaleDraw->setLabelTick( pos, label, false);
3347
3348           std::string std_label = label.toStdString();
3349           //const char *c_label = std_label.c_str();
3350           //std::cout << "    tick " << itic << " : pos= " << pos << ", label= |" << c_label << "|" << std::endl;
3351       }
3352       allTicks.append( posTicks);
3353
3354       // Compute the position of the system's label
3355       if (idev == ileftDev)
3356       {
3357           devLabPos = devXmin + 0.25*(devXmax - devXmin);
3358       }
3359       else
3360       {
3361           devLabPos = devXmin + 0.50*(devXmax - devXmin);
3362       }
3363       allTicks.append( devLabPos);
3364
3365       // Stock position and name of the system under X axis
3366       myScaleDraw->setLabelTick( devLabPos, deviceLabel, true);
3367
3368       if (idev > 0)
3369       {
3370           // Create the vertical segment between the current system and the next
3371           gapXmax = devXmin;
3372           segmentPos = gapXmin + 0.5*(gapXmax - gapXmin);
3373
3374           createSeparationLine( segmentPos);
3375       }
3376       gapXmin = devXmax;
3377   }
3378
3379   // List's items increasing sorting
3380   qSort( allTicks.begin(), allTicks.end() );  // iterators
3381
3382   // Stock the interval of X's values
3383   double lowerBound = allTicks.first() - XLeftMargin;
3384   double upperBound = allTicks.last() + XRightMargin;
3385   myScaleDraw->setInterval( lowerBound, upperBound);
3386
3387   // For each system, stock the position of the X's ticks and those of the name
3388   myScaleDraw->setTicks( allTicks);  // do not draw the ticks
3389
3390   // Memorize the X axis in the drawing zone
3391   setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw);  // heritage of QwtPlot
3392
3393   //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
3394 }
3395
3396
3397 /* Create vertical segment between two curves
3398  */
3399 void Plot2d_Plot2d::createSeparationLine( double Xpos)
3400 {
3401   QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
3402
3403   aPlotMarker->setLineStyle( QwtPlotMarker::VLine);
3404   aPlotMarker->setXValue( Xpos);
3405   aPlotMarker->setLinePen( QPen(Qt::black));
3406   aPlotMarker->attach(this);  // Add to drawing zone
3407   // To deallocate in EraseAll()
3408   mySeparationLineList.append( aPlotMarker);
3409 }
3410
3411 void Plot2d_Plot2d::clearSeparationLineList()
3412 {
3413   mySeparationLineList.clear();
3414 }
3415
3416 /* Set type of legend symbol
3417  */
3418 void Plot2d_Plot2d::setLegendSymbolType( const int type )
3419 {
3420   myLegendSymbolType = type;
3421 }
3422
3423 /* Get type of legend symbol
3424  */
3425 int Plot2d_Plot2d::getLegendSymbolType()
3426 {
3427   return myLegendSymbolType;
3428 }
3429
3430 /*!
3431   Creates presentation of object
3432   Default implementation is empty
3433 */
3434 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
3435 {
3436   return 0;
3437 }
3438
3439 /*!
3440   Copies preferences from other viewframe
3441   \param vf - other view frame
3442 */
3443 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
3444 {
3445   if( !vf )
3446     return;
3447
3448   myCurveType = vf->myCurveType;
3449   myShowLegend = vf->myShowLegend;
3450   myLegendPos = vf->myLegendPos;
3451   myLegendSymbolType = vf->myLegendSymbolType;
3452   myLegendFont = vf->myLegendFont;
3453   mySelectedLegendFontColor = vf->mySelectedLegendFontColor;
3454   myMarkerSize = vf->myMarkerSize;
3455   myBackground = vf->myBackground;
3456   mySelectionColor = vf->mySelectionColor;
3457   myTitle = vf->myTitle;
3458   myXTitle = vf->myXTitle;
3459   myYTitle = vf->myYTitle;
3460   myY2Title = vf->myY2Title;
3461   myTitleEnabled = vf->myTitleEnabled;
3462   myXTitleEnabled = vf->myXTitleEnabled;
3463   myYTitleEnabled = vf->myYTitleEnabled;
3464   myY2TitleEnabled = vf->myY2TitleEnabled;
3465   myXGridMajorEnabled = vf->myXGridMajorEnabled;
3466   myYGridMajorEnabled = vf->myYGridMajorEnabled;
3467   myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
3468   myXGridMinorEnabled = vf->myXGridMinorEnabled;
3469   myYGridMinorEnabled = vf->myYGridMinorEnabled;
3470   myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
3471   myXGridMaxMajor = vf->myXGridMaxMajor;
3472   myYGridMaxMajor = vf->myYGridMaxMajor;
3473   myY2GridMaxMajor = vf->myY2GridMaxMajor;
3474   myXGridMaxMinor = vf->myXGridMaxMinor;
3475   myYGridMaxMinor = vf->myYGridMaxMinor;
3476   myY2GridMaxMinor = vf->myY2GridMaxMinor;
3477   myXMode = vf->myXMode;
3478   myYMode = vf->myYMode;
3479   mySecondY = vf->mySecondY;
3480 }
3481
3482 /*!
3483   Updates titles according to curves
3484 */
3485 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
3486 void Plot2d_ViewFrame::updateTitles( const bool update )
3487 {
3488   ObjectDict::iterator it = myObjects.begin();
3489   QStringList aXTitles;
3490   QStringList aYTitles;
3491   QStringList aY2Titles;
3492   QStringList aXUnits;
3493   QStringList aYUnits;
3494   QStringList aY2Units;
3495   QStringList aTables;
3496   int i = 0;
3497
3498   Plot2d_Object* anObject;
3499   for ( ; it != myObjects.end(); it++ ) {
3500     // collect titles and units from all curves...
3501     anObject = it.value();
3502     QString xTitle = anObject->getHorTitle().trimmed();
3503     QString yTitle = anObject->getVerTitle().trimmed();
3504     QString xUnits = anObject->getHorUnits().trimmed();
3505     QString yUnits = anObject->getVerUnits().trimmed();
3506
3507     if ( anObject->getYAxis() == QwtPlot::yLeft ) {
3508       if ( !aYTitles.contains( yTitle ) )
3509         aYTitles.append( yTitle );
3510       if ( !aYUnits.contains( yUnits ) )
3511         aYUnits.append( yUnits );
3512     }
3513     else {
3514       if ( !aY2Titles.contains( yTitle ) )
3515         aY2Titles.append( yTitle );
3516       if ( !aY2Units.contains( yUnits ) )
3517         aY2Units.append( yUnits );
3518     }
3519     if ( !aXTitles.contains( xTitle ) )
3520       aXTitles.append( xTitle );
3521     if ( !aXUnits.contains( xUnits ) )
3522       aXUnits.append( xUnits );
3523
3524     QString aName = anObject->getTableTitle();
3525     if( !aName.isEmpty() && !aTables.contains( aName ) )
3526       aTables.append( aName );
3527     ++i;
3528   }
3529   // ... and update plot 2d view
3530   QString xUnits, yUnits, y2Units;
3531   if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
3532     xUnits = BRACKETIZE( aXUnits[0] );
3533   if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
3534     yUnits = BRACKETIZE( aYUnits[0] );
3535   if ( aY2Units.count() == 1 && !aY2Units[0].isEmpty())
3536     y2Units = BRACKETIZE( aY2Units[0] );
3537   QString xTitle, yTitle, y2Title;
3538   if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
3539     xTitle = aXTitles[0];
3540   if ( aYTitles.count() == 1 )
3541     yTitle = aYTitles[0];
3542   if ( mySecondY && aY2Titles.count() == 1 )
3543     y2Title = aY2Titles[0];
3544
3545   if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
3546     xTitle += " ";
3547   if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
3548     yTitle += " ";
3549   if ( !y2Title.isEmpty() && !y2Units.isEmpty() )
3550     y2Title += " ";
3551
3552   setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, false );
3553   setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, false );
3554   if ( mySecondY )
3555     setTitle( myY2TitleEnabled, y2Title + y2Units, Y2Title, false );
3556   if( myIsDefTitle )
3557     setTitle( true, aTables.join("; "), MainTitle, false );
3558
3559   // do update if necessary
3560   if ( update ) {
3561     myPlot->replot();
3562   }
3563 }
3564
3565 /*!
3566   Outputs content of viewframe to file
3567   \param file - file name
3568   \param format - file format
3569 */
3570 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
3571 {
3572 #ifdef WIN32
3573   return false;
3574
3575 #else
3576   bool res = false;
3577   if( myPlot )
3578   {
3579     QPaintDevice* pd = 0;
3580     if( format=="PS" || format=="EPS" || format == "PDF" )
3581     {
3582       QPrinter* pr = new QPrinter( QPrinter::HighResolution );
3583       if(format == "PDF")
3584           pr->setOutputFormat(QPrinter::PdfFormat);
3585       pr->setPageSize( QPrinter::A4 );
3586       pr->setOutputFileName( file );
3587       pr->setPrintProgram( "" );
3588       pd = pr;
3589     }
3590
3591     if( pd )
3592     {
3593       QwtPlotRenderer* pr = new QwtPlotRenderer();
3594       pr->renderTo( myPlot, *pd );
3595       res = true;
3596       delete pd;
3597     }
3598   }
3599   return res;
3600 #endif
3601
3602 }
3603
3604 /**
3605  * Print Plot2d window
3606  */
3607 void Plot2d_ViewFrame::printPlot( QPainter* p, const QRectF& rect) const
3608 {
3609   QwtPlotRenderer* pr = new QwtPlotRenderer();
3610   pr->render( myPlot, p, rect );
3611 }
3612
3613 /*!
3614   \return string with all visual parameters
3615 */
3616 QString Plot2d_ViewFrame::getVisualParameters()
3617 {
3618
3619   return getXmlVisualParameters();
3620
3621   /*
3622   RNV: Old case, now visual parameters stored in the XML format.
3623   //
3624   double xmin, xmax, ymin, ymax, y2min, y2max;
3625   getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
3626   QString retStr;
3627   //Store font in the visual parameters string as:
3628   //
3629   // ...*FontFamily|FontSize|B|I|U|r:g:b*...
3630
3631   retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%s|%i|%i|%i|%i|%i:%i:%i",
3632                   myXMode, myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max,
3633                   qPrintable(myLegendFont.family()), myLegendFont.pointSize(),myLegendFont.bold(),
3634                   myLegendFont.italic(), myLegendFont.underline(),myLegendColor.red(),
3635                   myLegendColor.green(), myLegendColor.blue());
3636
3637  //store all Analytical curves
3638   //store each curve in the following format
3639   // ...*Name|isActive|Expresion|NbInervals|isAutoAssign[|MarkerType|LineType|LineWidth|r:g:b]
3640   // parameters in the [ ] is optional in case if isAutoAssign == true
3641   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
3642   Plot2d_AnalyticalCurve* c = 0;
3643   bool isAuto;
3644   for( ; it != myAnalyticalCurves.end(); it++) {
3645     c = (*it);
3646     if(!c) continue;
3647     QString curveString("");
3648     isAuto = c->isAutoAssign();
3649     curveString.sprintf("*%s|%i|%s|%i|%i",
3650                         qPrintable(c->getName()),
3651                         c->isActive(),
3652                         qPrintable(c->getExpression()),
3653                         c->getNbIntervals(),
3654                         isAuto);
3655
3656     retStr+=curveString;
3657     if(!isAuto) {
3658       QString optCurveString("");
3659       optCurveString.sprintf("|%i|%i|%i|%i:%i:%i",
3660                              (int)c->getMarker(),
3661                              (int)c->getLine(),
3662                              c->getLineWidth(),
3663                              c->getColor().red(),
3664                              c->getColor().green(),
3665                              c->getColor().blue());
3666       retStr+=optCurveString;
3667     }
3668   }
3669   retStr += QString( "*%1" ).arg( Qtx::colorToString( backgroundColor() ) );
3670   return retStr;
3671   */
3672 }
3673
3674 /*!
3675   Restores all visual parameters from string
3676 */
3677 void Plot2d_ViewFrame::setVisualParameters( const QString& parameters )
3678 {
3679   if(setXmlVisualParameters(parameters))
3680     return;
3681
3682   double xmin, xmax;
3683   QStringList paramsLst = parameters.split( '*' );
3684   if ( paramsLst.size() >= 9 ) {
3685     double ymin, ymax, y2min, y2max;
3686     myXMode = paramsLst[0].toInt();
3687     myYMode = paramsLst[1].toInt();
3688     mySecondY = (bool)paramsLst[2].toInt();
3689     xmin =  paramsLst[3].toDouble();
3690     xmax =  paramsLst[4].toDouble();
3691     ymin =  paramsLst[5].toDouble();
3692     ymax =  paramsLst[6].toDouble();
3693     y2min = paramsLst[7].toDouble();
3694     y2max = paramsLst[8].toDouble();
3695
3696     if (mySecondY)
3697       setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
3698     setHorScaleMode( myXMode, /*update=*/false );
3699     setVerScaleMode( myYMode, /*update=*/false );
3700
3701     if (mySecondY) {
3702       QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
3703       myYDistance2 = yMap2.s2() - yMap2.s1();
3704     }
3705
3706     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3707     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3708   }
3709
3710   //Restore legend font
3711   if(paramsLst.size() >= 10) {
3712     QStringList fontList = paramsLst[9].split( '|' );
3713     if(fontList.size() == 6) {
3714       myLegendFont = QFont(fontList[0]);
3715       myLegendFont.setPointSize(fontList[1].toInt());
3716       myLegendFont.setBold(fontList[2].toInt());
3717       myLegendFont.setItalic(fontList[3].toInt());
3718       myLegendFont.setUnderline(fontList[4].toInt());
3719       QStringList colorList = fontList[5].split(":");
3720       setLegendFont( myLegendFont );
3721
3722       if(colorList.size() == 3) {
3723               myLegendColor = QColor(colorList[0].toInt(),
3724                                                  colorList[1].toInt(),
3725                                                  colorList[2].toInt());
3726               setLegendFontColor( myLegendColor );
3727       }
3728     }
3729   }
3730
3731 #ifndef NO_ANALYTICAL_CURVES
3732   //Restore all Analytical curves
3733   int startCurveIndex = 10;
3734   if( paramsLst.size() >= startCurveIndex+1 ) {
3735     for( int i=startCurveIndex; i<paramsLst.size() ; i++ ) {
3736       QStringList curveLst = paramsLst[i].split("|");
3737       if( curveLst.size() == 5 || curveLst.size() == 9 ) {
3738         Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
3739         c->setName(curveLst[0]);
3740         c->setActive(curveLst[1].toInt());
3741         c->setExpression(curveLst[2]);
3742         c->setNbIntervals(curveLst[3].toLong());
3743         c->setAutoAssign(curveLst[4].toInt());
3744         if( !c->isAutoAssign() ) {
3745           c->setMarker((Plot2d::MarkerType)curveLst[5].toInt());
3746           c->setLine((Plot2d::LineType)curveLst[6].toInt());
3747           c->setLineWidth(curveLst[7].toInt());
3748           QStringList colorList = curveLst[8].split(":");
3749           if( colorList.size() == 3 ) {
3750             c->setColor(QColor(colorList[0].toInt(),
3751                                colorList[1].toInt(),
3752                                colorList[2].toInt()));
3753           }
3754         } else {
3755           c->autoFill( myPlot );
3756         }
3757         addAnalyticalCurve(c);
3758         updateAnalyticalCurve(c);
3759       }
3760       else if( curveLst.size() == 1 ) {
3761         // background color can be set here
3762         QColor c;
3763         if ( Qtx::stringToColor( paramsLst[i], c ) )
3764           setBackgroundColor( c );
3765       }
3766     }
3767     myPlot->replot();
3768   }
3769 #endif
3770 }
3771
3772 /*!
3773   Store visual parameters in xml format.
3774 */
3775 QString Plot2d_ViewFrame::getXmlVisualParameters() {
3776   QString retStr;
3777   QXmlStreamWriter aWriter(&retStr);
3778   aWriter.setAutoFormatting(true);
3779
3780   //Ranges
3781   aWriter.writeStartDocument();
3782   aWriter.writeStartElement("ViewState");
3783   aWriter.writeStartElement("Range");
3784   double xmin, xmax, ymin, ymax, y2min, y2max;
3785   getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
3786   aWriter.writeAttribute("Xmin", QString("").sprintf("%.12e",xmin));
3787   aWriter.writeAttribute("Xmax", QString("").sprintf("%.12e",xmax));
3788   aWriter.writeAttribute("Ymin", QString("").sprintf("%.12e",ymin));
3789   aWriter.writeAttribute("Ymax", QString("").sprintf("%.12e",ymax));
3790   aWriter.writeAttribute("Y2min", QString("").sprintf("%.12e",y2min));
3791   aWriter.writeAttribute("Y2max", QString("").sprintf("%.12e",y2max));
3792   aWriter.writeEndElement();
3793
3794   //Display mode
3795   aWriter.writeStartElement("DisplayMode");
3796   aWriter.writeAttribute("SecondAxis", QString("").sprintf("%d",mySecondY));
3797   aWriter.writeStartElement("ScaleMode");
3798   aWriter.writeAttribute("Xscale", QString("").sprintf("%d",myXMode));
3799   aWriter.writeAttribute("Yscale", QString("").sprintf("%d",myYMode));
3800   aWriter.writeEndElement();
3801   aWriter.writeStartElement("NormalizationMode");
3802   aWriter.writeAttribute("LeftMin", QString("").sprintf("%d",myNormLMin));
3803   aWriter.writeAttribute("LeftMax", QString("").sprintf("%d",myNormLMax));
3804   aWriter.writeAttribute("RightMin", QString("").sprintf("%d",myNormRMin));
3805   aWriter.writeAttribute("RightMax", QString("").sprintf("%d",myNormRMax));
3806   aWriter.writeEndElement();
3807   aWriter.writeEndElement();
3808
3809   //Legend
3810   aWriter.writeStartElement("Legend");
3811   aWriter.writeAttribute("Visibility", QString("").sprintf("%d", myShowLegend));
3812   aWriter.writeStartElement("LegendFont");
3813   aWriter.writeAttribute("Family", myLegendFont.family());
3814   aWriter.writeAttribute("Size", QString("").sprintf("%d",myLegendFont.pointSize()));
3815   aWriter.writeAttribute("Bold", QString("").sprintf("%d",myLegendFont.bold()));
3816   aWriter.writeAttribute("Italic", QString("").sprintf("%d",myLegendFont.italic()));
3817   aWriter.writeAttribute("Underline", QString("").sprintf("%d",myLegendFont.underline()));
3818   aWriter.writeAttribute("R", QString("").sprintf("%d",myLegendColor.red()));
3819   aWriter.writeAttribute("G", QString("").sprintf("%d",myLegendColor.green()));
3820   aWriter.writeAttribute("B", QString("").sprintf("%d",myLegendColor.blue()));
3821   aWriter.writeEndElement();
3822   aWriter.writeEndElement();
3823
3824 #ifndef NO_ANALYTICAL_CURVES
3825   //AnalyticalCurve
3826   aWriter.writeStartElement("AnalyticalCurves");
3827   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
3828   Plot2d_AnalyticalCurve* c = 0;
3829   bool isAuto;
3830   int id = 1;
3831   for( ; it != myAnalyticalCurves.end(); it++) {
3832     c = (*it);
3833     if(!c) continue;
3834     aWriter.writeStartElement(QString("AnalyticalCurve_%1").arg(id));
3835     isAuto = c->isAutoAssign();
3836     aWriter.writeAttribute("Name",c->getName());
3837     aWriter.writeAttribute("IsActive", QString("").sprintf("%d",        c->isActive()));
3838                 aWriter.writeAttribute("Expression", c->getExpression());
3839     aWriter.writeAttribute("NbIntervals", QString("").sprintf("%d",     c->getNbIntervals()));
3840     aWriter.writeAttribute("isAuto", QString("").sprintf("%d",isAuto));
3841     if(!isAuto) {
3842       aWriter.writeAttribute("Marker", QString("").sprintf("%d",(int)c->getMarker()));
3843       aWriter.writeAttribute("Line", QString("").sprintf("%d",(int)c->getLine()));
3844       aWriter.writeAttribute("LineWidth", QString("").sprintf("%d",c->getLineWidth()));
3845       aWriter.writeAttribute("R", QString("").sprintf("%d",c->getColor().red()));
3846       aWriter.writeAttribute("G", QString("").sprintf("%d",c->getColor().green()));
3847       aWriter.writeAttribute("B", QString("").sprintf("%d",c->getColor().blue()));
3848     }
3849     aWriter.writeEndElement();
3850     id++;
3851   }
3852   aWriter.writeEndElement(); //AnalyticalCurve
3853 #endif
3854
3855   //Background
3856   aWriter.writeStartElement(QString("Background"));
3857   aWriter.writeStartElement(QString("BackgroundColor"));
3858   aWriter.writeAttribute("R", QString("").sprintf("%d",backgroundColor().red()));
3859   aWriter.writeAttribute("G", QString("").sprintf("%d",backgroundColor().green()));
3860   aWriter.writeAttribute("B", QString("").sprintf("%d",backgroundColor().blue()));
3861   aWriter.writeEndElement();
3862   aWriter.writeEndElement();
3863
3864
3865   aWriter.writeEndDocument();
3866   return retStr;
3867 }
3868 /*!
3869   Restore visual parameters from xml format.
3870 */
3871 bool Plot2d_ViewFrame::setXmlVisualParameters(const QString& parameters) {
3872   QXmlStreamReader aReader(parameters);
3873   double xmin, xmax, ymin, ymax, y2min, y2max;
3874   bool leftMin,leftMax,rightMin,rightMax;
3875   leftMin = leftMax = rightMin = rightMax = false;
3876   while(!aReader.atEnd()) {
3877       aReader.readNext();
3878       if (aReader.isStartElement()) {
3879       QXmlStreamAttributes aAttr = aReader.attributes();
3880         if(aReader.name() == "Range") {
3881           xmin = aAttr.value("Xmin").toString().toDouble();
3882           xmax = aAttr.value("Xmax").toString().toDouble();
3883           ymin = aAttr.value("Ymin").toString().toDouble();
3884           ymax = aAttr.value("Ymax").toString().toDouble();
3885           y2min = aAttr.value("Y2min").toString().toDouble();
3886           y2max = aAttr.value("Y2max").toString().toDouble();
3887         } else if(aReader.name() == "DisplayMode") {
3888           mySecondY = aAttr.value("Y2max").toString().toDouble();
3889         } else if(aReader.name() == "ScaleMode") {
3890            myXMode = aAttr.value("Xscale").toString().toInt();
3891            myYMode = aAttr.value("Yscale").toString().toInt();
3892         } else if(aReader.name() == "NormalizationMode") {
3893             leftMin = (bool)aAttr.value("LeftMin").toString().toInt();
3894             leftMax = (bool)aAttr.value("LeftMax").toString().toInt();
3895             rightMin = (bool)aAttr.value("RightMin").toString().toInt();
3896             rightMax = (bool)aAttr.value("RightMax").toString().toInt();
3897         } else if(aReader.name() == "Legend") {
3898           myShowLegend = (bool)aAttr.value("Visibility").toString().toInt();
3899         } else if (aReader.name() == "LegendFont") {
3900             myLegendFont = QFont(aAttr.value("Family").toString());
3901             myLegendFont.setPointSize(aAttr.value("Size").toString().toInt());
3902             myLegendFont.setBold((bool)aAttr.value("Bold").toString().toInt());
3903             myLegendFont.setItalic((bool)aAttr.value("Italic").toString().toInt());
3904             myLegendFont.setUnderline((bool)aAttr.value("Underline").toString().toInt());
3905               myLegendColor = QColor(aAttr.value("R").toString().toInt(),
3906                                                      aAttr.value("G").toString().toInt(),
3907                                                      aAttr.value("B").toString().toInt());
3908                   setLegendFontColor( myLegendColor );
3909             setLegendFont(myLegendFont);
3910         } else if(aReader.name().toString().indexOf("AnalyticalCurve_") >= 0) {
3911 #ifndef NO_ANALYTICAL_CURVES
3912             Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
3913                   c->setName(aAttr.value("Name").toString());
3914                   c->setActive((bool)aAttr.value("IsActive").toString().toInt());
3915                   c->setExpression(aAttr.value("Expression").toString());
3916                   c->setNbIntervals(aAttr.value("NbIntervals").toString().toLong());
3917                   c->setAutoAssign((bool)aAttr.value("isAuto").toString().toInt());
3918                   if( !c->isAutoAssign() ) {
3919                     c->setMarker((Plot2d::MarkerType)aAttr.value("Marker").toString().toInt());
3920                     c->setLine((Plot2d::LineType)aAttr.value("Line").toString().toInt());
3921                     c->setLineWidth(aAttr.value("LineWidth").toString().toInt());
3922                     c->setColor(QColor(aAttr.value("R").toString().toInt(),
3923                                                    aAttr.value("G").toString().toInt(),
3924                                                    aAttr.value("B").toString().toInt()));
3925             } else {
3926                     c->autoFill( myPlot );
3927                   }
3928                   addAnalyticalCurve(c);
3929                   updateAnalyticalCurve(c);
3930 #endif
3931         } else if(aReader.name().toString() == "BackgroundColor") {
3932           setBackgroundColor(QColor(aAttr.value("R").toString().toInt(),
3933                                                       aAttr.value("G").toString().toInt(),
3934                                                       aAttr.value("B").toString().toInt()));
3935         }
3936       }
3937   }
3938
3939   if(aReader.hasError())
3940     return false;
3941
3942   if (mySecondY)
3943     setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
3944   setHorScaleMode( myXMode, /*update=*/false );
3945   setVerScaleMode( myYMode, /*update=*/false );
3946   if (mySecondY) {
3947     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
3948     myYDistance2 = yMap2.s2() - yMap2.s1();
3949   }
3950   setNormLMinMode(leftMin);
3951   setNormLMaxMode(leftMax);
3952   setNormRMinMode(rightMin);
3953   setNormRMaxMode(rightMax);
3954
3955   showLegend( myShowLegend, false );
3956
3957   fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3958   return true;
3959 }
3960
3961 /*!
3962   Incremental zooming operation
3963 */
3964 void Plot2d_ViewFrame::incrementalPan( const int incrX, const int incrY ) {
3965   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
3966   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
3967
3968   myPlot->setAxisScale( QwtPlot::yLeft,
3969                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s1() )-incrY ),
3970                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() )-incrY ) );
3971   myPlot->setAxisScale( QwtPlot::xBottom,
3972                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s1() )-incrX ),
3973                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() )-incrX ) );
3974   if (mySecondY) {
3975     QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
3976     myPlot->setAxisScale( QwtPlot::yRight,
3977                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s1() )-incrY ),
3978                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() )-incrY ) );
3979   }
3980   myPlot->replot();
3981 }
3982
3983 /*!
3984   Incremental panning operation
3985 */
3986 void Plot2d_ViewFrame::incrementalZoom( const int incrX, const int incrY ) {
3987   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
3988   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
3989
3990   myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(),
3991                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() ) + incrY ) );
3992   myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(),
3993                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() ) - incrX ) );
3994   if (mySecondY) {
3995     QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
3996     myPlot->setAxisScale( QwtPlot::yRight, y2Map.s1(),
3997                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() ) + incrY ) );
3998   }
3999   myPlot->replot();
4000 }
4001
4002 /*
4003   Update plot item
4004 */
4005 void Plot2d_ViewFrame::updatePlotItem(Plot2d_Object* theObject, QwtPlotItem* theItem) {
4006   theObject->updatePlotItem( theItem );
4007   Plot2d_Curve* c = dynamic_cast<Plot2d_Curve*>(theObject);
4008   QwtPlotCurve* cu = dynamic_cast<QwtPlotCurve*>(theItem);
4009   Plot2d_NormalizeAlgorithm* aNormAlgo;
4010   if(c && cu) {
4011     if(c->getYAxis() == QwtPlot::yRight)
4012       aNormAlgo = myRNormAlgo;
4013     else
4014       aNormAlgo = myLNormAlgo;
4015     if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
4016       AlgoPlot2dOutputData aResultData =  aNormAlgo->getOutput();
4017       AlgoPlot2dOutputData::iterator itTmp = aResultData.find(theObject);
4018       double *xNew,*yNew;
4019       int size = itTmp.value().size();
4020       xNew = new double[size];
4021       yNew = new double[size];
4022       int j = 0;
4023       for (; j < size; ++j) {
4024         xNew[j] = itTmp.value().at(j).first;
4025         yNew[j] = itTmp.value().at(j).second;
4026       }
4027       cu->setSamples(xNew, yNew,j);
4028       delete [] xNew;
4029       delete [] yNew;
4030       if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
4031         QString name = c->getName().isEmpty() ? c->getVerTitle() : c->getName();
4032         name = name + QString("(B=%1, K=%2)");
4033         name = name.arg(aNormAlgo->getBkoef(c)).arg(aNormAlgo->getKkoef(c));
4034         cu->setTitle(name);
4035       }
4036     }
4037   }
4038 }
4039
4040 /**
4041  *
4042  */
4043 QwtPlotCanvas* Plot2d_ViewFrame::getPlotCanvas() const
4044 {
4045   return myPlot ? (QwtPlotCanvas*)myPlot->canvas() : 0;
4046 }
4047
4048 /*!
4049   return closest curve if it exist, else 0
4050 */
4051 Plot2d_Curve* Plot2d_ViewFrame::getClosestCurve( QPoint p, double& distance, int& index ) const
4052 {
4053   CurveDict aCurves = getCurves();
4054   CurveDict::iterator it = aCurves.begin();
4055   Plot2d_Curve* pCurve = 0;
4056   distance = -1.;
4057   for ( ; it != aCurves.end(); it++ ) {
4058     QwtPlotCurve* aCurve = it.key();
4059     if ( !aCurve )
4060       continue;
4061     double d;
4062     int i = aCurve->closestPoint( p, &d );
4063     if ( i > -1 && ( distance < 0 || d < distance ) ) {
4064       pCurve = it.value();
4065       distance = d;
4066       index = i;
4067     }
4068   }
4069   return pCurve;
4070 }
4071
4072 #ifndef NO_ANALYTICAL_CURVES
4073 /*!
4074  \brief  Deselect all analytical curves.
4075 */
4076 void Plot2d_ViewFrame::deselectAnalyticalCurves() {
4077   foreach(Plot2d_AnalyticalCurve* c, myAnalyticalCurves) {
4078    c->setSelected(false);
4079   }
4080 }
4081 #endif
4082
4083 /*!
4084  \brief  Deselect all objects, except analytical curves.
4085 */
4086 void Plot2d_ViewFrame::deselectObjects() {
4087   ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end();
4088   for ( ; it != aLast; it++ ) {
4089           it.value()->setSelected(false);
4090    }
4091 }
4092
4093 #define INCREMENT_FOR_OP 10
4094
4095 /*!
4096   Performs incremental panning to the left
4097 */
4098 void Plot2d_ViewFrame::onPanLeft()
4099 {
4100   this->incrementalPan( -INCREMENT_FOR_OP, 0 );
4101 #ifndef NO_ANALYTICAL_CURVES
4102   updateAnalyticalCurves();
4103 #endif
4104 }
4105
4106 /*!
4107   Performs incremental panning to the right
4108 */
4109 void Plot2d_ViewFrame::onPanRight()
4110 {
4111   this->incrementalPan( INCREMENT_FOR_OP, 0 );
4112 #ifndef NO_ANALYTICAL_CURVES
4113   updateAnalyticalCurves();
4114 #endif
4115 }
4116
4117 /*!
4118   Performs incremental panning to the top
4119 */
4120 void Plot2d_ViewFrame::onPanUp()
4121 {
4122   this->incrementalPan( 0, -INCREMENT_FOR_OP );
4123 #ifndef NO_ANALYTICAL_CURVES
4124   updateAnalyticalCurves();
4125 #endif
4126 }
4127
4128 /*!
4129   Performs incremental panning to the bottom
4130 */
4131 void Plot2d_ViewFrame::onPanDown()
4132 {
4133   this->incrementalPan( 0, INCREMENT_FOR_OP );
4134 #ifndef NO_ANALYTICAL_CURVES
4135   updateAnalyticalCurves();
4136 #endif
4137 }
4138
4139 /*!
4140   Performs incremental zooming in
4141 */
4142 void Plot2d_ViewFrame::onZoomIn()
4143 {
4144   this->incrementalZoom( INCREMENT_FOR_OP, INCREMENT_FOR_OP );
4145 #ifndef NO_ANALYTICAL_CURVES
4146   updateAnalyticalCurves();
4147 #endif
4148 }
4149
4150 /*!
4151   Performs incremental zooming out
4152 */
4153 void Plot2d_ViewFrame::onZoomOut()
4154 {
4155   this->incrementalZoom( -INCREMENT_FOR_OP, -INCREMENT_FOR_OP );
4156 #ifndef NO_ANALYTICAL_CURVES
4157   updateAnalyticalCurves();
4158 #endif
4159 }
4160
4161 /*!
4162   Schedules a FitAll operation by putting it to the application's
4163   event queue. This ensures that other important events (show, resize, etc.)
4164   are processed first.
4165 */
4166 void Plot2d_ViewFrame::customEvent( QEvent* ce )
4167 {
4168   if ( ce->type() == FITALL_EVENT )
4169     fitAll();
4170 }
4171
4172
4173 /*!
4174  * Return Plot2d_Object by the QwtPlotItem
4175  *
4176 */
4177 Plot2d_Object* Plot2d_ViewFrame::getPlotObject( QwtPlotItem* plotItem ) const {
4178
4179   ObjectDict::const_iterator it = myObjects.begin();
4180   for( ; it != myObjects.end(); ++it ) {
4181     if ( it.key() == plotItem ) {
4182       return it.value();
4183     }
4184   }
4185   return 0;
4186 }
4187
4188 Plot2d_ScaleDraw::Plot2d_ScaleDraw( char f, int prec )
4189   : QwtScaleDraw(),
4190     myFormat(f),
4191     myPrecision(prec)
4192 {
4193   invalidateCache();
4194 }
4195
4196 QwtText Plot2d_ScaleDraw::label( double value ) const
4197 {
4198   QwtScaleMap m = scaleMap();
4199   QString str1 = QwtScaleDraw::label( m.s1() ).text();
4200   QString str2 = QwtScaleDraw::label( m.s2() ).text();
4201   if ( str1 == str2 ) {
4202     double aDist = fabs(scaleMap().s2()-scaleMap().s1())/5;
4203     int precision = 0;
4204     while (aDist < 1 ) {
4205       precision++;
4206       aDist *= 10.;
4207     }
4208     if ( precision > 0 && value > 0 )
4209       return QLocale::system().toString( value,'f', precision );
4210   }
4211
4212   return QwtScaleDraw::label( value );
4213 }
4214
4215 Plot2d_YScaleDraw::Plot2d_YScaleDraw()
4216   : QwtScaleDraw()
4217 {
4218 }
4219
4220 QwtText Plot2d_YScaleDraw::label( double value ) const
4221 {
4222   // Axis labels format
4223   QString strD = QString( "%1").arg( value, 10, 'e', 3); // format 10.3e
4224
4225   return QwtText( strD);
4226 }
4227
4228 /* Definition of X axis graduations
4229  */
4230 const QString Plot2d_AxisScaleDraw::DEVICE_FONT = QString("Times");
4231 const int     Plot2d_AxisScaleDraw::DEVICE_FONT_SIZE = 12;
4232 const int     Plot2d_AxisScaleDraw::DEVICE_BY = 40;
4233
4234 Plot2d_AxisScaleDraw::Plot2d_AxisScaleDraw( Plot2d_Plot2d* plot)
4235 : myPlot(plot)
4236 {
4237   myLowerBound = -1;
4238   myUpperBound = -1;
4239   setLabelAlignment(Qt::AlignRight);
4240   setLabelRotation(45.);
4241
4242   applyTicks();
4243
4244   myActivTicksDrawing   = true;
4245   myNumTicksDrawingCall = 1;
4246 }
4247
4248
4249 Plot2d_AxisScaleDraw::~Plot2d_AxisScaleDraw()
4250 {
4251 }
4252
4253
4254 /* Unactivate automatic ticks drawing
4255  */
4256 void Plot2d_AxisScaleDraw::unactivTicksDrawing( int numcall)
4257 {
4258   myActivTicksDrawing   = false;
4259   myNumTicksDrawingCall = numcall;
4260 }
4261
4262
4263 /* Draw X ticks and labels.
4264  * Draw systems names under X axis.
4265  * Overload the same name QwtScaleDraw method.
4266  * (PB: who call automaticaly this method)
4267  */
4268 void Plot2d_AxisScaleDraw::draw( QPainter* painter, const QPalette & palette) const
4269 {
4270   //std::cout << "Plot2d_AxisScaleDraw::draw() : activ= " << myActivTicksDrawing
4271   //                           << "  numcall= " << myNumTicksDrawingCall << std::endl;
4272
4273   if (!myActivTicksDrawing)  return;
4274
4275   //std::cout << "Plot2d_AxisScaleDraw::draw()" << std::endl;
4276
4277   QList<double> major_ticks  = scaleDiv().ticks(QwtScaleDiv::MajorTick);
4278   QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
4279   QList<double> minor_ticks  = scaleDiv().ticks(QwtScaleDiv::MinorTick);
4280
4281   medium_ticks.clear();
4282   minor_ticks.clear();
4283   major_ticks.clear();
4284
4285   major_ticks.append( myTicks);
4286
4287   QwtScaleDiv aScaleDiv = myPlot->axisScaleDiv( QwtPlot::xBottom );
4288   aScaleDiv.setTicks( QwtScaleDiv::MajorTick,  major_ticks );
4289   aScaleDiv.setTicks( QwtScaleDiv::MediumTick, medium_ticks );
4290   aScaleDiv.setTicks( QwtScaleDiv::MinorTick,  minor_ticks );
4291   myPlot->setAxisScaleDiv( QwtPlot::xBottom, aScaleDiv );
4292
4293   QwtScaleDraw *scale = myPlot->axisScaleDraw(QwtPlot::xBottom);
4294   ((Plot2d_AxisScaleDraw*)(scale))->applyTicks();
4295
4296   QwtScaleDraw::draw( painter, palette);
4297
4298   for (int i = 0; i < myTicks.size(); i++)
4299   {
4300       drawLabel( painter, myTicks[i]);
4301   }
4302
4303   //std::cout << "Ok for Plot2d_AxisScaleDraw::draw()" << std::endl;
4304 }
4305
4306
4307 QwtText Plot2d_AxisScaleDraw::label( double value) const
4308 {
4309   if (myLabelX.contains(value))
4310           return myLabelX[value];
4311
4312   return QwtText(QString::number(value, 'f', 1));
4313 }
4314
4315
4316 /* Stock position and label of a X tick
4317  */
4318 void Plot2d_AxisScaleDraw::setLabelTick( double value, QString label, bool isDevice)
4319 {
4320   //qDebug()<< "setLabelTick ( " << value << ","<< label <<" )";
4321   if ( isDevice )
4322   {
4323       // For systems names under X axis
4324       myLabelDevice[value] = label;
4325   }
4326   else
4327   {
4328       // For X axis graduations
4329       myLabelX[value] = label;
4330   }
4331 }
4332
4333
4334 /* Stock ticks positions of a system, and draw them
4335  */
4336 void Plot2d_AxisScaleDraw::setTicks(const QList<double> aTicks)
4337 {
4338   //std::cout << "  Plot2d_AxisScaleDraw::setTicks()" << std::endl;
4339   myTicks = aTicks;
4340
4341   applyTicks();
4342 }
4343
4344
4345 void Plot2d_AxisScaleDraw::setInterval(double lowerBound, double upperBound)
4346 {
4347   myLowerBound = lowerBound;
4348   myUpperBound = upperBound;
4349   myPlot->setAxisScale( QwtPlot::xBottom, myLowerBound, myUpperBound );
4350 }
4351
4352
4353 /* Stock X ticks in drawing zone
4354  */
4355 void Plot2d_AxisScaleDraw::applyTicks()
4356 {
4357   //std::cout << "  Plot2d_AxisScaleDraw::applyTicks()" << std::endl;
4358
4359   QList<double> major_ticks = scaleDiv().ticks(QwtScaleDiv::MajorTick);
4360   QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
4361   QList<double> minor_ticks = scaleDiv().ticks(QwtScaleDiv::MinorTick);
4362
4363   medium_ticks.clear();
4364   minor_ticks.clear();
4365
4366   QwtScaleDiv aQwtScaleDiv = myPlot->axisScaleDiv( QwtPlot::xBottom );
4367   aQwtScaleDiv.setTicks( QwtScaleDiv::MajorTick, myTicks );
4368   aQwtScaleDiv.setTicks( QwtScaleDiv::MediumTick, medium_ticks );
4369   aQwtScaleDiv.setTicks( QwtScaleDiv::MinorTick, minor_ticks );
4370   myPlot->setAxisScaleDiv( QwtPlot::xBottom, aQwtScaleDiv );
4371
4372   QwtScaleDiv* aScaleDiv = (QwtScaleDiv*) &scaleDiv();
4373
4374   aScaleDiv->setTicks(QwtScaleDiv::MajorTick, myTicks);
4375   aScaleDiv->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
4376   aScaleDiv->setTicks(QwtScaleDiv::MinorTick, minor_ticks);
4377
4378   if (myLowerBound != -1 && myUpperBound != -1)
4379               aScaleDiv->setInterval(myLowerBound, myUpperBound);
4380
4381   //for (int i = 0; i < myTicks.size(); i++){
4382   //  QPoint p = labelPosition( i );
4383   //  qDebug() << i<< ") applyTicks -> LABEL" <<p;
4384   //}
4385 }
4386
4387
4388 void Plot2d_AxisScaleDraw::drawLabel( QPainter* painter, double value) const
4389 {
4390   //std::cout << "  Plot2d_AxisScaleDraw::drawLabel( " << value << " ) : "; //<< std::endl;
4391
4392   //qDebug() << "drawLabel  ( " <<value<<" )";
4393   if ( myLabelDevice.contains(value) )
4394   {
4395       QString deviceLabel = myLabelDevice[value];
4396       //
4397       std::string std_label = deviceLabel.toStdString();
4398       //const char *c_label = std_label.c_str();
4399       //std::cout << "    deviceLabel= |" << c_label << "|" << std::endl;
4400
4401       QPointF p = labelPosition( value );
4402       p += QPoint(0, DEVICE_BY);
4403       QFont  prevf = painter->font();
4404       //QColor prevc = (painter->pen()).color();
4405
4406       QFont devicef( DEVICE_FONT, DEVICE_FONT_SIZE, QFont::Bold);
4407       //
4408       //painter->setPen( QColor("blue") );
4409       painter->setFont( devicef );
4410       painter->drawText( p, myLabelDevice[value] );
4411       //painter->setPen( prevc );
4412       painter->setFont( prevf );
4413   }
4414   if ( myLabelX.contains(value) )
4415   {
4416       QString xLabel = myLabelX[value];
4417       //
4418       std::string std_label = xLabel.toStdString();
4419       //const char *c_label = std_label.c_str();
4420       //std::cout << "    xLabel= |" << c_label << "|" << std::endl;
4421
4422       QwtScaleDraw::drawLabel( painter, value );
4423   }
4424 }
4425
4426
4427 void Plot2d_AxisScaleDraw::drawTick( QPainter* painter, double value, int len) const
4428 {
4429   //qDebug() << "drawTick  ( " <<value<<" , "<<len<<" )  " ;
4430   //qDebug() << "myLabelX" << myLabelX;
4431   //
4432   if ( myLabelX.contains(value) )
4433   {
4434       QwtScaleDraw::drawTick( painter, value, len);
4435   }
4436 }
4437
4438
4439 /* Management of tooltips associated with markers for curves points or others points
4440  */
4441 const double Plot2d_QwtPlotPicker::BOUND_HV_SIZE = 0.2;
4442
4443 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int            xAxis,
4444                                             int            yAxis,
4445                                             RubberBand     rubberBand,
4446                                             DisplayMode    trackerMode,
4447                                             QwtPlotCanvas *canvas)
4448 : QwtPlotPicker( xAxis,
4449                  yAxis,
4450                  rubberBand,
4451                  trackerMode,
4452                  canvas)    // of drawing zone QwtPlot
4453 {
4454 }
4455
4456 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int            xAxis,
4457                                             int            yAxis,
4458                                             QwtPlotCanvas *canvas)
4459 : QwtPlotPicker( xAxis,
4460                  yAxis,
4461                  canvas)
4462 {
4463 }
4464
4465 Plot2d_QwtPlotPicker::~Plot2d_QwtPlotPicker()
4466 {
4467 }
4468 // http://www.qtcentre.org/threads/22751-How-do-i-select-a-QwtPlotMarker-using-a-QPlotPicker
4469
4470 /* Return the tooltip associated with a point when the mouse cursor pass near
4471  */
4472 QwtText Plot2d_QwtPlotPicker::trackerText( const QPoint & pos ) const
4473 {
4474   for (QList<QwtPlotMarker* >::const_iterator pMarkerIt = pMarkers.begin();pMarkerIt != pMarkers.end(); ++pMarkerIt )
4475     {
4476       QwtPlotMarker* pMarker = *pMarkerIt;
4477       if ( pMarker != NULL )
4478         {
4479           const QwtSymbol* symb=pMarker->symbol();
4480           const QSize& sz=symb->size();
4481           const QwtScaleMap yMapRef=plot()->canvasMap(QwtPlot::yLeft);
4482           const QwtScaleMap xMap=plot()->canvasMap(pMarker->xAxis());
4483           const QwtScaleMap yMap=plot()->canvasMap(pMarker->yAxis());
4484           QwtDoubleRect  bound0=pMarker->boundingRect();
4485           int x1 = qRound(xMap.transform(bound0.left()));
4486           int x2 = qRound(xMap.transform(bound0.right()));
4487           int y1 = qRound(yMap.transform(bound0.top()));
4488           int y2 = qRound(yMap.transform(bound0.bottom()));
4489           
4490           if ( x2 < x1 )
4491             qSwap(x1, x2);
4492           if ( y2 < y1 )
4493             qSwap(y1, y2);
4494           
4495           QRect bound00=QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
4496           QPoint toto(xMap.transform(pos.x()),yMapRef.transform(pos.y()));
4497           bound00.setX(bound00.x()-sz.width());
4498           bound00.setY(bound00.y()-sz.height());
4499           bound00.setWidth(bound00.width()+sz.width());
4500           bound00.setHeight(bound00.height()+sz.height());
4501           if( bound00.contains(toto) )
4502             {
4503               return pMarkersToolTip[pMarker];
4504             }
4505         }
4506   }
4507   return QwtText();
4508 }