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