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