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