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