Salome HOME
INT PAL 0052656: Plot2D Viewer: add possibility to change curve type of analytical...
[modules/gui.git] / src / Plot2d / Plot2d_ViewFrame.cxx
1 // Copyright (C) 2007-2015  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   for(int i=0 ; i < myAnalyticalCurves.count(); i++) {
1992     QwtPlotCurve* aPCurve = dynamic_cast<QwtPlotCurve*>( myAnalyticalCurves[i]->plotItem() );
1993     Plot2d_AnalyticalCurve* aCurve = dynamic_cast<Plot2d_AnalyticalCurve*>( myAnalyticalCurves[i] );
1994     if ( aPCurve && aCurve ) {
1995       setCurveType( aPCurve, myCurveType );
1996     }
1997   }
1998   if ( update )
1999     myPlot->replot();
2000   emit vpCurveChanged();
2001 }
2002
2003 /*!
2004   Gets curve type
2005 */
2006 int Plot2d_ViewFrame::getCurveType() const
2007 {
2008   return myCurveType;
2009 }
2010
2011 /*!
2012   Sets curve title
2013   \param curveKey - curve id
2014   \param title - new title
2015 */
2016 void Plot2d_ViewFrame::setCurveTitle( Plot2d_Curve* curve, const QString& title )
2017 {
2018   setObjectTitle( curve, title );
2019 }
2020
2021 /*!
2022   Sets object title
2023   \param object - object id
2024   \param title - new title
2025 */
2026 void Plot2d_ViewFrame::setObjectTitle( Plot2d_Object* object, const QString& title )
2027 {
2028   if ( object && hasPlotObject( object ) )
2029     getPlotObject( object )->setTitle( title );
2030 }
2031
2032 /*!
2033   Shows/hides legend
2034 */
2035 void Plot2d_ViewFrame::showLegend( bool show, bool update )
2036 {
2037   myShowLegend = show;
2038   if ( myShowLegend ) {
2039     QwtAbstractLegend* absLegend = myPlot->legend();
2040     QwtLegend* legend = 0;
2041     if ( !absLegend ) {
2042       legend = new Plot2d_QwtLegend( myPlot );
2043       legend->setDefaultItemMode(QwtLegendData::Clickable);
2044       connect( legend, SIGNAL( clicked (const QVariant&, int) ),
2045                this, SIGNAL( clicked (const QVariant&, int) ) );
2046       legend->setFrameStyle( QFrame::Box | QFrame::Sunken );
2047     }
2048     else {
2049       legend = dynamic_cast<QwtLegend*>(absLegend);
2050     }
2051     if(legend) {
2052       myPlot->insertLegend( legend );
2053       setLegendPos( myLegendPos );
2054       setLegendFont( myLegendFont );
2055       setLegendFontColor( myLegendColor );
2056     }
2057   }
2058   else
2059     myPlot->insertLegend( 0 );
2060
2061   if( show && update )
2062     updateLegend();
2063
2064   if ( update )
2065     myPlot->replot();
2066 }
2067
2068 /*!
2069   Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
2070 */
2071 void Plot2d_ViewFrame::setLegendPos( int pos )
2072 {
2073   myLegendPos = pos;
2074   QwtAbstractLegend* legend = myPlot->legend();
2075   if ( legend ) {
2076     switch( pos ) {
2077     case 0:
2078       myPlot->insertLegend( legend, QwtPlot::LeftLegend );
2079       break;
2080     case 1:
2081       myPlot->insertLegend( legend, QwtPlot::RightLegend );
2082       break;
2083     case 2:
2084       myPlot->insertLegend( legend, QwtPlot::TopLegend );
2085       break;
2086     case 3:
2087       myPlot->insertLegend( legend, QwtPlot::BottomLegend );
2088       break;
2089     }
2090   }
2091 }
2092
2093 /*!
2094   Gets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
2095 */
2096 int Plot2d_ViewFrame::getLegendPos() const
2097 {
2098   return myLegendPos;
2099 }
2100
2101 /*!
2102   Sets legend symbol type : 0 - marker on line, 1 - marker above line
2103 */
2104 void Plot2d_ViewFrame::setLegendSymbolType( int type )
2105 {
2106   myLegendSymbolType = type;
2107   myPlot->setLegendSymbolType( type );
2108   updateLegend();
2109 }
2110
2111 /*!
2112   Gets legend symbol type : 0 - marker on line, 1 - marker above line
2113 */
2114 int Plot2d_ViewFrame::getLegendSymbolType() const
2115 {
2116   return myLegendSymbolType;
2117 }
2118
2119 /*!
2120   Sets legend font
2121 */
2122 void Plot2d_ViewFrame::setLegendFont( const QFont& fnt )
2123 {
2124   myLegendFont = fnt;
2125   QwtAbstractLegend* legend = myPlot->legend();
2126   if ( legend ) {
2127     legend->setFont(fnt);
2128   }
2129 }
2130
2131 /*!
2132   Gets legend font
2133 */
2134 QFont Plot2d_ViewFrame::getLegendFont() const
2135 {
2136   return myLegendFont;
2137 }
2138
2139 /*!
2140   Sets legend font color
2141 */
2142 void Plot2d_ViewFrame::setLegendFontColor( const QColor& col )
2143 {
2144   myLegendColor = col;
2145   QwtAbstractLegend* legend = myPlot->legend();
2146   if ( legend ) {
2147     QPalette pal = legend->palette();
2148     pal.setColor( QPalette::Text, col );
2149     legend->setPalette( pal );
2150   }
2151 }
2152
2153 /*!
2154   Gets legend font color
2155 */
2156 QColor Plot2d_ViewFrame::getLegendFontColor() const
2157 {
2158   return myLegendColor;
2159 }
2160
2161 /*!
2162   Sets selected legend font color
2163 */
2164 void Plot2d_ViewFrame::setSelectedLegendFontColor( const QColor& col )
2165 {
2166   mySelectedLegendFontColor = col;
2167   Plot2d_Object::setHighlightedLegendTextColor( col );
2168 }
2169
2170 /*!
2171   Gets selected legend font color
2172 */
2173 QColor Plot2d_ViewFrame::getSelectedLegendFontColor() const
2174 {
2175   return mySelectedLegendFontColor;
2176 }
2177
2178 /*!
2179   Sets new marker size
2180 */
2181 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
2182 {
2183   if ( myMarkerSize != size )
2184   {
2185     myMarkerSize = size;
2186     CurveDict aCurves = getCurves();
2187     CurveDict::iterator it = aCurves.begin();
2188     for ( ; it != aCurves.end(); it++ ) {
2189       QwtPlotCurve* crv = it.key();
2190       if ( crv )
2191       {
2192         QwtSymbol* aSymbol = new QwtSymbol( crv->symbol()->style(), crv->symbol()->brush(),
2193                                                     crv->symbol()->pen(), QSize( myMarkerSize, myMarkerSize ) );
2194         crv->setSymbol( aSymbol );
2195         if( it.value() )
2196               it.value()->setMarkerSize( myMarkerSize );
2197       }
2198     }
2199     if ( update )
2200       myPlot->replot();
2201   }
2202 }
2203
2204 /*!
2205   Gets new marker size
2206 */
2207 int Plot2d_ViewFrame::getMarkerSize() const
2208 {
2209   return myMarkerSize;
2210 }
2211
2212 /*!
2213   Sets background color
2214 */
2215 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
2216 {
2217   myBackground = color;
2218   myPlot->canvas()->setPalette( myBackground );
2219   myPlot->setPalette( myBackground );
2220   if ( myPlot->getLegend() ) {
2221     QPalette aPal = myPlot->getLegend()->palette();
2222     for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
2223       aPal.setColor( QPalette::Base, myBackground );
2224       aPal.setColor( QPalette::Background, myBackground );
2225     }
2226     myPlot->getLegend()->setPalette( aPal );
2227     updateLegend();
2228   }
2229   Repaint();
2230 }
2231
2232 /*!
2233   Gets background color
2234 */
2235 QColor Plot2d_ViewFrame::backgroundColor() const
2236 {
2237   return myBackground;
2238 }
2239
2240 /*!
2241   Sets selection color
2242 */
2243 void Plot2d_ViewFrame::setSelectionColor( const QColor& color )
2244 {
2245   mySelectionColor = color;
2246   Plot2d_Object::setSelectionColor( color );
2247 }
2248
2249 /*!
2250   Gets selection color
2251 */
2252 QColor Plot2d_ViewFrame::selectionColor() const
2253 {
2254   return mySelectionColor;
2255 }
2256
2257 /*!
2258   Sets hor.axis grid parameters
2259 */
2260 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
2261          bool xMinorEnabled, const int xMinorMax,
2262          bool update )
2263 {
2264   myXGridMajorEnabled = xMajorEnabled;
2265   myXGridMinorEnabled = xMinorEnabled;
2266   myXGridMaxMajor = xMajorMax;
2267   myXGridMaxMinor = xMinorMax;
2268
2269   myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
2270   myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
2271
2272   QwtPlotGrid* grid = myPlot->grid();
2273   if ( !myPlot->axisScaleDiv( QwtPlot::xBottom ).isEmpty() )
2274     grid->setXDiv( myPlot->axisScaleDiv( QwtPlot::xBottom ) );
2275   grid->enableX( myXGridMajorEnabled );
2276   grid->enableXMin( myXGridMinorEnabled );
2277
2278   if ( update )
2279     myPlot->replot();
2280 }
2281 /*!
2282   Sets ver.axis grid parameters
2283 */
2284 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
2285                                  bool yMinorEnabled, const int yMinorMax,
2286                                  bool y2MajorEnabled, const int y2MajorMax,
2287                                  bool y2MinorEnabled, const int y2MinorMax,
2288                                  bool update )
2289 {
2290   myYGridMajorEnabled = yMajorEnabled;
2291   myYGridMinorEnabled = yMinorEnabled;
2292   myYGridMaxMajor = yMajorMax;
2293   myYGridMaxMinor = yMinorMax;
2294
2295   if (mySecondY) {
2296     myY2GridMajorEnabled = y2MajorEnabled;
2297     myY2GridMinorEnabled = y2MinorEnabled;
2298     myY2GridMaxMajor = y2MajorMax;
2299     myY2GridMaxMinor = y2MinorMax;
2300   }
2301   myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
2302   myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
2303
2304   if (mySecondY) {
2305     myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
2306     myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
2307   }
2308
2309   QwtPlotGrid* grid = myPlot->grid();
2310   if ( !myPlot->axisScaleDiv( QwtPlot::yLeft ).isEmpty() )
2311     grid->setYDiv( myPlot->axisScaleDiv( QwtPlot::yLeft ) );
2312
2313   if (mySecondY) {
2314     if (myYGridMajorEnabled) {
2315       grid->enableY( myYGridMajorEnabled );
2316       grid->enableYMin( myYGridMinorEnabled );
2317     }
2318     else if (myY2GridMajorEnabled) {
2319       if ( !myPlot->axisScaleDiv( QwtPlot::yRight ).isEmpty() )
2320         grid->setYDiv( myPlot->axisScaleDiv( QwtPlot::yRight ) );
2321       grid->enableY( myY2GridMajorEnabled );
2322       grid->enableYMin( myY2GridMinorEnabled );
2323     }
2324     else {
2325       grid->enableY( false );
2326       grid->enableYMin( false );
2327     }
2328   }
2329   else {
2330     grid->enableY( myYGridMajorEnabled );
2331     grid->enableYMin( myYGridMinorEnabled );
2332   }
2333   if ( update )
2334     myPlot->replot();
2335 }
2336
2337 /*!
2338   Sets title for some axis
2339 */
2340 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
2341                                  ObjectType type, bool update )
2342 {
2343   switch (type) {
2344     case MainTitle:
2345       myTitleEnabled = enabled;
2346       myTitle = title;
2347       myPlot->setTitle( myTitleEnabled ? myTitle : QString() );
2348       break;
2349     case XTitle:
2350       myXTitleEnabled = enabled;
2351       myXTitle = title;
2352       myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString() );
2353       break;
2354     case YTitle:
2355       myYTitleEnabled = enabled;
2356       myYTitle = title;
2357       myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString() );
2358       break;
2359     case Y2Title:
2360       myY2TitleEnabled = enabled;
2361       myY2Title = title;
2362       myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString() );
2363       break;
2364     default:
2365       break;
2366   }
2367   if ( update )
2368     myPlot->replot();
2369 }
2370 /*!
2371   Sets title for some axis
2372 */
2373 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
2374 {
2375   QString title = "";
2376   switch (type) {
2377     case MainTitle:
2378       title = myTitle;   break;
2379     case XTitle:
2380       title = myXTitle;  break;
2381     case YTitle:
2382       title = myYTitle;  break;
2383     case Y2Title:
2384       title = myY2Title; break;
2385     default:
2386       break;
2387   }
2388   return title;
2389 }
2390 /*!
2391   Sets font for Plot2d object : title or axis
2392 */
2393 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
2394 {
2395   switch (type) {
2396     case MainTitle:
2397       myPlot->title().setFont(font);
2398       break;
2399     case XTitle:
2400        myPlot->axisTitle(QwtPlot::xBottom).setFont(font); break;
2401     case YTitle:
2402       myPlot->axisTitle(QwtPlot::yLeft).setFont(font);    break;
2403     case Y2Title:
2404       myPlot->axisTitle(QwtPlot::yRight).setFont(font);   break;
2405     case XAxis:
2406       myPlot->setAxisFont(QwtPlot::xBottom, font);        break;
2407     case YAxis:
2408       myPlot->setAxisFont(QwtPlot::yLeft, font);          break;
2409     case Y2Axis:
2410       myPlot->setAxisFont(QwtPlot::yRight, font);         break;
2411   }
2412   if ( update )
2413     myPlot->replot();
2414 }
2415
2416 /*!
2417   Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
2418 */
2419 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
2420 {
2421   if ( myXMode == mode )
2422     return;
2423
2424   // san -- Protection against QwtCurve bug in Qwt 0.4.x:
2425   // it crashes if switched to X/Y logarithmic mode, when one or more points have
2426   // non-positive X/Y coordinate
2427   if ( mode && !isXLogEnabled() ){
2428 #ifndef NO_SUIT
2429     SUIT_MessageBox::warning(this, tr("WRN_WARNING"), tr("WRN_XLOG_NOT_ALLOWED"));
2430 #else
2431     QMessageBox::warning(this, tr("WRN_WARNING"), tr("WRN_XLOG_NOT_ALLOWED"));
2432 #endif
2433     return;
2434   }
2435
2436   myXMode = mode;
2437
2438   // set bounds of logarithmic scale
2439   if( myXMode != 0 ) {
2440     myPlot->setAxisScale( QwtPlot::xBottom, 1.0, 1e5 );
2441     myPlot->updateAxes();
2442   }
2443
2444   myPlot->setLogScale(QwtPlot::xBottom, myXMode != 0);
2445
2446   if ( update )
2447     fitAll();
2448   emit vpModeHorChanged();
2449 }
2450
2451 /*!
2452   Gets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
2453 */
2454 int Plot2d_ViewFrame::getHorScaleMode() const
2455 {
2456   return myXMode;
2457 }
2458
2459 /*!
2460   Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
2461 */
2462 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
2463 {
2464   if ( myYMode == mode )
2465     return;
2466
2467   // san -- Protection against QwtCurve bug in Qwt 0.4.x:
2468   // it crashes if switched to X/Y logarithmic mode, when one or more points have
2469   // non-positive X/Y coordinate
2470   if ( mode && !isYLogEnabled() ){
2471 #ifndef NO_SUIT
2472     SUIT_MessageBox::warning(this, tr("WRN_WARNING"), tr("WRN_YLOG_NOT_ALLOWED"));
2473 #else
2474     QMessageBox::warning(this, tr("WRN_WARNING"), tr("WRN_YLOG_NOT_ALLOWED"));
2475 #endif
2476     return;
2477   }
2478
2479   myYMode = mode;
2480
2481   // set bounds of logarithmic scale
2482   if( myYMode != 0 ){
2483     myPlot->setAxisScale( QwtPlot::yLeft, 1.0, 1e5 );
2484     myPlot->updateAxes();
2485   }
2486
2487   myPlot->setLogScale(QwtPlot::yLeft, myYMode != 0);
2488   if (mySecondY) {
2489     if( myYMode != 0 ){
2490       myPlot->setAxisScale( QwtPlot::yRight, 1.0, 1e5 );
2491       myPlot->updateAxes();
2492     }
2493     myPlot->setLogScale( QwtPlot::yRight, myYMode != 0 );
2494   }
2495
2496   if ( update )
2497     fitAll();
2498   emit vpModeVerChanged();
2499 }
2500
2501 /*!
2502   Gets scale mode for vertical axis: 0 - linear, 1 - logarithmic
2503 */
2504 int Plot2d_ViewFrame::getVerScaleMode() const
2505 {
2506   return myYMode;
2507 }
2508
2509 /*!
2510   Sets normalization mode to the global maximum by left Y axis
2511 */
2512 void Plot2d_ViewFrame::setNormLMaxMode( bool mode, bool update )
2513 {
2514   if ( myNormLMax == mode )
2515     return;
2516
2517   myNormLMax = mode;
2518   processFiltering(true);
2519   if ( update )
2520     fitAll();
2521   emit vpNormLModeChanged();
2522 }
2523
2524 /*!
2525   Gets normalization mode to the global maximum by left Y axis
2526 */
2527 bool Plot2d_ViewFrame::getNormLMaxMode() const
2528 {
2529   return myNormLMax;
2530 }
2531
2532 /*!
2533   Sets normalization mode to the global minimum by left Y axis
2534 */
2535 void Plot2d_ViewFrame::setNormLMinMode( bool mode, bool update )
2536 {
2537   if ( myNormLMin == mode )
2538     return;
2539
2540   myNormLMin = mode;
2541   processFiltering(true);
2542   if ( update )
2543     fitAll();
2544   emit vpNormLModeChanged();
2545 }
2546
2547 /*!
2548   Gets normalization mode to the global minimum by left Y axis
2549 */
2550 bool Plot2d_ViewFrame::getNormLMinMode() const
2551 {
2552   return myNormLMax;
2553 }
2554
2555 /*!
2556   Sets normalization mode to the global maximum by right Y axis
2557 */
2558 void Plot2d_ViewFrame::setNormRMaxMode( bool mode, bool update )
2559 {
2560   if ( myNormRMax == mode )
2561     return;
2562
2563   myNormRMax = mode;
2564   processFiltering(true);
2565   if ( update )
2566     fitAll();
2567   emit vpNormRModeChanged();
2568 }
2569
2570 /*!
2571   Gets normalization mode to the global maximum by right Y axis
2572 */
2573 bool Plot2d_ViewFrame::getNormRMaxMode() const
2574 {
2575   return myNormRMax;
2576 }
2577
2578 /*!
2579   Sets normalization mode to the global minimum by right Y axis
2580 */
2581 void Plot2d_ViewFrame::setNormRMinMode( bool mode, bool update )
2582 {
2583   if ( myNormRMin == mode )
2584     return;
2585
2586   myNormRMin = mode;
2587   processFiltering(true);
2588   if ( update )
2589     fitAll();
2590   emit vpNormRModeChanged();
2591 }
2592
2593 /*!
2594   Gets normalization mode to the global minimum by right Y axis
2595 */
2596 bool Plot2d_ViewFrame::getNormRMinMode() const
2597 {
2598   return myNormRMax;
2599 }
2600
2601 /*!
2602   Return, scale mode for horizontal axis
2603 */
2604 bool Plot2d_ViewFrame::isModeHorLinear()
2605 {
2606   return (myXMode == 0 ? true : false);
2607 }
2608
2609 /*!
2610   Return, scale mode for vertical axis
2611 */
2612 bool Plot2d_ViewFrame::isModeVerLinear()
2613 {
2614   return (myYMode == 0 ? true : false);
2615 }
2616
2617 /*!
2618   Return \c True if curves are normalize to the global maximum by left Y axis
2619 */
2620 bool Plot2d_ViewFrame::isNormLMaxMode()
2621 {
2622   return (myNormLMax ? true : false);
2623 }
2624
2625 /*!
2626   Return \c True if curves are normalize to the global minimum by left Y axis
2627 */
2628 bool Plot2d_ViewFrame::isNormLMinMode()
2629 {
2630   return (myNormLMin ? true : false);
2631 }
2632
2633 /*!
2634   Return \c True if curves are normalize to the global maximum by right Y axis
2635 */
2636 bool Plot2d_ViewFrame::isNormRMaxMode()
2637 {
2638   return (myNormRMax ? true : false);
2639 }
2640
2641 /*!
2642   Return \c True if curves are normalize to the global minimum by right Y axis
2643 */
2644 bool Plot2d_ViewFrame::isNormRMinMode()
2645 {
2646   return (myNormRMin ? true : false);
2647 }
2648
2649 /*!
2650   Return \c True if legend is shown
2651 */
2652 bool Plot2d_ViewFrame::isLegendShow() const
2653 {
2654   return myShowLegend;
2655 }
2656
2657 /*!
2658   Slot, called when user presses mouse button
2659 */
2660 void Plot2d_ViewFrame::plotMousePressed( const QMouseEvent& me )
2661 {
2662 #ifndef NO_SUIT
2663   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2664   if (aParent)
2665      aParent->putInfo(getInfo(me.pos()));
2666 #endif
2667   if ( myOperation == NoOpId )
2668     myOperation = testOperation( me );
2669   if ( myOperation != NoOpId ) {
2670     myPnt = me.pos();
2671     if ( myOperation == GlPanId ) {
2672       myPlot->setAxisScale( QwtPlot::yLeft,
2673           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2,
2674           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2 );
2675       myPlot->setAxisScale( QwtPlot::xBottom,
2676           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
2677           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
2678       if (mySecondY)
2679         myPlot->setAxisScale( QwtPlot::yRight,
2680           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2,
2681           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2 );
2682       myPlot->replot();
2683     }
2684   }
2685   else {
2686     int btn = me.button() | me.modifiers();
2687     if (btn == Qt::RightButton) {
2688       QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
2689                                             me.pos(), me.button(), me.buttons(), me.modifiers() );
2690       // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
2691       parent()->eventFilter(this, aEvent);
2692     }
2693   }
2694   setFocus();
2695 }
2696 /*!
2697   Slot, called when user moves mouse
2698 */
2699 bool Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
2700 {
2701   int    dx = me.pos().x() - myPnt.x();
2702   int    dy = me.pos().y() - myPnt.y();
2703
2704   bool aRes = false;
2705   if ( myOperation != NoOpId) {
2706     if ( myOperation == ZoomId ) {
2707       this->incrementalZoom( dx, dy );
2708       myPnt = me.pos();
2709       aRes = true;
2710     }
2711     else if ( myOperation == PanId ) {
2712       this->incrementalPan( dx, dy );
2713       myPnt = me.pos();
2714       aRes = true;
2715     }
2716   }
2717   else {
2718 #ifndef NO_SUIT
2719      Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2720      if (aParent)
2721        aParent->putInfo(getInfo(me.pos()));
2722 #endif
2723   }
2724   return aRes;
2725 }
2726 /*!
2727   Slot, called when user releases mouse
2728 */
2729 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
2730 {
2731   if ( myOperation == NoOpId && me.button() == Qt::RightButton && me.modifiers() != Qt::ControlModifier )
2732   {
2733     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
2734                               me.pos(), me.globalPos() );
2735     emit contextMenuRequested( &aEvent );
2736   }
2737   else {
2738 #ifndef NO_ANALYTICAL_CURVES
2739     updateAnalyticalCurves();
2740 #endif
2741   }
2742   myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
2743   myPlot->defaultPicker();
2744
2745 #ifndef NO_SUIT
2746   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2747    if (aParent)
2748      aParent->putInfo(tr("INF_READY"));
2749 #endif
2750   myOperation = NoOpId;
2751 }
2752 /*!
2753   Slot, called when user wheeling mouse
2754 */
2755 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
2756 {
2757   QwtPlotLayout* pl = myPlot->plotLayout();
2758
2759   // compute zooming factor
2760   double aDelta = event->delta();
2761   double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
2762
2763   bool scaleXBottom = pl->scaleRect(QwtPlot::xBottom).contains( event->pos() ) ||
2764                       pl->canvasRect().contains( event->pos() );
2765   bool scaleYLeft   = pl->scaleRect(QwtPlot::yLeft).contains( event->pos() ) ||
2766                       pl->canvasRect().contains( event->pos() );
2767   bool scaleYRight  = mySecondY && ( pl->scaleRect(QwtPlot::yRight).contains( event->pos() ) ||
2768                                      pl->canvasRect().contains( event->pos() ) );
2769
2770   // scale x bottom axis
2771   if ( scaleXBottom ) {
2772     QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
2773     if ( xMap.s2() - xMap.s1() > 1.0e-12 || aScale > 1 )
2774       myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(), xMap.s1() + aScale*(xMap.s2() - xMap.s1()) );
2775   }
2776
2777   // scale y left axis
2778   if ( scaleYLeft ) {
2779     QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
2780     if ( yMap.s2() - yMap.s1() > 1.0e-12 || aScale > 1 )
2781       myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(), yMap.s1() + aScale*(yMap.s2() - yMap.s1()) );
2782   }
2783
2784   // scale y right axis (note: mySecondY value is checked above)
2785   if ( scaleYRight ) {
2786     QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yRight );
2787     if ( yMap.s2() - yMap.s1() > 10e-12 || aScale > 1 )
2788       myPlot->setAxisScale( QwtPlot::yRight, yMap.s1(), yMap.s1() + aScale*(yMap.s2() - yMap.s1()) );
2789   }
2790
2791   // redraw
2792   myPlot->replot();
2793   // update zoomer
2794   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
2795   // store current mouse position
2796   myPnt = event->pos();
2797 #ifndef NO_ANALYTICAL_CURVES
2798   // update analytical curves
2799   updateAnalyticalCurves();
2800 #endif
2801 }
2802
2803 /*!
2804   Returns qwt plot curve if it is existed in map of curves and 0 otherwise
2805 */
2806 QwtPlotCurve* Plot2d_ViewFrame::getPlotCurve( Plot2d_Curve* curve ) const
2807 {
2808   return dynamic_cast<QwtPlotCurve*>( getPlotObject( curve ) );
2809 }
2810 /*!
2811   Returns true if qwt plot curve is existed in map of curves and false otherwise
2812 */
2813 bool Plot2d_ViewFrame::hasPlotCurve( Plot2d_Curve* curve ) const
2814 {
2815   return hasPlotObject( curve );
2816 }
2817
2818 /*!
2819   Returns qwt plot curve if it is existed in map of curves and 0 otherwise
2820 */
2821 QwtPlotItem* Plot2d_ViewFrame::getPlotObject( Plot2d_Object* object ) const
2822 {
2823   ObjectDict::const_iterator it = myObjects.begin();
2824   for ( ; it != myObjects.end(); it++ ) {
2825     if ( it.value() == object )
2826       return it.key();
2827   }
2828   return 0;
2829 }
2830 /*!
2831   Returns true if qwt plot curve is existed in map of curves and false otherwise
2832 */
2833 bool Plot2d_ViewFrame::hasPlotObject( Plot2d_Object* object ) const
2834 {
2835   ObjectDict::const_iterator it = myObjects.begin();
2836   for ( ; it != myObjects.end(); it++ ) {
2837     if ( it.value() == object )
2838       return true;
2839   }
2840   return false;
2841 }
2842
2843 /*!
2844   Sets curve type
2845 */
2846 void Plot2d_ViewFrame::setCurveType( QwtPlotCurve* curve, int curveType )
2847 {
2848   if ( !curve )
2849     return;
2850   if ( myCurveType == 0 )
2851     curve->setStyle( QwtPlotCurve::Dots );//QwtCurve::NoCurve
2852   else if ( myCurveType == 1 ) {
2853     curve->setStyle( QwtPlotCurve::Lines );
2854     curve->setCurveAttribute( QwtPlotCurve::Fitted, false );
2855   }
2856   else if ( myCurveType == 2 ) {
2857     curve->setStyle( QwtPlotCurve::Lines );
2858     QwtSplineCurveFitter* fitter = new QwtSplineCurveFitter();
2859     fitter->setSplineSize( 250 );
2860     curve->setCurveAttribute( QwtPlotCurve::Fitted, true );
2861     curve->setCurveFitter( fitter );
2862   }
2863 }
2864
2865 /*!
2866   View operations : Pan view
2867 */
2868 void Plot2d_ViewFrame::onViewPan()
2869 {
2870   // reset the previous operation
2871   myPlot->defaultPicker();
2872
2873   QCursor panCursor (Qt::SizeAllCursor);
2874   myPlot->canvas()->setCursor( panCursor );
2875   myOperation = PanId;
2876 }
2877 /*!
2878   View operations : Zoom view
2879 */
2880 void Plot2d_ViewFrame::onViewZoom()
2881 {
2882   // reset the previous operation
2883   myPlot->defaultPicker();
2884
2885   QPixmap zoomPixmap (imageZoomCursor);
2886   QCursor zoomCursor (zoomPixmap);
2887   myPlot->canvas()->setCursor( zoomCursor );
2888   myOperation = ZoomId;
2889 }
2890 /*!
2891   View operations : Fit All
2892 */
2893 void Plot2d_ViewFrame::onViewFitAll()
2894 {
2895   fitAll();
2896
2897   // reset the previous operation
2898   myPlot->defaultPicker();
2899   myPlot->canvas()->setCursor( QCursor(Qt::CrossCursor) );
2900   myOperation = NoOpId;
2901 }
2902 /*!
2903   View operations : Fit Area
2904 */
2905 void Plot2d_ViewFrame::onViewFitArea()
2906 {
2907   myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
2908   myOperation = FitAreaId;
2909   myPlot->setPickerMousePattern( Qt::LeftButton );
2910 }
2911 /*!
2912   View operations : Global panning
2913 */
2914 void Plot2d_ViewFrame::onViewGlobalPan()
2915 {
2916   // reset the previous operation
2917   myPlot->defaultPicker();
2918
2919   QPixmap globalPanPixmap (imageCrossCursor);
2920   QCursor glPanCursor (globalPanPixmap);
2921   myPlot->canvas()->setCursor( glPanCursor );
2922   myPlot->setLogScale(QwtPlot::xBottom, false);
2923   myPlot->setLogScale(QwtPlot::yLeft, false);
2924   if (mySecondY)
2925     myPlot->setLogScale(QwtPlot::yRight, false);
2926   myPlot->replot();
2927   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
2928   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
2929
2930   myXDistance = xMap.s2() - xMap.s1();
2931   myYDistance = yMap.s2() - yMap.s1();
2932
2933   if (mySecondY) {
2934     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
2935     myYDistance2 = yMap2.s2() - yMap2.s1();
2936   }
2937   // don't make fit all
2938   // fitAll();
2939   myOperation = GlPanId;
2940 }
2941
2942 /*!
2943   Precaution for logarithmic X scale
2944 */
2945 bool Plot2d_ViewFrame::isXLogEnabled() const
2946 {
2947   bool allPositive = true;
2948   ObjectDict::const_iterator it = myObjects.begin();
2949   for ( ; allPositive && it != myObjects.end(); it++ )
2950     allPositive = ( it.value()->getMinX() > 0. );
2951   return allPositive;
2952 }
2953
2954 /*!
2955   Precaution for logarithmic Y scale
2956 */
2957 bool Plot2d_ViewFrame::isYLogEnabled() const
2958 {
2959   bool allPositive = true;
2960   ObjectDict::const_iterator it = myObjects.begin();
2961   for ( ; allPositive && it != myObjects.end(); it++ )
2962     allPositive = ( it.value()->getMinY() > 0. );
2963   return allPositive;
2964 }
2965
2966 /**
2967  *
2968  */
2969 void Plot2d_ViewFrame::setEnableAxis( QwtPlot::Axis theAxis, bool isEnable )
2970 {
2971   if ( myPlot->axisEnabled( theAxis ) == isEnable )
2972     return;
2973   myPlot->enableAxis( theAxis, isEnable );
2974   if ( theAxis == QwtPlot::yRight )
2975     mySecondY = isEnable;
2976 }
2977
2978 class Plot2d_QwtPlotZoomer : public QwtPlotZoomer
2979 {
2980 public:
2981   Plot2d_QwtPlotZoomer( int xAxis, int yAxis, QWidget* canvas )
2982   : QwtPlotZoomer( xAxis, yAxis, canvas )
2983   {
2984     qApp->installEventFilter( this );
2985     // now picker working after only a button pick.
2986     // after click on button FitArea in toolbar of the ViewFrame.
2987   };
2988   ~Plot2d_QwtPlotZoomer() {};
2989 };
2990
2991 /*!
2992   Constructor
2993 */
2994 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
2995   : QwtPlot( parent ),
2996     myPicker( 0 )
2997 {
2998   // Create alternative scales
2999   setAxisScaleDraw( QwtPlot::yLeft,   new Plot2d_ScaleDraw() );
3000   setAxisScaleDraw( QwtPlot::xBottom, new Plot2d_ScaleDraw() );
3001   setAxisScaleDraw( QwtPlot::yRight,  new Plot2d_ScaleDraw() );
3002
3003   myPlotZoomer = new Plot2d_QwtPlotZoomer( QwtPlot::xBottom, QwtPlot::yLeft, canvas() );
3004   myPlotZoomer->setTrackerMode( QwtPicker::AlwaysOff );
3005   myPlotZoomer->setRubberBand( QwtPicker::RectRubberBand );
3006   myPlotZoomer->setRubberBandPen( QColor( Qt::green ) );
3007
3008   defaultPicker();
3009
3010   // auto scaling by default
3011   setAxisAutoScale( QwtPlot::yLeft );
3012   setAxisAutoScale( QwtPlot::yRight );
3013   setAxisAutoScale( QwtPlot::xBottom );
3014
3015   myScaleDraw = NULL;
3016 // grid
3017   myGrid = new QwtPlotGrid();
3018   QPen aMajPen = myGrid->majorPen();
3019   aMajPen.setStyle( Qt::DashLine );
3020   myGrid->setPen( aMajPen );
3021
3022   myGrid->enableX( false );
3023   myGrid->enableXMin( false );
3024   myGrid->enableY( false );
3025   myGrid->enableYMin( false );
3026
3027   myGrid->attach( this );
3028
3029   setMouseTracking( false );
3030   canvas()->setMouseTracking( true );
3031
3032   myPlotZoomer->setEnabled( true );
3033   myPlotZoomer->setZoomBase();
3034
3035   setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
3036 }
3037
3038 Plot2d_Plot2d::~Plot2d_Plot2d()
3039 {
3040 }
3041
3042 /*!
3043   \set axis scale engine - linear or log10
3044 */
3045 void Plot2d_Plot2d::setLogScale( int axisId, bool log10 )
3046 {
3047   if ( log10 )
3048     setAxisScaleEngine( axisId, new QwtLogScaleEngine() );
3049   else
3050     setAxisScaleEngine( axisId, new QwtLinearScaleEngine() );
3051 }
3052
3053 /*!
3054   Recalculates and redraws Plot 2d view
3055 */
3056 void Plot2d_Plot2d::replot()
3057 {
3058   // the following code is intended to enable only axes
3059   // that are really used by displayed objects
3060   bool enableXBottom = false, enableXTop   = false;
3061   bool enableYLeft   = false, enableYRight = false;
3062   const QwtPlotItemList& items = itemList();
3063   QwtPlotItemIterator it;
3064   for ( it = items.begin(); it != items.end(); it++ ) {
3065     QwtPlotItem* item = *it;
3066     if ( item ) {
3067       enableXBottom |= item->xAxis() == QwtPlot::xBottom;
3068       enableXTop    |= item->xAxis() == QwtPlot::xTop;
3069       enableYLeft   |= item->yAxis() == QwtPlot::yLeft;
3070       enableYRight  |= item->yAxis() == QwtPlot::yRight;
3071     }
3072   }
3073   enableAxis( QwtPlot::xBottom, enableXBottom );
3074   enableAxis( QwtPlot::xTop,    enableXTop );
3075   enableAxis( QwtPlot::yLeft,   enableYLeft );
3076   enableAxis( QwtPlot::yRight,  enableYRight );
3077
3078   updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
3079   QwtPlot::replot();
3080 }
3081
3082 /*!
3083   Get legend
3084 */
3085 QwtAbstractLegend* Plot2d_Plot2d::getLegend()
3086 {
3087 #if QWT_VERSION < 0x040200
3088   return d_legend;
3089 #else
3090   return legend(); /* mpv: porting to the Qwt 4.2.0 */
3091 #endif
3092 }
3093
3094 /*!
3095   \return the recommended size for the widget
3096 */
3097 QSize Plot2d_Plot2d::sizeHint() const
3098 {
3099   return QwtPlot::minimumSizeHint();
3100 }
3101
3102 /*!
3103   return minimum size for qwt plot
3104 */
3105 QSize Plot2d_Plot2d::minimumSizeHint() const
3106 {
3107   return QSize( 0, 0 );
3108 //  QSize aSize = QwtPlot::minimumSizeHint();
3109 //  return QSize(aSize.width()*3/4, aSize.height());
3110 }
3111
3112 void Plot2d_Plot2d::defaultPicker()
3113 {
3114   myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1,
3115                                  Qt::RightButton, Qt::ControlModifier ); // zooming button
3116   for ( int i = QwtEventPattern::MouseSelect2; i < QwtEventPattern::MouseSelect6; i++ )
3117     myPlotZoomer->setMousePattern( (QwtEventPattern::MousePatternCode)i, Qt::NoButton,
3118                                        Qt::NoModifier );
3119 }
3120
3121 void Plot2d_Plot2d::setPickerMousePattern( int button, int state )
3122 {
3123   myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1, (Qt::MouseButton)button,
3124                                          (Qt::KeyboardModifiers)state );
3125 }
3126
3127 /*!
3128  * Set the point picker associated with a graphic view
3129  */
3130 void Plot2d_Plot2d::setPicker( Plot2d_QwtPlotPicker *picker)
3131 {
3132   myPicker = picker;
3133 }
3134
3135 /*!
3136  * Create marker and tooltip associed with a point
3137  */
3138 QwtPlotMarker* Plot2d_Plot2d::createMarkerAndTooltip( QwtSymbol* symbol,
3139                                                       double    X,
3140                                                       double    Y,
3141                                                       QString & tooltip,
3142                                                       Plot2d_QwtPlotPicker *picker)
3143 {
3144   QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
3145
3146   aPlotMarker->setSymbol( symbol );  // symbol must have a color
3147   aPlotMarker->setLabelAlignment( Qt::AlignTop);
3148   aPlotMarker->setXValue(X);
3149   aPlotMarker->setYValue(Y);
3150   //
3151   aPlotMarker->attach(this);
3152
3153   // Associate a tooltip with the point's marker
3154   // PB: how to obtain a tooltip with a rectangular frame ?
3155   //QwtText tooltip ("X=" + QString::number(X) + " Y=" + QString::number(Y) );
3156
3157   QwtText text (tooltip);
3158   //QColor tooltipColor( 245, 222, 179);            // Wheat  -RGB (0 a 255)
3159   QColor tooltipColor( 253, 245, 230);            // OldLace
3160   text.setBackgroundBrush( QBrush(tooltipColor)); //, Qt::SolidPattern));
3161   //
3162   if ( picker ) {
3163     picker->pMarkers.append( aPlotMarker);
3164     picker->pMarkersToolTip[ aPlotMarker] = text;
3165   }
3166   return aPlotMarker;
3167 }
3168
3169 QwtPlotGrid* Plot2d_Plot2d::grid() const
3170 {
3171   return myGrid;
3172 };
3173
3174 QwtPlotZoomer* Plot2d_Plot2d::zoomer() const
3175 {
3176   return myPlotZoomer;
3177 }
3178
3179 /*!
3180   Updates identifiers of Y axis type in the legend.
3181 */
3182 void Plot2d_Plot2d::updateYAxisIdentifiers()
3183 {
3184   bool enableYLeft = false, enableYRight = false;
3185   const QwtPlotItemList& items = itemList();
3186   QwtPlotItemIterator it;
3187   for ( it = items.begin(); it != items.end(); it++ ) {
3188     QwtPlotItem* item = *it;
3189     if ( item ) {
3190       enableYLeft  |= item->yAxis() == QwtPlot::yLeft;
3191       enableYRight |= item->yAxis() == QwtPlot::yRight;
3192     }
3193   }
3194
3195   // if several curves are attached to different axes
3196   // display corresponding identifiers in the legend,
3197   // otherwise hide them
3198   for ( it = items.begin(); it != items.end(); it++ ) {
3199     QwtPlotItem* item = *it;
3200     if ( Plot2d_QwtPlotCurve* aPCurve = dynamic_cast<Plot2d_QwtPlotCurve*>( item ) )
3201       aPCurve->setYAxisIdentifierEnabled( enableYLeft && enableYRight );
3202     if ( item && item->isVisible() && legend() )
3203       item->updateLegend( item, item->legendData() );
3204   }
3205 }
3206
3207 // Methods to manage axis graduations
3208
3209 /* Create definition and graduations of axes
3210  */
3211 void Plot2d_Plot2d::createAxisScaleDraw()
3212 {
3213   myScaleDraw = new Plot2d_AxisScaleDraw( this);
3214 }
3215
3216
3217 /* Stock X axis's ticks in the drawing zone
3218 */
3219 void Plot2d_Plot2d::applyTicks()
3220 {
3221   myScaleDraw->applyTicks();
3222 }
3223
3224
3225 /* Unactivate automatic ticks drawing (call to method Plot2d_AxisScaleDraw::draw() )
3226  * Parameters :
3227  * - number call to ticks drawing (for information) : numcall
3228  */
3229 void Plot2d_Plot2d::unactivAxisScaleDraw( int numcall)
3230 {
3231   // Memorize X axis (myScaleDraw already exists) in the drawing zone
3232   //setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw);  // heritage of QwtPlot
3233
3234   myScaleDraw->unactivTicksDrawing( numcall);
3235 }
3236
3237
3238 /* Draw ticks and labels on X axis of the drawing zone
3239  * Draw systems' names under the X axis of the drawing zone
3240  * Draw vertical segments between X axis's intervals of the systems
3241  * Parameters :
3242  * - left and right margins for ticks : XLeftMargin, XRightMargin
3243  * - for each named system :
3244  *     positions and labels for ticks on X axis : devicesPosLabelTicks
3245  *
3246  * The true drawings will be realized by the method Plot2d_AxisScaleDraw::draw()
3247  * PB: who call il ?
3248  */
3249 void Plot2d_Plot2d::displayXTicksAndLabels(
3250                       double XLeftMargin, double XRightMargin,
3251                       const QList< QPair< QString, QMap<double, QString> > > & devicesPosLabelTicks)
3252                       //                    name        position  label
3253                       //                   system         tick    tick
3254 {
3255   //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
3256
3257   int nbDevices = devicesPosLabelTicks.size();
3258   //
3259   //std::cout << "  Nombre de systemes = " << nbDevices << std::endl;
3260   if (nbDevices == 0)  return;
3261
3262   // For drawing systems' names, their positions must be in the allTicks list
3263   // (cf class Plot2d_AxisScaleDraw)
3264
3265   // Liste of ticks' positions and systems' names
3266   QList<double> allTicks;
3267
3268   double devXmin, devXmax;  // X interval of a system
3269   double gapXmin, gapXmax;  // X interval between two systems
3270   double devLabPos;         // Label's position of a system
3271   double segmentPos;  // Position of the vertical segment between current system and the next
3272
3273   // 1)- Search for the system whose X interval is the most to the left
3274
3275   int ileftDev = 0;
3276   double XminMin = 1.e+12;
3277
3278   if (nbDevices > 1)
3279   {
3280       for (int idev=0; idev < nbDevices; idev++)
3281       {
3282           QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
3283
3284           QString deviceLabel = paire.first;
3285
3286           // Ticks' map of the system
3287           QMap<double,QString> devPosLabelTicks = paire.second;
3288
3289           QList<double> posTicks = devPosLabelTicks.keys();
3290
3291           // List's items increasing sorting
3292           qSort( posTicks.begin(), posTicks.end() );  // iterators
3293
3294           // X interval for the system
3295           devXmin = posTicks.first();
3296           devXmax = posTicks.last();
3297
3298           if (devXmin < XminMin)
3299           {
3300               XminMin = devXmin;
3301               ileftDev = idev;
3302           }
3303       }
3304   }
3305
3306   // 2)- Ticks, systems' names, verticals segments
3307
3308   for (int idev=0; idev < nbDevices; idev++)
3309   {
3310       QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
3311
3312       QString deviceLabel = paire.first;
3313
3314       std::string std_label = deviceLabel.toStdString();
3315       //const char *c_label = std_label.c_str();
3316       //std::cout << "  deviceLabel: |" << c_label << "|" << std::endl;
3317
3318       // Ticks' map of the system
3319       QMap<double,QString> devPosLabelTicks = paire.second;
3320
3321       int nbTicks = devPosLabelTicks.size();
3322
3323       QList<double> posTicks = devPosLabelTicks.keys();
3324
3325       // List's items increasing sorting
3326       qSort( posTicks.begin(), posTicks.end() );  // iterators
3327
3328       // X interval for the system
3329       devXmin = posTicks.first();
3330       devXmax = posTicks.last();
3331
3332       // Stock ticks' positions and labels on X axis
3333       double pos;
3334       QString label;
3335       //
3336       for (int itic=0; itic < nbTicks; itic++)
3337       {
3338           pos   = posTicks.at(itic);
3339           label = devPosLabelTicks[pos];
3340
3341           myScaleDraw->setLabelTick( pos, label, false);
3342
3343           std::string std_label = label.toStdString();
3344           //const char *c_label = std_label.c_str();
3345           //std::cout << "    tick " << itic << " : pos= " << pos << ", label= |" << c_label << "|" << std::endl;
3346       }
3347       allTicks.append( posTicks);
3348
3349       // Compute the position of the system's label
3350       if (idev == ileftDev)
3351       {
3352           devLabPos = devXmin + 0.25*(devXmax - devXmin);
3353       }
3354       else
3355       {
3356           devLabPos = devXmin + 0.50*(devXmax - devXmin);
3357       }
3358       allTicks.append( devLabPos);
3359
3360       // Stock position and name of the system under X axis
3361       myScaleDraw->setLabelTick( devLabPos, deviceLabel, true);
3362
3363       if (idev > 0)
3364       {
3365           // Create the vertical segment between the current system and the next
3366           gapXmax = devXmin;
3367           segmentPos = gapXmin + 0.5*(gapXmax - gapXmin);
3368
3369           createSeparationLine( segmentPos);
3370       }
3371       gapXmin = devXmax;
3372   }
3373
3374   // List's items increasing sorting
3375   qSort( allTicks.begin(), allTicks.end() );  // iterators
3376
3377   // Stock the interval of X's values
3378   double lowerBound = allTicks.first() - XLeftMargin;
3379   double upperBound = allTicks.last() + XRightMargin;
3380   myScaleDraw->setInterval( lowerBound, upperBound);
3381
3382   // For each system, stock the position of the X's ticks and those of the name
3383   myScaleDraw->setTicks( allTicks);  // do not draw the ticks
3384
3385   // Memorize the X axis in the drawing zone
3386   setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw);  // heritage of QwtPlot
3387
3388   //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
3389 }
3390
3391
3392 /* Create vertical segment between two curves
3393  */
3394 void Plot2d_Plot2d::createSeparationLine( double Xpos)
3395 {
3396   QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
3397
3398   aPlotMarker->setLineStyle( QwtPlotMarker::VLine);
3399   aPlotMarker->setXValue( Xpos);
3400   aPlotMarker->setLinePen( QPen(Qt::black));
3401   aPlotMarker->attach(this);  // Add to drawing zone
3402   // To deallocate in EraseAll()
3403   mySeparationLineList.append( aPlotMarker);
3404 }
3405
3406 void Plot2d_Plot2d::clearSeparationLineList()
3407 {
3408   mySeparationLineList.clear();
3409 }
3410
3411 /* Set type of legend symbol
3412  */
3413 void Plot2d_Plot2d::setLegendSymbolType( const int type )
3414 {
3415   myLegendSymbolType = type;
3416 }
3417
3418 /* Get type of legend symbol
3419  */
3420 int Plot2d_Plot2d::getLegendSymbolType()
3421 {
3422   return myLegendSymbolType;
3423 }
3424
3425 /*!
3426   Creates presentation of object
3427   Default implementation is empty
3428 */
3429 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
3430 {
3431   return 0;
3432 }
3433
3434 /*!
3435   Copies preferences from other viewframe
3436   \param vf - other view frame
3437 */
3438 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
3439 {
3440   if( !vf )
3441     return;
3442
3443   myCurveType = vf->myCurveType;
3444   myShowLegend = vf->myShowLegend;
3445   myLegendPos = vf->myLegendPos;
3446   myLegendSymbolType = vf->myLegendSymbolType;
3447   myLegendFont = vf->myLegendFont;
3448   mySelectedLegendFontColor = vf->mySelectedLegendFontColor;
3449   myMarkerSize = vf->myMarkerSize;
3450   myBackground = vf->myBackground;
3451   mySelectionColor = vf->mySelectionColor;
3452   myTitle = vf->myTitle;
3453   myXTitle = vf->myXTitle;
3454   myYTitle = vf->myYTitle;
3455   myY2Title = vf->myY2Title;
3456   myTitleEnabled = vf->myTitleEnabled;
3457   myXTitleEnabled = vf->myXTitleEnabled;
3458   myYTitleEnabled = vf->myYTitleEnabled;
3459   myY2TitleEnabled = vf->myY2TitleEnabled;
3460   myXGridMajorEnabled = vf->myXGridMajorEnabled;
3461   myYGridMajorEnabled = vf->myYGridMajorEnabled;
3462   myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
3463   myXGridMinorEnabled = vf->myXGridMinorEnabled;
3464   myYGridMinorEnabled = vf->myYGridMinorEnabled;
3465   myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
3466   myXGridMaxMajor = vf->myXGridMaxMajor;
3467   myYGridMaxMajor = vf->myYGridMaxMajor;
3468   myY2GridMaxMajor = vf->myY2GridMaxMajor;
3469   myXGridMaxMinor = vf->myXGridMaxMinor;
3470   myYGridMaxMinor = vf->myYGridMaxMinor;
3471   myY2GridMaxMinor = vf->myY2GridMaxMinor;
3472   myXMode = vf->myXMode;
3473   myYMode = vf->myYMode;
3474   mySecondY = vf->mySecondY;
3475 }
3476
3477 /*!
3478   Updates titles according to curves
3479 */
3480 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
3481 void Plot2d_ViewFrame::updateTitles( const bool update )
3482 {
3483   ObjectDict::iterator it = myObjects.begin();
3484   QStringList aXTitles;
3485   QStringList aYTitles;
3486   QStringList aY2Titles;
3487   QStringList aXUnits;
3488   QStringList aYUnits;
3489   QStringList aY2Units;
3490   QStringList aTables;
3491   int i = 0;
3492
3493   Plot2d_Object* anObject;
3494   for ( ; it != myObjects.end(); it++ ) {
3495     // collect titles and units from all curves...
3496     anObject = it.value();
3497     QString xTitle = anObject->getHorTitle().trimmed();
3498     QString yTitle = anObject->getVerTitle().trimmed();
3499     QString xUnits = anObject->getHorUnits().trimmed();
3500     QString yUnits = anObject->getVerUnits().trimmed();
3501
3502     if ( anObject->getYAxis() == QwtPlot::yLeft ) {
3503       if ( !aYTitles.contains( yTitle ) )
3504         aYTitles.append( yTitle );
3505       if ( !aYUnits.contains( yUnits ) )
3506         aYUnits.append( yUnits );
3507     }
3508     else {
3509       if ( !aY2Titles.contains( yTitle ) )
3510         aY2Titles.append( yTitle );
3511       if ( !aY2Units.contains( yUnits ) )
3512         aY2Units.append( yUnits );
3513     }
3514     if ( !aXTitles.contains( xTitle ) )
3515       aXTitles.append( xTitle );
3516     if ( !aXUnits.contains( xUnits ) )
3517       aXUnits.append( xUnits );
3518
3519     QString aName = anObject->getTableTitle();
3520     if( !aName.isEmpty() && !aTables.contains( aName ) )
3521       aTables.append( aName );
3522     ++i;
3523   }
3524   // ... and update plot 2d view
3525   QString xUnits, yUnits, y2Units;
3526   if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
3527     xUnits = BRACKETIZE( aXUnits[0] );
3528   if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
3529     yUnits = BRACKETIZE( aYUnits[0] );
3530   if ( aY2Units.count() == 1 && !aY2Units[0].isEmpty())
3531     y2Units = BRACKETIZE( aY2Units[0] );
3532   QString xTitle, yTitle, y2Title;
3533   if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
3534     xTitle = aXTitles[0];
3535   if ( aYTitles.count() == 1 )
3536     yTitle = aYTitles[0];
3537   if ( mySecondY && aY2Titles.count() == 1 )
3538     y2Title = aY2Titles[0];
3539
3540   if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
3541     xTitle += " ";
3542   if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
3543     yTitle += " ";
3544   if ( !y2Title.isEmpty() && !y2Units.isEmpty() )
3545     y2Title += " ";
3546
3547   setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, false );
3548   setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, false );
3549   if ( mySecondY )
3550     setTitle( myY2TitleEnabled, y2Title + y2Units, Y2Title, false );
3551   if( myIsDefTitle )
3552     setTitle( true, aTables.join("; "), MainTitle, false );
3553
3554   // do update if necessary
3555   if ( update ) {
3556     myPlot->replot();
3557   }
3558 }
3559
3560 /*!
3561   Outputs content of viewframe to file
3562   \param file - file name
3563   \param format - file format
3564 */
3565 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
3566 {
3567 #ifdef WIN32
3568   return false;
3569
3570 #else
3571   bool res = false;
3572   if( myPlot )
3573   {
3574     QPaintDevice* pd = 0;
3575     if( format=="PS" || format=="EPS" || format == "PDF" )
3576     {
3577       QPrinter* pr = new QPrinter( QPrinter::HighResolution );
3578       if(format == "PDF")
3579           pr->setOutputFormat(QPrinter::PdfFormat);
3580       pr->setPageSize( QPrinter::A4 );
3581       pr->setOutputFileName( file );
3582       pr->setPrintProgram( "" );
3583       pd = pr;
3584     }
3585
3586     if( pd )
3587     {
3588       QwtPlotRenderer* pr = new QwtPlotRenderer();
3589       pr->renderTo( myPlot, *pd );
3590       res = true;
3591       delete pd;
3592     }
3593   }
3594   return res;
3595 #endif
3596
3597 }
3598
3599 /**
3600  * Print Plot2d window
3601  */
3602 void Plot2d_ViewFrame::printPlot( QPainter* p, const QRectF& rect) const
3603 {
3604   QwtPlotRenderer* pr = new QwtPlotRenderer();
3605   pr->render( myPlot, p, rect );
3606 }
3607
3608 /*!
3609   \return string with all visual parameters
3610 */
3611 QString Plot2d_ViewFrame::getVisualParameters()
3612 {
3613
3614   return getXmlVisualParameters();
3615
3616   /*
3617   RNV: Old case, now visual parameters stored in the XML format.
3618   //
3619   double xmin, xmax, ymin, ymax, y2min, y2max;
3620   getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
3621   QString retStr;
3622   //Store font in the visual parameters string as:
3623   //
3624   // ...*FontFamily|FontSize|B|I|U|r:g:b*...
3625
3626   retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%s|%i|%i|%i|%i|%i:%i:%i",
3627                   myXMode, myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max,
3628                   qPrintable(myLegendFont.family()), myLegendFont.pointSize(),myLegendFont.bold(),
3629                   myLegendFont.italic(), myLegendFont.underline(),myLegendColor.red(),
3630                   myLegendColor.green(), myLegendColor.blue());
3631
3632  //store all Analytical curves
3633   //store each curve in the following format
3634   // ...*Name|isActive|Expresion|NbInervals|isAutoAssign[|MarkerType|LineType|LineWidth|r:g:b]
3635   // parameters in the [ ] is optional in case if isAutoAssign == true
3636   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
3637   Plot2d_AnalyticalCurve* c = 0;
3638   bool isAuto;
3639   for( ; it != myAnalyticalCurves.end(); it++) {
3640     c = (*it);
3641     if(!c) continue;
3642     QString curveString("");
3643     isAuto = c->isAutoAssign();
3644     curveString.sprintf("*%s|%i|%s|%i|%i",
3645                         qPrintable(c->getName()),
3646                         c->isActive(),
3647                         qPrintable(c->getExpression()),
3648                         c->getNbIntervals(),
3649                         isAuto);
3650
3651     retStr+=curveString;
3652     if(!isAuto) {
3653       QString optCurveString("");
3654       optCurveString.sprintf("|%i|%i|%i|%i:%i:%i",
3655                              (int)c->getMarker(),
3656                              (int)c->getLine(),
3657                              c->getLineWidth(),
3658                              c->getColor().red(),
3659                              c->getColor().green(),
3660                              c->getColor().blue());
3661       retStr+=optCurveString;
3662     }
3663   }
3664   retStr += QString( "*%1" ).arg( Qtx::colorToString( backgroundColor() ) );
3665   return retStr;
3666   */
3667 }
3668
3669 /*!
3670   Restores all visual parameters from string
3671 */
3672 void Plot2d_ViewFrame::setVisualParameters( const QString& parameters )
3673 {
3674   if(setXmlVisualParameters(parameters))
3675     return;
3676
3677   double xmin, xmax;
3678   QStringList paramsLst = parameters.split( '*' );
3679   if ( paramsLst.size() >= 9 ) {
3680     double ymin, ymax, y2min, y2max;
3681     myXMode = paramsLst[0].toInt();
3682     myYMode = paramsLst[1].toInt();
3683     mySecondY = (bool)paramsLst[2].toInt();
3684     xmin =  paramsLst[3].toDouble();
3685     xmax =  paramsLst[4].toDouble();
3686     ymin =  paramsLst[5].toDouble();
3687     ymax =  paramsLst[6].toDouble();
3688     y2min = paramsLst[7].toDouble();
3689     y2max = paramsLst[8].toDouble();
3690
3691     if (mySecondY)
3692       setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
3693     setHorScaleMode( myXMode, /*update=*/false );
3694     setVerScaleMode( myYMode, /*update=*/false );
3695
3696     if (mySecondY) {
3697       QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
3698       myYDistance2 = yMap2.s2() - yMap2.s1();
3699     }
3700
3701     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3702     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3703   }
3704
3705   //Restore legend font
3706   if(paramsLst.size() >= 10) {
3707     QStringList fontList = paramsLst[9].split( '|' );
3708     if(fontList.size() == 6) {
3709       myLegendFont = QFont(fontList[0]);
3710       myLegendFont.setPointSize(fontList[1].toInt());
3711       myLegendFont.setBold(fontList[2].toInt());
3712       myLegendFont.setItalic(fontList[3].toInt());
3713       myLegendFont.setUnderline(fontList[4].toInt());
3714       QStringList colorList = fontList[5].split(":");
3715       setLegendFont( myLegendFont );
3716
3717       if(colorList.size() == 3) {
3718               myLegendColor = QColor(colorList[0].toInt(),
3719                                                  colorList[1].toInt(),
3720                                                  colorList[2].toInt());
3721               setLegendFontColor( myLegendColor );
3722       }
3723     }
3724   }
3725
3726 #ifndef NO_ANALYTICAL_CURVES
3727   //Restore all Analytical curves
3728   int startCurveIndex = 10;
3729   if( paramsLst.size() >= startCurveIndex+1 ) {
3730     for( int i=startCurveIndex; i<paramsLst.size() ; i++ ) {
3731       QStringList curveLst = paramsLst[i].split("|");
3732       if( curveLst.size() == 5 || curveLst.size() == 9 ) {
3733         Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
3734         c->setName(curveLst[0]);
3735         c->setActive(curveLst[1].toInt());
3736         c->setExpression(curveLst[2]);
3737         c->setNbIntervals(curveLst[3].toLong());
3738         c->setAutoAssign(curveLst[4].toInt());
3739         if( !c->isAutoAssign() ) {
3740           c->setMarker((Plot2d::MarkerType)curveLst[5].toInt());
3741           c->setLine((Plot2d::LineType)curveLst[6].toInt());
3742           c->setLineWidth(curveLst[7].toInt());
3743           QStringList colorList = curveLst[8].split(":");
3744           if( colorList.size() == 3 ) {
3745             c->setColor(QColor(colorList[0].toInt(),
3746                                colorList[1].toInt(),
3747                                colorList[2].toInt()));
3748           }
3749         } else {
3750           c->autoFill( myPlot );
3751         }
3752         addAnalyticalCurve(c);
3753         updateAnalyticalCurve(c);
3754       }
3755       else if( curveLst.size() == 1 ) {
3756         // background color can be set here
3757         QColor c;
3758         if ( Qtx::stringToColor( paramsLst[i], c ) )
3759           setBackgroundColor( c );
3760       }
3761     }
3762     myPlot->replot();
3763   }
3764 #endif
3765 }
3766
3767 /*!
3768   Store visual parameters in xml format.
3769 */
3770 QString Plot2d_ViewFrame::getXmlVisualParameters() {
3771   QString retStr;
3772   QXmlStreamWriter aWriter(&retStr);
3773   aWriter.setAutoFormatting(true);
3774
3775   //Ranges
3776   aWriter.writeStartDocument();
3777   aWriter.writeStartElement("ViewState");
3778   aWriter.writeStartElement("Range");
3779   double xmin, xmax, ymin, ymax, y2min, y2max;
3780   getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
3781   aWriter.writeAttribute("Xmin", QString("").sprintf("%.12e",xmin));
3782   aWriter.writeAttribute("Xmax", QString("").sprintf("%.12e",xmax));
3783   aWriter.writeAttribute("Ymin", QString("").sprintf("%.12e",ymin));
3784   aWriter.writeAttribute("Ymax", QString("").sprintf("%.12e",ymax));
3785   aWriter.writeAttribute("Y2min", QString("").sprintf("%.12e",y2min));
3786   aWriter.writeAttribute("Y2max", QString("").sprintf("%.12e",y2max));
3787   aWriter.writeEndElement();
3788
3789   //Display mode
3790   aWriter.writeStartElement("DisplayMode");
3791   aWriter.writeAttribute("SecondAxis", QString("").sprintf("%d",mySecondY));
3792   aWriter.writeStartElement("ScaleMode");
3793   aWriter.writeAttribute("Xscale", QString("").sprintf("%d",myXMode));
3794   aWriter.writeAttribute("Yscale", QString("").sprintf("%d",myYMode));
3795   aWriter.writeEndElement();
3796   aWriter.writeStartElement("NormalizationMode");
3797   aWriter.writeAttribute("LeftMin", QString("").sprintf("%d",myNormLMin));
3798   aWriter.writeAttribute("LeftMax", QString("").sprintf("%d",myNormLMax));
3799   aWriter.writeAttribute("RightMin", QString("").sprintf("%d",myNormRMin));
3800   aWriter.writeAttribute("RightMax", QString("").sprintf("%d",myNormRMax));
3801   aWriter.writeEndElement();
3802   aWriter.writeEndElement();
3803
3804   //Legend
3805   aWriter.writeStartElement("Legend");
3806   aWriter.writeAttribute("Visibility", QString("").sprintf("%d", myShowLegend));
3807   aWriter.writeStartElement("LegendFont");
3808   aWriter.writeAttribute("Family", myLegendFont.family());
3809   aWriter.writeAttribute("Size", QString("").sprintf("%d",myLegendFont.pointSize()));
3810   aWriter.writeAttribute("Bold", QString("").sprintf("%d",myLegendFont.bold()));
3811   aWriter.writeAttribute("Italic", QString("").sprintf("%d",myLegendFont.italic()));
3812   aWriter.writeAttribute("Underline", QString("").sprintf("%d",myLegendFont.underline()));
3813   aWriter.writeAttribute("R", QString("").sprintf("%d",myLegendColor.red()));
3814   aWriter.writeAttribute("G", QString("").sprintf("%d",myLegendColor.green()));
3815   aWriter.writeAttribute("B", QString("").sprintf("%d",myLegendColor.blue()));
3816   aWriter.writeEndElement();
3817   aWriter.writeEndElement();
3818
3819 #ifndef NO_ANALYTICAL_CURVES
3820   //AnalyticalCurve
3821   aWriter.writeStartElement("AnalyticalCurves");
3822   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
3823   Plot2d_AnalyticalCurve* c = 0;
3824   bool isAuto;
3825   int id = 1;
3826   for( ; it != myAnalyticalCurves.end(); it++) {
3827     c = (*it);
3828     if(!c) continue;
3829     aWriter.writeStartElement(QString("AnalyticalCurve_%1").arg(id));
3830     isAuto = c->isAutoAssign();
3831     aWriter.writeAttribute("Name",c->getName());
3832     aWriter.writeAttribute("IsActive", QString("").sprintf("%d",        c->isActive()));
3833                 aWriter.writeAttribute("Expression", c->getExpression());
3834     aWriter.writeAttribute("NbIntervals", QString("").sprintf("%d",     c->getNbIntervals()));
3835     aWriter.writeAttribute("isAuto", QString("").sprintf("%d",isAuto));
3836     if(!isAuto) {
3837       aWriter.writeAttribute("Marker", QString("").sprintf("%d",(int)c->getMarker()));
3838       aWriter.writeAttribute("Line", QString("").sprintf("%d",(int)c->getLine()));
3839       aWriter.writeAttribute("LineWidth", QString("").sprintf("%d",c->getLineWidth()));
3840       aWriter.writeAttribute("R", QString("").sprintf("%d",c->getColor().red()));
3841       aWriter.writeAttribute("G", QString("").sprintf("%d",c->getColor().green()));
3842       aWriter.writeAttribute("B", QString("").sprintf("%d",c->getColor().blue()));
3843     }
3844     aWriter.writeEndElement();
3845     id++;
3846   }
3847   aWriter.writeEndElement(); //AnalyticalCurve
3848 #endif
3849
3850   //Background
3851   aWriter.writeStartElement(QString("Background"));
3852   aWriter.writeStartElement(QString("BackgroundColor"));
3853   aWriter.writeAttribute("R", QString("").sprintf("%d",backgroundColor().red()));
3854   aWriter.writeAttribute("G", QString("").sprintf("%d",backgroundColor().green()));
3855   aWriter.writeAttribute("B", QString("").sprintf("%d",backgroundColor().blue()));
3856   aWriter.writeEndElement();
3857   aWriter.writeEndElement();
3858
3859
3860   aWriter.writeEndDocument();
3861   return retStr;
3862 }
3863 /*!
3864   Restore visual parameters from xml format.
3865 */
3866 bool Plot2d_ViewFrame::setXmlVisualParameters(const QString& parameters) {
3867   QXmlStreamReader aReader(parameters);
3868   double xmin, xmax, ymin, ymax, y2min, y2max;
3869   bool leftMin,leftMax,rightMin,rightMax;
3870   leftMin = leftMax = rightMin = rightMax = false;
3871   while(!aReader.atEnd()) {
3872       aReader.readNext();
3873       if (aReader.isStartElement()) {
3874       QXmlStreamAttributes aAttr = aReader.attributes();
3875         if(aReader.name() == "Range") {
3876           xmin = aAttr.value("Xmin").toString().toDouble();
3877           xmax = aAttr.value("Xmax").toString().toDouble();
3878           ymin = aAttr.value("Ymin").toString().toDouble();
3879           ymax = aAttr.value("Ymax").toString().toDouble();
3880           y2min = aAttr.value("Y2min").toString().toDouble();
3881           y2max = aAttr.value("Y2max").toString().toDouble();
3882         } else if(aReader.name() == "DisplayMode") {
3883           mySecondY = aAttr.value("Y2max").toString().toDouble();
3884         } else if(aReader.name() == "ScaleMode") {
3885            myXMode = aAttr.value("Xscale").toString().toInt();
3886            myYMode = aAttr.value("Yscale").toString().toInt();
3887         } else if(aReader.name() == "NormalizationMode") {
3888             leftMin = (bool)aAttr.value("LeftMin").toString().toInt();
3889             leftMax = (bool)aAttr.value("LeftMax").toString().toInt();
3890             rightMin = (bool)aAttr.value("RightMin").toString().toInt();
3891             rightMax = (bool)aAttr.value("RightMax").toString().toInt();
3892         } else if(aReader.name() == "Legend") {
3893           myShowLegend = (bool)aAttr.value("Visibility").toString().toInt();
3894         } else if (aReader.name() == "LegendFont") {
3895             myLegendFont = QFont(aAttr.value("Family").toString());
3896             myLegendFont.setPointSize(aAttr.value("Size").toString().toInt());
3897             myLegendFont.setBold((bool)aAttr.value("Bold").toString().toInt());
3898             myLegendFont.setItalic((bool)aAttr.value("Italic").toString().toInt());
3899             myLegendFont.setUnderline((bool)aAttr.value("Underline").toString().toInt());
3900               myLegendColor = QColor(aAttr.value("R").toString().toInt(),
3901                                                      aAttr.value("G").toString().toInt(),
3902                                                      aAttr.value("B").toString().toInt());
3903                   setLegendFontColor( myLegendColor );
3904             setLegendFont(myLegendFont);
3905         } else if(aReader.name().toString().indexOf("AnalyticalCurve_") >= 0) {
3906 #ifndef NO_ANALYTICAL_CURVES
3907             Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
3908                   c->setName(aAttr.value("Name").toString());
3909                   c->setActive((bool)aAttr.value("IsActive").toString().toInt());
3910                   c->setExpression(aAttr.value("Expression").toString());
3911                   c->setNbIntervals(aAttr.value("NbIntervals").toString().toLong());
3912                   c->setAutoAssign((bool)aAttr.value("isAuto").toString().toInt());
3913                   if( !c->isAutoAssign() ) {
3914                     c->setMarker((Plot2d::MarkerType)aAttr.value("Marker").toString().toInt());
3915                     c->setLine((Plot2d::LineType)aAttr.value("Line").toString().toInt());
3916                     c->setLineWidth(aAttr.value("LineWidth").toString().toInt());
3917                     c->setColor(QColor(aAttr.value("R").toString().toInt(),
3918                                                    aAttr.value("G").toString().toInt(),
3919                                                    aAttr.value("B").toString().toInt()));
3920             } else {
3921                     c->autoFill( myPlot );
3922                   }
3923                   addAnalyticalCurve(c);
3924                   updateAnalyticalCurve(c);
3925 #endif
3926         } else if(aReader.name().toString() == "BackgroundColor") {
3927           setBackgroundColor(QColor(aAttr.value("R").toString().toInt(),
3928                                                       aAttr.value("G").toString().toInt(),
3929                                                       aAttr.value("B").toString().toInt()));
3930         }
3931       }
3932   }
3933
3934   if(aReader.hasError())
3935     return false;
3936
3937   if (mySecondY)
3938     setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
3939   setHorScaleMode( myXMode, /*update=*/false );
3940   setVerScaleMode( myYMode, /*update=*/false );
3941   if (mySecondY) {
3942     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
3943     myYDistance2 = yMap2.s2() - yMap2.s1();
3944   }
3945   setNormLMinMode(leftMin);
3946   setNormLMaxMode(leftMax);
3947   setNormRMinMode(rightMin);
3948   setNormRMaxMode(rightMax);
3949
3950   showLegend( myShowLegend, false );
3951
3952   fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3953   return true;
3954 }
3955
3956 /*!
3957   Incremental zooming operation
3958 */
3959 void Plot2d_ViewFrame::incrementalPan( const int incrX, const int incrY ) {
3960   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
3961   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
3962
3963   myPlot->setAxisScale( QwtPlot::yLeft,
3964                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s1() )-incrY ),
3965                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() )-incrY ) );
3966   myPlot->setAxisScale( QwtPlot::xBottom,
3967                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s1() )-incrX ),
3968                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() )-incrX ) );
3969   if (mySecondY) {
3970     QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
3971     myPlot->setAxisScale( QwtPlot::yRight,
3972                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s1() )-incrY ),
3973                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() )-incrY ) );
3974   }
3975   myPlot->replot();
3976 }
3977
3978 /*!
3979   Incremental panning operation
3980 */
3981 void Plot2d_ViewFrame::incrementalZoom( const int incrX, const int incrY ) {
3982   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
3983   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
3984
3985   myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(),
3986                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() ) + incrY ) );
3987   myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(),
3988                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() ) - incrX ) );
3989   if (mySecondY) {
3990     QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
3991     myPlot->setAxisScale( QwtPlot::yRight, y2Map.s1(),
3992                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() ) + incrY ) );
3993   }
3994   myPlot->replot();
3995 }
3996
3997 /*
3998   Update plot item
3999 */
4000 void Plot2d_ViewFrame::updatePlotItem(Plot2d_Object* theObject, QwtPlotItem* theItem) {
4001   theObject->updatePlotItem( theItem );
4002   Plot2d_Curve* c = dynamic_cast<Plot2d_Curve*>(theObject);
4003   QwtPlotCurve* cu = dynamic_cast<QwtPlotCurve*>(theItem);
4004   Plot2d_NormalizeAlgorithm* aNormAlgo;
4005   if(c && cu) {
4006     if(c->getYAxis() == QwtPlot::yRight)
4007       aNormAlgo = myRNormAlgo;
4008     else
4009       aNormAlgo = myLNormAlgo;
4010     if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
4011       AlgoPlot2dOutputData aResultData =  aNormAlgo->getOutput();
4012       AlgoPlot2dOutputData::iterator itTmp = aResultData.find(theObject);
4013       double *xNew,*yNew;
4014       int size = itTmp.value().size();
4015       xNew = new double[size];
4016       yNew = new double[size];
4017       int j = 0;
4018       for (; j < size; ++j) {
4019         xNew[j] = itTmp.value().at(j).first;
4020         yNew[j] = itTmp.value().at(j).second;
4021       }
4022       cu->setSamples(xNew, yNew,j);
4023       delete [] xNew;
4024       delete [] yNew;
4025       if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
4026         QString name = c->getName().isEmpty() ? c->getVerTitle() : c->getName();
4027         name = name + QString("(B=%1, K=%2)");
4028         name = name.arg(aNormAlgo->getBkoef(c)).arg(aNormAlgo->getKkoef(c));
4029         cu->setTitle(name);
4030       }
4031     }
4032   }
4033 }
4034
4035 /**
4036  *
4037  */
4038 QwtPlotCanvas* Plot2d_ViewFrame::getPlotCanvas() const
4039 {
4040   return myPlot ? (QwtPlotCanvas*)myPlot->canvas() : 0;
4041 }
4042
4043 /*!
4044   return closest curve if it exist, else 0
4045 */
4046 Plot2d_Curve* Plot2d_ViewFrame::getClosestCurve( QPoint p, double& distance, int& index ) const
4047 {
4048   CurveDict aCurves = getCurves();
4049   CurveDict::iterator it = aCurves.begin();
4050   Plot2d_Curve* pCurve = 0;
4051   distance = -1.;
4052   for ( ; it != aCurves.end(); it++ ) {
4053     QwtPlotCurve* aCurve = it.key();
4054     if ( !aCurve )
4055       continue;
4056     double d;
4057     int i = aCurve->closestPoint( p, &d );
4058     if ( i > -1 && ( distance < 0 || d < distance ) ) {
4059       pCurve = it.value();
4060       distance = d;
4061       index = i;
4062     }
4063   }
4064   return pCurve;
4065 }
4066
4067 #ifndef NO_ANALYTICAL_CURVES
4068 /*!
4069  \brief  Deselect all analytical curves.
4070 */
4071 void Plot2d_ViewFrame::deselectAnalyticalCurves() {
4072   foreach(Plot2d_AnalyticalCurve* c, myAnalyticalCurves) {
4073    c->setSelected(false);
4074   }
4075 }
4076 #endif
4077
4078 /*!
4079  \brief  Deselect all objects, except analytical curves.
4080 */
4081 void Plot2d_ViewFrame::deselectObjects() {
4082   ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end();
4083   for ( ; it != aLast; it++ ) {
4084           it.value()->setSelected(false);
4085    }
4086 }
4087
4088 #define INCREMENT_FOR_OP 10
4089
4090 /*!
4091   Performs incremental panning to the left
4092 */
4093 void Plot2d_ViewFrame::onPanLeft()
4094 {
4095   this->incrementalPan( -INCREMENT_FOR_OP, 0 );
4096 #ifndef NO_ANALYTICAL_CURVES
4097   updateAnalyticalCurves();
4098 #endif
4099 }
4100
4101 /*!
4102   Performs incremental panning to the right
4103 */
4104 void Plot2d_ViewFrame::onPanRight()
4105 {
4106   this->incrementalPan( INCREMENT_FOR_OP, 0 );
4107 #ifndef NO_ANALYTICAL_CURVES
4108   updateAnalyticalCurves();
4109 #endif
4110 }
4111
4112 /*!
4113   Performs incremental panning to the top
4114 */
4115 void Plot2d_ViewFrame::onPanUp()
4116 {
4117   this->incrementalPan( 0, -INCREMENT_FOR_OP );
4118 #ifndef NO_ANALYTICAL_CURVES
4119   updateAnalyticalCurves();
4120 #endif
4121 }
4122
4123 /*!
4124   Performs incremental panning to the bottom
4125 */
4126 void Plot2d_ViewFrame::onPanDown()
4127 {
4128   this->incrementalPan( 0, INCREMENT_FOR_OP );
4129 #ifndef NO_ANALYTICAL_CURVES
4130   updateAnalyticalCurves();
4131 #endif
4132 }
4133
4134 /*!
4135   Performs incremental zooming in
4136 */
4137 void Plot2d_ViewFrame::onZoomIn()
4138 {
4139   this->incrementalZoom( INCREMENT_FOR_OP, INCREMENT_FOR_OP );
4140 #ifndef NO_ANALYTICAL_CURVES
4141   updateAnalyticalCurves();
4142 #endif
4143 }
4144
4145 /*!
4146   Performs incremental zooming out
4147 */
4148 void Plot2d_ViewFrame::onZoomOut()
4149 {
4150   this->incrementalZoom( -INCREMENT_FOR_OP, -INCREMENT_FOR_OP );
4151 #ifndef NO_ANALYTICAL_CURVES
4152   updateAnalyticalCurves();
4153 #endif
4154 }
4155
4156 /*!
4157   Schedules a FitAll operation by putting it to the application's
4158   event queue. This ensures that other important events (show, resize, etc.)
4159   are processed first.
4160 */
4161 void Plot2d_ViewFrame::customEvent( QEvent* ce )
4162 {
4163   if ( ce->type() == FITALL_EVENT )
4164     fitAll();
4165 }
4166
4167
4168 /*!
4169  * Return Plot2d_Object by the QwtPlotItem
4170  *
4171 */
4172 Plot2d_Object* Plot2d_ViewFrame::getPlotObject( QwtPlotItem* plotItem ) const {
4173
4174   ObjectDict::const_iterator it = myObjects.begin();
4175   for( ; it != myObjects.end(); ++it ) {
4176     if ( it.key() == plotItem ) {
4177       return it.value();
4178     }
4179   }
4180   return 0;
4181 }
4182
4183 Plot2d_ScaleDraw::Plot2d_ScaleDraw( char f, int prec )
4184   : QwtScaleDraw(),
4185     myFormat(f),
4186     myPrecision(prec)
4187 {
4188   invalidateCache();
4189 }
4190
4191 QwtText Plot2d_ScaleDraw::label( double value ) const
4192 {
4193   QwtScaleMap m = scaleMap();
4194   QString str1 = QwtScaleDraw::label( m.s1() ).text();
4195   QString str2 = QwtScaleDraw::label( m.s2() ).text();
4196   if ( str1 == str2 ) {
4197     double aDist = fabs(scaleMap().s2()-scaleMap().s1())/5;
4198     int precision = 0;
4199     while (aDist < 1 ) {
4200       precision++;
4201       aDist *= 10.;
4202     }
4203     if ( precision > 0 && value > 0 )
4204       return QLocale::system().toString( value,'f', precision );
4205   }
4206
4207   return QwtScaleDraw::label( value );
4208 }
4209
4210 Plot2d_YScaleDraw::Plot2d_YScaleDraw()
4211   : QwtScaleDraw()
4212 {
4213 }
4214
4215 QwtText Plot2d_YScaleDraw::label( double value ) const
4216 {
4217   // Axis labels format
4218   QString strD = QString( "%1").arg( value, 10, 'e', 3); // format 10.3e
4219
4220   return QwtText( strD);
4221 }
4222
4223 /* Definition of X axis graduations
4224  */
4225 const QString Plot2d_AxisScaleDraw::DEVICE_FONT = QString("Times");
4226 const int     Plot2d_AxisScaleDraw::DEVICE_FONT_SIZE = 12;
4227 const int     Plot2d_AxisScaleDraw::DEVICE_BY = 40;
4228
4229 Plot2d_AxisScaleDraw::Plot2d_AxisScaleDraw( Plot2d_Plot2d* plot)
4230 : myPlot(plot)
4231 {
4232   myLowerBound = -1;
4233   myUpperBound = -1;
4234   setLabelAlignment(Qt::AlignRight);
4235   setLabelRotation(45.);
4236
4237   applyTicks();
4238
4239   myActivTicksDrawing   = true;
4240   myNumTicksDrawingCall = 1;
4241 }
4242
4243
4244 Plot2d_AxisScaleDraw::~Plot2d_AxisScaleDraw()
4245 {
4246 }
4247
4248
4249 /* Unactivate automatic ticks drawing
4250  */
4251 void Plot2d_AxisScaleDraw::unactivTicksDrawing( int numcall)
4252 {
4253   myActivTicksDrawing   = false;
4254   myNumTicksDrawingCall = numcall;
4255 }
4256
4257
4258 /* Draw X ticks and labels.
4259  * Draw systems names under X axis.
4260  * Overload the same name QwtScaleDraw method.
4261  * (PB: who call automaticaly this method)
4262  */
4263 void Plot2d_AxisScaleDraw::draw( QPainter* painter, const QPalette & palette) const
4264 {
4265   //std::cout << "Plot2d_AxisScaleDraw::draw() : activ= " << myActivTicksDrawing
4266   //                           << "  numcall= " << myNumTicksDrawingCall << std::endl;
4267
4268   if (!myActivTicksDrawing)  return;
4269
4270   //std::cout << "Plot2d_AxisScaleDraw::draw()" << std::endl;
4271
4272   QList<double> major_ticks  = scaleDiv().ticks(QwtScaleDiv::MajorTick);
4273   QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
4274   QList<double> minor_ticks  = scaleDiv().ticks(QwtScaleDiv::MinorTick);
4275
4276   medium_ticks.clear();
4277   minor_ticks.clear();
4278   major_ticks.clear();
4279
4280   major_ticks.append( myTicks);
4281
4282   QwtScaleDiv aScaleDiv = myPlot->axisScaleDiv( QwtPlot::xBottom );
4283   aScaleDiv.setTicks( QwtScaleDiv::MajorTick,  major_ticks );
4284   aScaleDiv.setTicks( QwtScaleDiv::MediumTick, medium_ticks );
4285   aScaleDiv.setTicks( QwtScaleDiv::MinorTick,  minor_ticks );
4286   myPlot->setAxisScaleDiv( QwtPlot::xBottom, aScaleDiv );
4287
4288   QwtScaleDraw *scale = myPlot->axisScaleDraw(QwtPlot::xBottom);
4289   ((Plot2d_AxisScaleDraw*)(scale))->applyTicks();
4290
4291   QwtScaleDraw::draw( painter, palette);
4292
4293   for (int i = 0; i < myTicks.size(); i++)
4294   {
4295       drawLabel( painter, myTicks[i]);
4296   }
4297
4298   //std::cout << "Ok for Plot2d_AxisScaleDraw::draw()" << std::endl;
4299 }
4300
4301
4302 double Plot2d_AxisScaleDraw::extent( const QFont &font ) const
4303 {
4304   QFontMetrics fm( font );
4305   return QwtScaleDraw::extent( font ) + fm.height() * 2;
4306 }
4307
4308 QwtText Plot2d_AxisScaleDraw::label( double value) const
4309 {
4310   if (myLabelX.contains(value))
4311           return myLabelX[value];
4312
4313   return QwtText(QString::number(value, 'f', 1));
4314 }
4315
4316
4317 /* Stock position and label of a X tick
4318  */
4319 void Plot2d_AxisScaleDraw::setLabelTick( double value, QString label, bool isDevice)
4320 {
4321   //qDebug()<< "setLabelTick ( " << value << ","<< label <<" )";
4322   if ( isDevice )
4323   {
4324       // For systems names under X axis
4325       myLabelDevice[value] = label;
4326   }
4327   else
4328   {
4329       // For X axis graduations
4330       myLabelX[value] = label;
4331   }
4332 }
4333
4334
4335 /* Stock ticks positions of a system, and draw them
4336  */
4337 void Plot2d_AxisScaleDraw::setTicks(const QList<double> aTicks)
4338 {
4339   //std::cout << "  Plot2d_AxisScaleDraw::setTicks()" << std::endl;
4340   myTicks = aTicks;
4341
4342   applyTicks();
4343 }
4344
4345
4346 void Plot2d_AxisScaleDraw::setInterval(double lowerBound, double upperBound)
4347 {
4348   myLowerBound = lowerBound;
4349   myUpperBound = upperBound;
4350   myPlot->setAxisScale( QwtPlot::xBottom, myLowerBound, myUpperBound );
4351 }
4352
4353
4354 /* Stock X ticks in drawing zone
4355  */
4356 void Plot2d_AxisScaleDraw::applyTicks()
4357 {
4358   //std::cout << "  Plot2d_AxisScaleDraw::applyTicks()" << std::endl;
4359
4360   QList<double> major_ticks = scaleDiv().ticks(QwtScaleDiv::MajorTick);
4361   QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
4362   QList<double> minor_ticks = scaleDiv().ticks(QwtScaleDiv::MinorTick);
4363
4364   medium_ticks.clear();
4365   minor_ticks.clear();
4366
4367   QwtScaleDiv aQwtScaleDiv = myPlot->axisScaleDiv( QwtPlot::xBottom );
4368   aQwtScaleDiv.setTicks( QwtScaleDiv::MajorTick, myTicks );
4369   aQwtScaleDiv.setTicks( QwtScaleDiv::MediumTick, medium_ticks );
4370   aQwtScaleDiv.setTicks( QwtScaleDiv::MinorTick, minor_ticks );
4371   myPlot->setAxisScaleDiv( QwtPlot::xBottom, aQwtScaleDiv );
4372
4373   QwtScaleDiv* aScaleDiv = (QwtScaleDiv*) &scaleDiv();
4374
4375   aScaleDiv->setTicks(QwtScaleDiv::MajorTick, myTicks);
4376   aScaleDiv->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
4377   aScaleDiv->setTicks(QwtScaleDiv::MinorTick, minor_ticks);
4378
4379   if (myLowerBound != -1 && myUpperBound != -1)
4380               aScaleDiv->setInterval(myLowerBound, myUpperBound);
4381
4382   //for (int i = 0; i < myTicks.size(); i++){
4383   //  QPoint p = labelPosition( i );
4384   //  qDebug() << i<< ") applyTicks -> LABEL" <<p;
4385   //}
4386 }
4387
4388
4389 void Plot2d_AxisScaleDraw::drawLabel( QPainter* painter, double value) const
4390 {
4391   //std::cout << "  Plot2d_AxisScaleDraw::drawLabel( " << value << " ) : "; //<< std::endl;
4392
4393   //qDebug() << "drawLabel  ( " <<value<<" )";
4394   if ( myLabelDevice.contains(value) )
4395   {
4396       QString deviceLabel = myLabelDevice[value];
4397       //
4398       std::string std_label = deviceLabel.toStdString();
4399       //const char *c_label = std_label.c_str();
4400       //std::cout << "    deviceLabel= |" << c_label << "|" << std::endl;
4401
4402       QPointF p = labelPosition( value );
4403       p += QPoint(0, DEVICE_BY);
4404       QFont  prevf = painter->font();
4405       //QColor prevc = (painter->pen()).color();
4406
4407       QFont devicef( DEVICE_FONT, DEVICE_FONT_SIZE, QFont::Bold);
4408       //
4409       //painter->setPen( QColor("blue") );
4410       painter->setFont( devicef );
4411       painter->drawText( p, myLabelDevice[value] );
4412       //painter->setPen( prevc );
4413       painter->setFont( prevf );
4414   }
4415   if ( myLabelX.contains(value) )
4416   {
4417       QString xLabel = myLabelX[value];
4418       //
4419       std::string std_label = xLabel.toStdString();
4420       //const char *c_label = std_label.c_str();
4421       //std::cout << "    xLabel= |" << c_label << "|" << std::endl;
4422
4423       QwtScaleDraw::drawLabel( painter, value );
4424   }
4425 }
4426
4427
4428 void Plot2d_AxisScaleDraw::drawTick( QPainter* painter, double value, int len) const
4429 {
4430   //qDebug() << "drawTick  ( " <<value<<" , "<<len<<" )  " ;
4431   //qDebug() << "myLabelX" << myLabelX;
4432   //
4433   if ( myLabelX.contains(value) )
4434   {
4435       QwtScaleDraw::drawTick( painter, value, len);
4436   }
4437 }
4438
4439
4440 /* Management of tooltips associated with markers for curves points or others points
4441  */
4442 const double Plot2d_QwtPlotPicker::BOUND_HV_SIZE = 0.2;
4443
4444 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int            xAxis,
4445                                             int            yAxis,
4446                                             RubberBand     rubberBand,
4447                                             DisplayMode    trackerMode,
4448                                             QwtPlotCanvas *canvas)
4449 : QwtPlotPicker( xAxis,
4450                  yAxis,
4451                  rubberBand,
4452                  trackerMode,
4453                  canvas)    // of drawing zone QwtPlot
4454 {
4455 }
4456
4457 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int            xAxis,
4458                                             int            yAxis,
4459                                             QwtPlotCanvas *canvas)
4460 : QwtPlotPicker( xAxis,
4461                  yAxis,
4462                  canvas)
4463 {
4464 }
4465
4466 Plot2d_QwtPlotPicker::~Plot2d_QwtPlotPicker()
4467 {
4468 }
4469 // http://www.qtcentre.org/threads/22751-How-do-i-select-a-QwtPlotMarker-using-a-QPlotPicker
4470
4471 /* Return the tooltip associated with a point when the mouse cursor pass near
4472  */
4473 QwtText Plot2d_QwtPlotPicker::trackerText( const QPoint & pos ) const
4474 {
4475   for (QList<QwtPlotMarker* >::const_iterator pMarkerIt = pMarkers.begin();pMarkerIt != pMarkers.end(); ++pMarkerIt )
4476     {
4477       QwtPlotMarker* pMarker = *pMarkerIt;
4478       if ( pMarker != NULL )
4479         {
4480           const QwtSymbol* symb=pMarker->symbol();
4481           const QSize& sz=symb->size();
4482           const QwtScaleMap yMapRef=plot()->canvasMap(QwtPlot::yLeft);
4483           const QwtScaleMap xMap=plot()->canvasMap(pMarker->xAxis());
4484           const QwtScaleMap yMap=plot()->canvasMap(pMarker->yAxis());
4485           QwtDoubleRect  bound0=pMarker->boundingRect();
4486           int x1 = qRound(xMap.transform(bound0.left()));
4487           int x2 = qRound(xMap.transform(bound0.right()));
4488           int y1 = qRound(yMap.transform(bound0.top()));
4489           int y2 = qRound(yMap.transform(bound0.bottom()));
4490           
4491           if ( x2 < x1 )
4492             qSwap(x1, x2);
4493           if ( y2 < y1 )
4494             qSwap(y1, y2);
4495           
4496           QRect bound00=QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
4497           QPoint toto(xMap.transform(pos.x()),yMapRef.transform(pos.y()));
4498           bound00.setX(bound00.x()-sz.width());
4499           bound00.setY(bound00.y()-sz.height());
4500           bound00.setWidth(bound00.width()+sz.width());
4501           bound00.setHeight(bound00.height()+sz.height());
4502           if( bound00.contains(toto) )
4503             {
4504               return pMarkersToolTip[pMarker];
4505             }
4506         }
4507   }
4508   return QwtText();
4509 }