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