Back to index

salome-gui  6.5.0
Plot2d_ViewFrame.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "Plot2d_ViewFrame.h"
00024 
00025 #include "Plot2d_Prs.h"
00026 #include "Plot2d_Curve.h"
00027 #include "Plot2d_PlotItems.h"
00028 #include "Plot2d_FitDataDlg.h"
00029 #include "Plot2d_ViewWindow.h"
00030 #include "Plot2d_SetupViewDlg.h"
00031 #include "Plot2d_AnalyticalCurveDlg.h"
00032 #include "Plot2d_AnalyticalCurve.h"
00033 #include "Plot2d_ToolTip.h"
00034 
00035 #include "SUIT_Tools.h"
00036 #include "SUIT_Session.h"
00037 #include "SUIT_MessageBox.h"
00038 #include "SUIT_ResourceMgr.h"
00039 #include "SUIT_Application.h"
00040 
00041 #include <QApplication>
00042 #include <QToolBar>
00043 #include <QToolButton>
00044 #include <QCursor>
00045 #include <QColorDialog>
00046 #include <QLayout>
00047 #include <QMap>
00048 #include <QPainter>
00049 #include <QPaintDevice>
00050 #include <QEvent>
00051 #include <QMouseEvent>
00052 #include <QContextMenuEvent>
00053 #include <QPrinter>
00054 #include <QPalette>
00055 #include <QLocale>
00056 #include <QXmlStreamWriter>
00057 #include <QXmlStreamReader>
00058 
00059 #include <qwt_math.h>
00060 #include <qwt_plot_canvas.h>
00061 #include <qwt_scale_div.h>
00062 #include <qwt_plot_marker.h>
00063 #include <qwt_plot_curve.h>
00064 #include <qwt_plot_grid.h>
00065 #include <qwt_scale_engine.h>
00066 #include <qwt_plot_zoomer.h>
00067 #include <qwt_curve_fitter.h>
00068 
00069 #include <stdlib.h>
00070 #include <qprinter.h>
00071 
00072 #include <qwt_legend.h>
00073 #include <qwt_scale_widget.h>
00074 
00075 #define DEFAULT_LINE_WIDTH     0     // (default) line width
00076 #define DEFAULT_MARKER_SIZE    9     // default marker size
00077 #define MIN_RECT_SIZE          11    // min sensibility area size
00078 
00079 #define FITALL_EVENT           ( QEvent::User + 9999 )
00080 
00081 const char* imageZoomCursor[] = { 
00082 "32 32 3 1",
00083 ". c None",
00084 "a c #000000",
00085 "# c #ffffff",
00086 "................................",
00087 "................................",
00088 ".#######........................",
00089 "..aaaaaaa.......................",
00090 "................................",
00091 ".............#####..............",
00092 "...........##.aaaa##............",
00093 "..........#.aa.....a#...........",
00094 ".........#.a.........#..........",
00095 ".........#a..........#a.........",
00096 "........#.a...........#.........",
00097 "........#a............#a........",
00098 "........#a............#a........",
00099 "........#a............#a........",
00100 "........#a............#a........",
00101 ".........#...........#.a........",
00102 ".........#a..........#a.........",
00103 ".........##.........#.a.........",
00104 "........#####.....##.a..........",
00105 ".......###aaa#####.aa...........",
00106 "......###aa...aaaaa.......#.....",
00107 ".....###aa................#a....",
00108 "....###aa.................#a....",
00109 "...###aa...............#######..",
00110 "....#aa.................aa#aaaa.",
00111 ".....a....................#a....",
00112 "..........................#a....",
00113 "...........................a....",
00114 "................................",
00115 "................................",
00116 "................................",
00117 "................................"};
00118 
00119 const char* imageCrossCursor[] = { 
00120   "32 32 3 1",
00121   ". c None",
00122   "a c #000000",
00123   "# c #ffffff",
00124   "................................",
00125   "................................",
00126   "................................",
00127   "................................",
00128   "................................",
00129   "................................",
00130   "................................",
00131   "...............#................",
00132   "...............#a...............",
00133   "...............#a...............",
00134   "...............#a...............",
00135   "...............#a...............",
00136   "...............#a...............",
00137   "...............#a...............",
00138   "...............#a...............",
00139   ".......#################........",
00140   "........aaaaaaa#aaaaaaaaa.......",
00141   "...............#a...............",
00142   "...............#a...............",
00143   "...............#a...............",
00144   "...............#a...............",
00145   "...............#a...............",
00146   "...............#a...............",
00147   "...............#a...............",
00148   "................a...............",
00149   "................................",
00150   "................................",
00151   "................................",
00152   "................................",
00153   "................................",
00154   "................................",
00155   "................................"};
00156   
00160 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
00161      : QWidget (parent, 0),
00162        myOperation( NoOpId ), 
00163        myCurveType( 1 ), 
00164        myShowLegend( true ), myLegendPos( 1 ), myLegendFont("Helvetic",12),
00165        myLegendColor(Qt::black),
00166        myMarkerSize( DEFAULT_MARKER_SIZE ),
00167        myBackground( Qt::white ),
00168        myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
00169        myTitleEnabled( true ), myXTitleEnabled( true ),
00170        myYTitleEnabled( true ), myY2TitleEnabled (true),
00171        myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ), 
00172        myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
00173        myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
00174        myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
00175        myXMode( 0 ), myYMode( 0 ),myNormLMin(false), myNormLMax(false), myNormRMin(false), myNormRMax(false),
00176        mySecondY( false ), myIsDefTitle( true )
00177 {
00178   setObjectName( title );
00179   myRNormAlgo = new Plot2d_NormalizeAlgorithm(this);
00180   myLNormAlgo = new Plot2d_NormalizeAlgorithm(this);
00181   /* Plot 2d View */
00182   QVBoxLayout* aLayout = new QVBoxLayout( this ); 
00183   myPlot = new Plot2d_Plot2d( this );
00184   new Plot2d_ToolTip( this );
00185 
00186   aLayout->addWidget( myPlot );
00187 
00188   //  createActions();
00189   connect( myPlot, SIGNAL( legendClicked( QwtPlotItem* ) ), 
00190            this, SIGNAL( legendClicked( QwtPlotItem* ) ) );
00191 
00192   // IPAL 21465
00193   /*  connect( myPlot->axisWidget( QwtPlot::xBottom ), SIGNAL( scaleDivChanged() ),
00194            myPlot, SLOT( onScaleDivChanged() ) );
00195   connect( myPlot->axisWidget( QwtPlot::yLeft ), SIGNAL( scaleDivChanged() ),
00196            myPlot, SLOT( onScaleDivChanged() ) );
00197   if (mySecondY)
00198     connect( myPlot->axisWidget( QwtPlot::yRight ), SIGNAL( scaleDivChanged() ),
00199     myPlot, SLOT( onScaleDivChanged() ) );*/
00200 
00201   /* Initial Setup - get from the preferences */
00202   readPreferences();
00203 
00204   myPlot->setMargin( 5 );
00205   setCurveType( myCurveType, false );
00206   setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
00207   setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
00208             myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
00209 
00210   setTitle( myTitleEnabled,  myTitle,  MainTitle, false );
00211   setTitle( myXTitleEnabled, myXTitle, XTitle, false );
00212   setTitle( myYTitleEnabled, myYTitle, YTitle, false );
00213 
00214   if (mySecondY)
00215     setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
00216   setHorScaleMode( myXMode, false );
00217   setVerScaleMode( myYMode, false );
00218   setBackgroundColor( myBackground );
00219   setLegendPos( myLegendPos );
00220   setLegendFont( myLegendFont );
00221   setLegendFontColor( myLegendColor );
00222   showLegend( myShowLegend, false );
00223   myPlot->replot();
00224 
00225   if ( parent ) {
00226     resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
00227   }
00228   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
00229   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
00230   myXDistance = xMap.s2() - xMap.s1();
00231   myYDistance = yMap.s2() - yMap.s1();
00232   myYDistance2 = 0;
00233   if (mySecondY) {
00234     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
00235     myYDistance2 = yMap2.s2() - yMap2.s1();
00236   }
00237   myPlot->canvas()->installEventFilter( this );
00238 }
00242 Plot2d_ViewFrame::~Plot2d_ViewFrame()
00243 {
00244 }
00248 QWidget* Plot2d_ViewFrame::getViewWidget()
00249 {
00250   return (QWidget*)myPlot;
00251 }
00255 void Plot2d_ViewFrame::DisplayAll()
00256 {
00257   objectList olist;
00258   getObjects( olist );
00259   foreach ( Plot2d_Object* o, olist )
00260     updateObject( o, false );
00261   myPlot->replot();
00262   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
00263 }
00267 void Plot2d_ViewFrame::EraseAll() 
00268 {
00269   objectList anObjects;
00270   getObjects( anObjects );
00271   eraseObjects( anObjects, false );
00272   myObjects.clear();
00273   // Erase all the intermittent segments who connect curves
00274   // (cf displayPlot2dCurveList() and createSegment(() )
00275   //
00276   {
00277     int nbSeg = myIntermittentSegmentList.size();
00278     for (int iseg=0; iseg < nbSeg; iseg++)
00279       {
00280         QwtPlotCurve *segment = myIntermittentSegmentList[iseg]; 
00281         segment->detach();  // erase in QwtPlot window
00282         delete segment;
00283       }
00284     myIntermittentSegmentList.clear();
00285   }
00286   myPlot->replot();
00287   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
00288 }
00292 void Plot2d_ViewFrame::Repaint()
00293 {
00294   myPlot->replot();
00295 }
00299 void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
00300 {
00301   if ( !prs || prs->IsNull() )
00302     return;
00303 
00304   setEnableAxis( QwtPlot::yRight, prs->isSecondY() ); // VSR: is it correct? maybe we should only enable second Y axis if required
00305 
00306   // display all objects from presentation
00307   objectList anObjects = prs->getObjects();
00308   displayObjects( anObjects );
00309   setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
00310   setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
00311             myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
00312   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
00313 }
00314 
00318 void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
00319 {
00320   if ( !prs || prs->IsNull() )
00321     return;
00322 
00323   // erase all objects from presentation
00324   objectList anObjects = prs->getObjects();
00325   eraseObjects( anObjects );
00326   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
00327 }
00328 
00329 bool Plot2d_ViewFrame::eventFilter( QObject* watched, QEvent* e )
00330 {
00331   if ( watched == myPlot->canvas() ) {
00332     int aType = e->type();
00333     switch( aType ) {
00334       case QEvent::MouseMove: {
00335         QMouseEvent* me = (QMouseEvent*)e;
00336         if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
00337           QMouseEvent m( QEvent::MouseMove, me->pos(), me->button(),
00338                          me->buttons(), me->modifiers() );
00339           if ( plotMouseMoved( m ) )
00340             return true;
00341         }
00342         break;
00343       }
00344       case QEvent::MouseButtonPress: {
00345         QMouseEvent* me = (QMouseEvent*)e;
00346         if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
00347           QMouseEvent m( QEvent::MouseButtonPress, me->pos(), me->button(),
00348                           me->buttons(), me->modifiers() );
00349           plotMousePressed( m );
00350         }
00351         break;
00352       }
00353       case QEvent::MouseButtonRelease: {
00354         QMouseEvent* me = (QMouseEvent*)e;
00355         if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
00356           QMouseEvent m( QEvent::MouseButtonRelease, me->pos(), me->button(),
00357                          me->buttons(), me->modifiers() );
00358           plotMouseReleased( m );
00359         }
00360         break;
00361       }
00362     case QEvent::ContextMenu:
00363       // Fix from SLN
00364       // Do nothing because context menu is called from MouseRelease
00365       return true;
00366     }
00367   }
00368   return QWidget::eventFilter( watched, e );
00369 }
00370 
00374 void Plot2d_ViewFrame::setTitle( const QString& title )
00375 {
00376   setTitle( myTitleEnabled, title, MainTitle, true );
00377   myIsDefTitle = false;
00378 }
00379 
00383 QString Plot2d_ViewFrame::getTitle() const
00384 {
00385   return myTitle;
00386 }
00387 
00391 void Plot2d_ViewFrame::readPreferences()
00392 {
00393   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
00394 
00395   myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
00396   setCurveType( resMgr->integerValue( "Plot2d", "CurveType", myCurveType ) );
00397 
00398   myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
00399   myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
00400   myLegendFont = resMgr->fontValue( "Plot2d", "LegendFont", myLegendFont );
00401   myLegendColor = resMgr->colorValue( "Plot2d", "LegendFontColor", myLegendColor );
00402   myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
00403   myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
00404 
00405   myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
00406   myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
00407   myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
00408   myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
00409 
00410   myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
00411   myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
00412   myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
00413 
00414   myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
00415   myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
00416   myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
00417 
00418   myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
00419   myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
00420   if ( mySecondY )
00421     myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
00422 
00423   myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
00424   myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
00425   if ( mySecondY )
00426     myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
00427 
00428   setHorScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode ) ) ), false );
00429   setVerScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode ) ) ), false );
00430   setNormLMinMode( resMgr->booleanValue( "Plot2d", "VerNormLMinMode", myNormLMin ) );
00431   setNormLMaxMode( resMgr->booleanValue( "Plot2d", "VerNormLMaxMode", myNormLMax ) );
00432   setNormRMinMode( resMgr->booleanValue( "Plot2d", "VerNormRMinMode", myNormRMin ) );
00433   setNormRMaxMode( resMgr->booleanValue( "Plot2d", "VerNormRMaxMode", myNormRMax ) );
00434   QColor c = resMgr->colorValue( "Plot2d", "DeviationMarkerColor", QColor(255,0,0));
00435   myPlot->setProperty(PLOT2D_DEVIATION_COLOR, c);
00436   myPlot->setProperty(PLOT2D_DEVIATION_LW, 
00437                       resMgr->integerValue( "Plot2d", "DeviationMarkerLineWidth", 1));
00438   myPlot->setProperty(PLOT2D_DEVIATION_TS, 
00439                       resMgr->integerValue( "Plot2d", "DeviationMarkerTickSize", 2));
00440 
00441 }
00442 
00446 void Plot2d_ViewFrame::writePreferences()
00447 {
00448   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
00449 
00450   resMgr->setValue( "Plot2d", "CurveType", myCurveType );
00451   resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
00452   resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
00453   resMgr->setValue( "Plot2d", "LegendFont", myLegendFont );
00454   resMgr->setValue( "Plot2d", "LegendFontColor", myLegendColor );
00455   resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
00456   resMgr->setValue( "Plot2d", "Background", myBackground );
00457   resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
00458   resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
00459   resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
00460   if ( mySecondY )
00461     resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
00462 
00463   resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
00464   resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
00465   resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
00466   resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
00467 
00468   resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
00469   resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
00470 
00471   resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
00472   resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
00473 
00474   resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
00475 
00476   if ( mySecondY )
00477   {
00478     resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
00479     resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
00480     resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
00481     resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
00482   }
00483 
00484   resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
00485   resMgr->setValue( "Plot2d", "VerNormLMinMode", myNormLMin );
00486   resMgr->setValue( "Plot2d", "VerNormLMaxMode", myNormLMax );
00487   resMgr->setValue( "Plot2d", "VerNormRMinMode", myNormRMin );
00488   resMgr->setValue( "Plot2d", "VerNormRMaxMode", myNormRMax );
00489 }
00490 
00494 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt ) 
00495 {
00496   int i;
00497   QwtValueList aTicks;
00498   bool xFound = false, yFound = false;
00499   double xCoord, yCoord;
00500   const QwtScaleDiv* aXscale = myPlot->axisScaleDiv( QwtPlot::xBottom );
00501   aTicks = aXscale->ticks( QwtScaleDiv::MajorTick );
00502   for ( i = 0; i < aTicks.count(); i++ ) {
00503     double majXmark = aTicks[i];
00504     int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
00505     if ( xmark-2 == pnt.x() ) {
00506       xCoord = majXmark; 
00507       xFound = true;
00508       break;
00509     }
00510   }
00511   if ( !xFound ) {
00512     aTicks = aXscale->ticks( QwtScaleDiv::MinorTick );
00513     for ( i = 0; i < aTicks.count(); i++ ) {
00514       double minXmark = aTicks[i];
00515       int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
00516       if ( xmark-2 == pnt.x() ) {
00517         xCoord = minXmark; 
00518         xFound = true;
00519         break;
00520       }
00521     }
00522   }  
00523   const QwtScaleDiv* aYscale = myPlot->axisScaleDiv( QwtPlot::yLeft );
00524   aTicks = aYscale->ticks( QwtScaleDiv::MajorTick );
00525   for ( i = 0; i < aTicks.count(); i++ ) {
00526     double majYmark = aTicks[i];
00527     int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
00528     if ( ymark-2 == pnt.y() ) {
00529       yCoord = majYmark; 
00530       yFound = true;
00531       break;
00532     }
00533   }
00534   if ( !yFound ) {
00535     aTicks = aYscale->ticks( QwtScaleDiv::MinorTick );
00536     for ( i = 0; i < aTicks.count(); i++ ) {
00537       double minYmark = aTicks[i];
00538       int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
00539       if ( ymark-2 == pnt.y() ) {
00540         yCoord = minYmark; 
00541         yFound = true;
00542         break;
00543       }
00544     }
00545   }  
00546 
00547   QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).trimmed();
00548   if ( strX == "-0" )
00549     strX = "0";
00550   QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).trimmed();
00551   if ( strY == "-0" )
00552     strY = "0";
00553   QString info = "";
00554 
00555   if (mySecondY) {
00556     bool yFound2 = false;
00557     double yCoord2;
00558 
00559     const QwtScaleDiv* aYscale2 = myPlot->axisScaleDiv( QwtPlot::yRight );
00560     aTicks = aYscale2->ticks( QwtScaleDiv::MajorTick );
00561     for ( i = 0; i < aTicks.count(); i++ ) {
00562       double majYmark = aTicks[i];
00563       int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
00564       if ( ymark-2 == pnt.y() ) {
00565         yCoord2 = majYmark; 
00566         yFound2 = true;
00567         break;
00568       }
00569     }
00570     if ( !yFound2 ) {
00571       aTicks = aYscale2->ticks( QwtScaleDiv::MinorTick );
00572       for ( i = 0; i < aTicks.count(); i++ ) {
00573         double minYmark = aTicks[i];
00574         int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
00575         if ( ymark-2 == pnt.y() ) {
00576           yCoord2 = minYmark; 
00577           yFound2 = true;
00578           break;
00579         }
00580       }
00581     }
00582     QString strY2 = QString::number( yFound2 ? yCoord2 : 
00583                       myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).trimmed();
00584     if ( strY2 == "-0" )
00585     strY2 = "0";
00586     info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
00587   }
00588   else
00589     info = tr("INF_COORDINATES").arg( strX ).arg( strY );
00590 
00591   return info;
00592 }
00593 
00597 void Plot2d_ViewFrame::createCurveTooltips( Plot2d_Curve *curve,
00598                                             Plot2d_QwtPlotPicker *picker)
00599 {      
00600   // Dans Plot2d.h : pointList == QList<Plot2d_Point> 
00601   double x, y;
00602   QString tooltip;
00603 
00604   pointList points = curve->getPointList();
00605   QColor    color  = curve->getColor();
00606 
00607   // Point marker
00608   QwtSymbol symbol;
00609   symbol.setStyle(QwtSymbol::Ellipse);
00610   symbol.setSize(1,1);
00611   symbol.setPen( QPen(color));
00612   symbol.setBrush( QBrush(color));
00613 
00614   for (int ip=0; ip < points.count(); ip++)
00615   {
00616       x = points[ip].x;
00617       y = points[ip].y;
00618       tooltip = points[ip].text;
00619 
00620       myPlot->createMarkerAndTooltip( symbol,
00621                                       x,
00622                                       y,
00623                                       tooltip,
00624                                       picker);
00625   }
00626 }
00627 
00628 
00639 void Plot2d_ViewFrame::displayPlot2dCurveList( QList< QList<Plot2d_Curve*> > sysCoCurveList,
00640                                                Plot2d_QwtPlotPicker*         picker,
00641                                                bool                          displayLegend)
00642 {
00643   //std::cout << "Plot2d_ViewFrame::displayPlot2dCurveList() 1" << std::endl;
00644 
00645   // Systems number
00646   int nbSystem = sysCoCurveList.size();
00647 
00648   // Composants number by system
00649   int nbComponent = (sysCoCurveList.at(0)).size();
00650 
00651   // Total number of curves
00652   //int nbAllCurve = nbSystem*nbComponent;
00653 
00654    //std::cout << "  Number of systems       = " << nbSystem << std::endl;
00655    //std::cout << "  Number of components    = " << nbComponent << std::endl;
00656    //std::cout << "  Number total of courbes = " << nbAllCurve << std::endl;
00657 
00658    // 1)- Construction of a list by component and by system
00659  
00660    // |      component 1      |      component 2      | ..... |      component M      |
00661    // | syst1 syst2 ... systN | syst1 syst2 ... systN | ..... | syst1 syst2 ... systN |
00662 
00663   QList<Plot2d_Curve*> plot2dCurveCoSysList;
00664 
00665   //std::cout << "  Liste par composant et par systeme :" << std::endl;
00666 
00667   for (int icom = 0; icom < nbComponent; icom++)
00668   {
00669       for (int isys = 0; isys < nbSystem; isys++)
00670       {
00671           //std::cout << "    icom= " << icom << " idev= " << isys << std::endl;
00672 
00673          // The system curves list
00674           QList<Plot2d_Curve*> sysCurveList = sysCoCurveList.at(isys);
00675 
00676          Plot2d_Curve *curve = sysCurveList.at(icom);
00677 
00678           plot2dCurveCoSysList.append( curve);
00679       }
00680   }
00681 
00682   // 2)- Display list curves by a component's curves group
00683   //     Draw connection segments (intermittent line) between the curves
00684 
00685   displayPlot2dCurveList( plot2dCurveCoSysList, nbSystem, picker, displayLegend);
00686 
00687   // 3)- Size of graduations labels and texts under X axis
00688 
00689   QwtScaleWidget *wid = myPlot->axisWidget( QwtPlot::xBottom);
00690   wid->setTitle( "  "); // indispensable pour que les noms des systemes apparaissent
00691                         // sous l'axe des X !!
00692 
00693   QFont xFont = myPlot->axisFont(QwtPlot::xBottom);
00694   xFont.setPointSize(8); 
00695   myPlot->setAxisFont( QwtPlot::xBottom, xFont);
00696 
00697   //std::cout << "Ok for Plot2d_ViewFrame::displayPlot2dCurveList() 1" << std::endl;
00698 }
00699 
00700 
00707 void Plot2d_ViewFrame::displayPlot2dCurveList( QList<Plot2d_Curve*>  curveList,
00708                                                                 int  groupSize,
00709                                                Plot2d_QwtPlotPicker* picker,
00710                                                                bool  displayLegend)
00711 {
00712   //std::cout << "Plot2d_ViewFrame::displayPlot2dCurveList() 2" << std::endl;
00713 
00714   // Consider the new legend's entries
00715   // (PB: to update the legend we must remove it and put a new QwtLegend in the QwtPlot)
00716   myPlot->insertLegend( (QwtLegend*)NULL); // we remove here, we shall put at the end
00717 
00718   double X[2];
00719   double Y[2];
00720 
00721   int nbAllCurves = curveList.size();
00722   int nbGroups    = nbAllCurves / groupSize;
00723   int ig, icur;
00724   int icur1, icur2;  // curves indices in a group
00725 
00726   //std::cout << "  " << nbGroups << " groupes a " << groupSize << " courbes" << std::endl;
00727 
00728   icur1 = 0;
00729   for (ig=0; ig < nbGroups; ig++)
00730   {
00731       icur2 = icur1 + groupSize -1;
00732 
00733       //std::cout << "  Indices des courbes du groupe " << ig << " : " << icur1
00734       //                                                      << " a " << icur2 << std::endl;
00735       int nbCurves = icur2 - icur1 + 1;
00736       //std::cout << "    groupe a " << nbCurves << " courbes" << std::endl;
00737 
00738       // 1)- Graphical attributs of group's curves
00739 
00740       // Graphical attributes of the first group's curve
00741       //
00742       Plot2d_Curve *plot2dCurve1 = curveList.at(icur1);
00743       //
00744       QColor color1 = plot2dCurve1->getColor();
00745       Plot2d::LineType linetype1 = plot2dCurve1->getLine();
00746       int lineWidth1 = plot2dCurve1->getLineWidth();
00747       QwtSymbol::Style symbolStyle1 = plot2dCurve1->getMarkerStyle();
00748 
00749       if (nbCurves > 1)
00750       {
00751           // We attribute to the current group's curve, the color, the line's kind
00752           // and the marker's kind of the first group's curve
00753 
00754           for (icur=icur1 +1; icur <= icur2; icur++)
00755           {
00756               Plot2d_Curve *plot2dCurve = curveList.at(icur);
00757               //
00758               plot2dCurve->setColor( color1);
00759               plot2dCurve->setLine( linetype1, lineWidth1);
00760               plot2dCurve->setMarkerStyle( symbolStyle1);
00761           }
00762       }
00763 
00764       // 2)- Display the group's curves
00765 
00766       for (icur=icur1; icur <= icur2; icur++)
00767       {
00768           Plot2d_Curve *plot2dCurve = curveList.at(icur);
00769 
00770           QString title = plot2dCurve->getVerTitle();
00771           std::string std_title = title.toStdString();
00772           //const char *c_title = std_title.c_str();
00773           //std::cout << "    courbe d'indice " << icur << " : |" << c_title << "|" << std::endl;
00774 
00775           // Create the graphic curve (QwtPlotCurve) et display it in the drawing zone
00776           // (Qwtplot)
00777           displayCurve( plot2dCurve);
00778 
00779          // Draw the points' markers and create the associated tooltips
00780           createCurveTooltips( plot2dCurve, picker);
00781 
00782           // Get the graphic curve
00783           QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>( getPlotObject( plot2dCurve));
00784 
00785           // Modify the points' markers
00786           QwtSymbol symbol (plotCurve->symbol()) ;
00787           symbol.setStyle( symbolStyle1);
00788           symbol.setPen( QPen( color1, lineWidth1));
00789           symbol.setBrush( QBrush( color1));
00790           QSize size = 0.5*(symbol.size());
00791           symbol.setSize(size);
00792           //
00793           plotCurve->setPen( QPen( color1, lineWidth1));
00794           plotCurve->setSymbol( symbol);
00795 
00796           if (icur > icur1)
00797           {
00798               //std::cout << "  courbe d'indice " << icur << " sans entree dans la legende" << std::endl;
00799 
00800               // The curve must not have legend's entry
00801               plotCurve->setItemAttribute( QwtPlotItem::Legend, false);
00802           }
00803           else
00804           {
00805               plotCurve->setItemAttribute( QwtPlotItem::Legend, true);
00806           }
00807       }
00808 
00809       // 3)- Intermittent segments to connect all the group's curves
00810 
00811       if (nbCurves > 1)
00812       {
00813           double *Xval;
00814           double *Yval;
00815           int nbPoints;
00816 
00817           Plot2d_Curve *plot2dCurve1 = curveList.at(icur1);
00818 
00819           // Last point of the first curve
00820           nbPoints = plot2dCurve1->getData( &Xval, &Yval);  // dynamic allocation
00821           X[0] = Xval[ nbPoints -1];
00822           Y[0] = Yval[ nbPoints -1];
00823           delete [] Xval;
00824           delete [] Yval;
00825 
00826           for (icur=icur1 +1; icur <= icur2; icur++)
00827           {
00828               Plot2d_Curve *plot2dCurve = curveList.at(icur);
00829 
00830               // First curve's point
00831               nbPoints = plot2dCurve->getData( &Xval, &Yval);
00832               X[1] = Xval[0];
00833               Y[1] = Yval[0];
00834 
00835               createSegment( X, Y, 2,
00836                              Qt::DotLine,
00837                              lineWidth1,
00838                              color1,
00839                              QwtSymbol::NoSymbol);
00840 
00841               // Last curve's point
00842               X[0] = Xval[ nbPoints -1];
00843               Y[0] = Yval[ nbPoints -1];
00844               delete [] Xval;
00845               delete [] Yval;
00846           }
00847       }
00848 
00849       icur1 = icur2 + 1;
00850   }
00851 
00852   if (displayLegend)
00853     {
00854       // Consider the new legend's entries
00855       showLegend( true, true);
00856     }
00857 
00858   //std::cout << "Ok for Plot2d_ViewFrame::displayPlot2dCurveList() 2" << std::endl;
00859 }
00860 
00861 
00868 Plot2d_Curve* Plot2d_ViewFrame::createPlot2dCurve( QString & title,
00869                                                    QString & unit,
00870                                                    QList<double> & xList,
00871                                                    QList<double> & yList,
00872                                                    QList<QString> & tooltipList,
00873                                                    Plot2d::LineType lineKind,
00874                                                    int lineWidth,
00875                                                    QColor & lineColor,
00876                                                    QwtSymbol::Style markerKind,
00877                                                    Plot2d_QwtPlotPicker* picker,
00878                                                    bool toDraw,
00879                                                    bool displayLegend)
00880 {
00881   //std::cout << "Plot2d_ViewFrame::createPlot2dCurve()" << std::endl;
00882 
00883   // Mathematical curve
00884   Plot2d_Curve* plot2dCurve = new Plot2d_Curve();
00885 
00886   int nbPoint = xList.size();
00887   double xVal, yVal;
00888   QString tooltip;
00889 
00890   for (int ip=0; ip < nbPoint; ip++)
00891   {
00892       xVal = xList.at(ip);
00893       yVal = yList.at(ip);
00894       tooltip = tooltipList.at(ip);
00895 
00896       plot2dCurve->addPoint( xVal, yVal, tooltip);
00897   }
00898 
00899   plot2dCurve->setVerTitle( title);
00900   plot2dCurve->setVerUnits( unit);
00901   if (lineColor.isValid())
00902   {
00903       plot2dCurve->setColor( lineColor);
00904   }
00905   plot2dCurve->setLine( lineKind, lineWidth);
00906   plot2dCurve->setMarkerStyle( markerKind);
00907   plot2dCurve->setMarkerSize(1);
00908 
00909   // Graphical curve (QwtPlotCurve) in the drawing zone (QwtPlot) myPlot
00910   if (toDraw)
00911   {
00912       if (!displayLegend)
00913         {
00914           myPlot->insertLegend( (QwtLegend*)NULL);
00915         }
00916       displayCurve( plot2dCurve);
00917 
00918       // plot points marker create associated tooltips
00919       createCurveTooltips( plot2dCurve, picker);
00920 
00921       // Get the graphical curve
00922       QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>( getPlotObject( plot2dCurve));
00923 
00924       QColor theColor;
00925 
00926       if (lineColor.isValid())
00927       {
00928         //std::cout << "  valid color" << std::endl;
00929           theColor = lineColor;
00930       }
00931       else
00932       {
00933         //std::cout << "  valid color" << std::endl;
00934           QPen pen = plotCurve->pen();
00935           theColor = pen.color();
00936       }
00937 
00938       // Modify points' markers
00939       QwtSymbol symbol (plotCurve->symbol()) ;
00940       symbol.setStyle( markerKind);
00941       //
00942       if (markerKind != QwtSymbol::NoSymbol)
00943       {
00944           symbol.setPen( QPen( theColor, lineWidth));
00945           symbol.setBrush( QBrush( theColor));
00946           QSize size = 2.0*(symbol.size()); //0.5
00947           symbol.setSize(size);
00948       }
00949 
00950       plotCurve->setSymbol( symbol);
00951       plotCurve->setStyle( QwtPlotCurve::Lines);
00952       plotCurve->setPen( QPen( theColor, lineWidth));
00953 
00954       // The curve must not have legend's entry
00955       plotCurve->setItemAttribute( QwtPlotItem::Legend, false);
00956   }
00957   return plot2dCurve;
00958 }
00959 
00960 
00964 QColor Plot2d_ViewFrame::getPlot2dCurveColor( Plot2d_Curve* plot2dCurve)
00965 {
00966 
00967   // Get graphical curve
00968   QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>( getPlotObject( plot2dCurve));
00969 
00970   QPen pen = plotCurve->pen();
00971   QColor color = pen.color();
00972 
00973   return color;
00974 }
00975 
00976 
00980 void Plot2d_ViewFrame::createSegment( double *X, double *Y, int nbPoint,
00981                                       Qt::PenStyle lineKind,
00982                                       int lineWidth,
00983                                       QColor & lineColor,
00984                                       QwtSymbol::Style markerKind)
00985 {
00986   QwtPlotCurve* aPCurve = new QwtPlotCurve();
00987 
00988   aPCurve->setData( X, Y, nbPoint);
00989 
00990   aPCurve->setPen( QPen( lineColor, lineWidth, lineKind));
00991   QwtSymbol aSymbol;
00992   aSymbol.setStyle( markerKind);
00993   aPCurve->setSymbol( aSymbol);
00994 
00995   // The segment must not have legend's entry
00996   aPCurve->setItemAttribute( QwtPlotItem::Legend, false);
00997 
00998   aPCurve->attach( myPlot);
00999   // To deallocate in EraseAll()
01000   myIntermittentSegmentList.append( aPCurve);
01001 }
01002 
01006 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
01007 {
01008   displayObject( curve, update );
01009 }
01010 
01014 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
01015 {
01016   objectList objects;
01017   foreach ( Plot2d_Curve* curve, curves )
01018     objects << curve;
01019   displayObjects( objects, update );
01020 }
01021 
01025 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
01026 {
01027   eraseObject( curve, update );
01028 }
01029 
01033 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
01034 {
01035   objectList objects;
01036   foreach ( Plot2d_Curve* curve, curves )
01037     objects << curve;
01038   eraseObjects( objects, update );
01039 }
01040 
01044 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
01045 {
01046   updateObject( curve, update );
01047 }
01048 
01049 void Plot2d_ViewFrame::processFiltering(bool update) 
01050 {
01051   CurveDict aCurves = getCurves();
01052   AlgoPlot2dInputData aLData, aRData;
01053   CurveDict::iterator it;
01054   for ( it = aCurves.begin(); it != aCurves.end(); it++ ) {
01055     Plot2d_Object* objItem = it.value();
01056     if (objItem->getYAxis() == QwtPlot::yRight)
01057       aRData.append(objItem);
01058     else
01059       aLData.append(objItem);
01060   }
01061 
01062 // Normalization by left Y axis
01063   if (!myNormLMin && !myNormLMax)
01064     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeNone);
01065   if(myNormLMin && myNormLMax)  
01066     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMinMax);
01067   else if(myNormLMin)
01068     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMin);
01069   else if(myNormLMax)
01070     myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMax);
01071 
01072   myLNormAlgo->setInput(aLData);
01073   myLNormAlgo->execute();
01074 
01075 // Normalization by right Y axis
01076   if (!myNormRMin && !myNormRMax)
01077     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeNone);
01078   if(myNormRMin && myNormRMax)  
01079     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMinMax);
01080   else if(myNormRMin)
01081     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMin);
01082   else if(myNormRMax)
01083     myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMax);
01084 
01085   myRNormAlgo->setInput(aRData);
01086   myRNormAlgo->execute();
01087 
01088   for ( it = aCurves.begin(); it != aCurves.end(); it++) {
01089     QwtPlotCurve* item = it.key();
01090     Plot2d_Object* objItem = it.value();
01091     updatePlotItem(objItem, item);
01092   }
01093   if(update)
01094   myPlot->replot();
01095 }
01096 
01100 int Plot2d_ViewFrame::getCurves( curveList& curves ) const
01101 {
01102   curves.clear();
01103 
01104   CurveDict aCurves = getCurves();
01105   CurveDict::iterator it;
01106   for ( it = aCurves.begin(); it != aCurves.end(); it++ )
01107     curves << it.value();
01108   return curves.count();
01109 }
01110 
01111 CurveDict Plot2d_ViewFrame::getCurves() const
01112 {
01113   CurveDict curves;
01114   ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end();
01115   for ( ; it != aLast; it++ ) {
01116     QwtPlotItem* anItem = it.key();
01117     if ( anItem && anItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) {
01118       QwtPlotCurve* aPCurve = dynamic_cast<QwtPlotCurve*>( anItem );
01119       Plot2d_Curve* aCurve = dynamic_cast<Plot2d_Curve*>( it.value() );
01120       if ( aPCurve && aCurve )
01121         curves.insert( aPCurve, aCurve );
01122     }
01123   }
01124   return curves;
01125 }
01126 
01130 void Plot2d_ViewFrame::displayObject( Plot2d_Object* object, bool update )
01131 {
01132   if ( !object )
01133     return;
01134   
01135   if ( object->getYAxis() == QwtPlot::yRight )
01136     mySecondY = true;
01137 
01138   // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
01139   // it crashes if switched to X/Y logarithmic mode, when one or more points have
01140   // non-positive X/Y coordinate
01141   if ( myXMode && object->getMinX() <= 0. )
01142     setHorScaleMode( 0, false );
01143   if ( myYMode && object->getMinY() <= 0. )
01144     setVerScaleMode( 0, false );
01145 
01146   if ( object->isAutoAssign() )
01147     object->autoFill( myPlot );
01148   
01149   if ( hasPlotObject( object ) ) {
01150     processFiltering(update);
01151     updateObject( object, update );
01152   }
01153   else {
01154     QwtPlotItem* anItem = object->createPlotItem();
01155     anItem->attach( myPlot );
01156     myObjects.insert( anItem, object );
01157     //myPlot->setCurveYAxis(curveKey, curve->getYAxis());
01158 
01159     if ( object->rtti() == QwtPlotItem::Rtti_PlotCurve )
01160     {
01161       Plot2d_Curve* aCurve = dynamic_cast<Plot2d_Curve*>( object );
01162       if ( aCurve )
01163       {
01164        //myMarkerSize = 1;
01165         //aCurve->setMarkerSize( myMarkerSize );
01166 
01167        if (aCurve->getMarkerSize() == 0)
01168        {
01169             aCurve->setMarkerSize( myMarkerSize );
01170        }
01171 
01172         processFiltering(update);
01173         updatePlotItem( aCurve, anItem );
01174         setCurveType( getPlotCurve( aCurve ), myCurveType );
01175       }
01176     }
01177   }
01178   updateTitles();
01179   myPlot->updateYAxisIdentifiers();
01180   if ( update )
01181     myPlot->replot();
01182   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
01183 }
01184 
01188 void Plot2d_ViewFrame::displayObjects( const objectList& objects, bool update )
01189 {
01190   //myPlot->setUpdatesEnabled( false ); // call this function deprecate update of legend
01191   foreach ( Plot2d_Object* object, objects )
01192     displayObject( object, false );
01193   fitAll();
01194   //myPlot->setUpdatesEnabled( true );
01195   // update legend
01196   if ( update )
01197     myPlot->replot();
01198 }
01199 
01203 void Plot2d_ViewFrame::eraseObject( Plot2d_Object* object, bool update )
01204 {
01205   if ( !object )
01206     return;
01207 
01208   if ( hasPlotObject( object ) ) {
01209     QwtPlotItem* anObject = getPlotObject( object );
01210     anObject->hide();
01211     anObject->detach();
01212     myObjects.remove( anObject );
01213     updateTitles();
01214     myPlot->updateYAxisIdentifiers();
01215     if ( update )
01216       myPlot->replot();
01217   }
01218   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
01219 }
01220 
01224 void Plot2d_ViewFrame::eraseObjects( const objectList& objects, bool update )
01225 {
01226   foreach ( Plot2d_Object* object, objects )
01227     eraseObject( object, false );
01228 
01229   //  fitAll();
01230   if ( update )
01231     myPlot->replot();
01232   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
01233 }
01234 
01238 void Plot2d_ViewFrame::updateObject( Plot2d_Object* object, bool update )
01239 {
01240   if ( !object )
01241     return;
01242   if ( hasPlotObject( object ) ) {
01243     QwtPlotItem* anItem = getPlotObject( object );
01244     if ( !anItem )
01245       return;
01246     updatePlotItem(object, anItem );
01247     anItem->setVisible( true );
01248     if ( update )
01249       myPlot->replot();
01250     if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
01251   }
01252 }
01253 
01257 int Plot2d_ViewFrame::getObjects( objectList& objects ) const
01258 {
01259   objects.clear();
01260 
01261   ObjectDict::const_iterator it;
01262   for ( it = myObjects.begin(); it != myObjects.end(); it++ )
01263     objects << it.value();
01264   return objects.count();
01265 }
01266 
01270 bool Plot2d_ViewFrame::isVisible( Plot2d_Object* object ) const
01271 {
01272   return object && hasPlotObject( object ) && getPlotObject( object )->isVisible();
01273 } 
01274 
01278 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
01279 {
01280   if ( !prs || prs->IsNull() )
01281     return;
01282 
01283   ObjectDict::iterator it = myObjects.begin();
01284   Plot2d_Object* anObj;
01285   for (; it != myObjects.end(); ++it ) {
01286     anObj = *it;
01287     if ( hasPlotObject( anObj ) )
01288       getPlotObject( anObj )->setTitle( !anObj->getName().isEmpty() ?
01289                             anObj->getName() : anObj->getVerTitle() );
01290   }
01291 }
01292 
01296 void Plot2d_ViewFrame::updateLegend() {
01297   if ( myPlot->getLegend() ) {
01298     ObjectDict::iterator it = myObjects.begin();
01299     for( ; it != myObjects.end(); ++it ) 
01300       it.key()->updateLegend(myPlot->getLegend());
01301   }
01302 }
01303 
01304 
01308 void Plot2d_ViewFrame::fitAll()
01309 {
01310   // Postpone fitAll operation until QwtPlot geometry
01311   // has been fully defined
01312   if ( !myPlot->polished() ){
01313     QApplication::postEvent( this, new QEvent( (QEvent::Type)FITALL_EVENT ) );
01314     return;
01315   }
01316 
01317   myPlot->setAxisAutoScale( QwtPlot::yLeft );
01318   myPlot->setAxisAutoScale( QwtPlot::xBottom );
01319   myPlot->replot();
01320 
01321   double xmin, xmax, y1min, y1max, y2min, y2max;
01322   getFitRangeByCurves(xmin, xmax, y1min, y1max, y2min, y2max);
01323 
01324   myPlot->setAxisScale( QwtPlot::xBottom, xmin, xmax );
01325   myPlot->setAxisScale( QwtPlot::yLeft, y1min, y1max );
01326 
01327   if (mySecondY) {
01328     myPlot->setAxisAutoScale( QwtPlot::yRight );
01329     myPlot->replot();
01330     myPlot->setAxisScale( QwtPlot::yRight, y2min, y2max );
01331   }
01332   myPlot->replot();
01333   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
01334 }
01335 
01339 void Plot2d_ViewFrame::fitArea( const QRect& area )
01340 {
01341   QRect rect = area.normalized();
01342   if ( rect.width() < MIN_RECT_SIZE ) {
01343     rect.setWidth( MIN_RECT_SIZE );
01344     rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
01345   }
01346   if ( rect.height() < MIN_RECT_SIZE ) {
01347     rect.setHeight( MIN_RECT_SIZE );
01348     rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
01349   }
01350   myPlot->setAxisScale( QwtPlot::yLeft, 
01351             myPlot->invTransform( QwtPlot::yLeft, rect.top() ), 
01352             myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
01353   if (mySecondY)
01354     myPlot->setAxisScale( QwtPlot::yRight, 
01355             myPlot->invTransform( QwtPlot::yRight, rect.top() ), 
01356             myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
01357   myPlot->setAxisScale( QwtPlot::xBottom, 
01358             myPlot->invTransform( QwtPlot::xBottom, rect.left() ), 
01359             myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
01360   myPlot->replot();
01361   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
01362 }
01363 
01367 void Plot2d_ViewFrame::fitData(const int mode,
01368                                const double xMin, const double xMax,
01369                                const double yMin, const double yMax,
01370                                double y2Min, double y2Max)
01371 {
01372   if ( mode == 0 || mode == 2 ) {
01373     myPlot->setAxisScale( QwtPlot::yLeft, yMin, yMax );
01374     if (mySecondY)
01375       myPlot->setAxisScale( QwtPlot::yRight, y2Min, y2Max );
01376   }
01377   if ( mode == 0 || mode == 1 ) 
01378     myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax ); 
01379   myPlot->replot();
01380   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
01381 }
01382 
01386 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
01387                                     double& yMin, double& yMax,
01388                                     double& y2Min, double& y2Max)
01389 {
01390   int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).transform( myPlot->canvasMap( QwtPlot::xBottom ).s1() );
01391   int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).transform( myPlot->canvasMap( QwtPlot::xBottom ).s2() );
01392   int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).transform( myPlot->canvasMap( QwtPlot::yLeft ).s1() );
01393   int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).transform( myPlot->canvasMap( QwtPlot::yLeft ).s2() );
01394   xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
01395   xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
01396   yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
01397   yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
01398   y2Min = 0;
01399   y2Max = 0;
01400   if (mySecondY) {
01401     int iyMin = myPlot->canvasMap( QwtPlot::yRight ).transform( myPlot->canvasMap( QwtPlot::yRight ).s1() );
01402     int iyMax = myPlot->canvasMap( QwtPlot::yRight ).transform( myPlot->canvasMap( QwtPlot::yRight ).s2() );
01403     y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
01404     y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
01405   }
01406 }
01407 
01411 void Plot2d_ViewFrame::getFitRangeByCurves(double& xMin,  double& xMax,
01412                                            double& yMin,  double& yMax,
01413                                            double& y2Min, double& y2Max)
01414 {
01415   bool emptyV1 = true, emptyV2 = true;
01416   if ( !myObjects.isEmpty() ) {
01417     ObjectDict::const_iterator it = myObjects.begin();
01418     for ( ; it != myObjects.end(); it++ ) {
01419       bool isV2 = it.value()->getYAxis() == QwtPlot::yRight;
01420       if ( !it.value()->isEmpty() ) {
01421        if ( emptyV1 && emptyV2 ) {
01422          xMin = 1e150;
01423          xMax = -1e150;
01424        }
01425        if ( emptyV1 ) {
01426          yMin = 1e150;
01427          yMax = -1e150;
01428        }
01429        if ( emptyV2 ) {
01430          y2Min = 1e150;
01431          y2Max = -1e150;
01432        }
01433        isV2 ? emptyV2 = false : emptyV1 = false;
01434        xMin = qMin( xMin, it.value()->getMinX() );
01435        xMax = qMax( xMax, it.value()->getMaxX() );
01436         if ( isV2 ) {
01437           y2Min = qMin( y2Min, it.value()->getMinY() );
01438           y2Max = qMax( y2Max, it.value()->getMaxY() );
01439         }
01440         else {
01441           yMin = qMin( yMin, it.value()->getMinY() );
01442           yMax = qMax( yMax, it.value()->getMaxY() );
01443         }
01444       }
01445     }
01446     if ( xMin == xMax ) {
01447       xMin = xMin == 0. ? -1. : xMin - xMin/10.;
01448       xMax = xMax == 0. ?  1. : xMax + xMax/10.;
01449     }
01450     if ( yMin == yMax ) {
01451       yMin = yMin == 0. ? -1. : yMin - yMin/10.;
01452       yMax = yMax == 0. ?  1  : yMax + yMax/10.;
01453     }
01454     if ( y2Min == y2Max ) {
01455       y2Min = y2Min == 0. ? -1. : y2Min - y2Min/10.;
01456       y2Max = y2Max == 0. ?  1  : y2Max + y2Max/10.;
01457     }
01458   }
01459   // default values
01460   if ( emptyV1 && emptyV2 ) {
01461     xMin = isModeHorLinear() ? 0.    : 1.;
01462     xMax = isModeHorLinear() ? 1000. : 1e5;
01463   }
01464   if ( emptyV1  ) {
01465     yMin = isModeVerLinear() ? 0.    : 1.;
01466     yMax = isModeVerLinear() ? 1000. : 1e5;
01467   }
01468   if ( emptyV2  ) {
01469     y2Min = isModeVerLinear() ? 0.    : 1.;
01470     y2Max = isModeVerLinear() ? 1000. : 1e5;
01471   }
01472 }
01473 
01477 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
01478 {
01479   int btn = me.button() | me.modifiers();
01480   const int zoomBtn = Qt::ControlModifier | Qt::LeftButton;
01481   const int panBtn  = Qt::ControlModifier | Qt::MidButton;
01482   const int fitBtn  = Qt::ControlModifier | Qt::RightButton;
01483 
01484   int op = NoOpId;
01485   if ( btn == zoomBtn ) {
01486     QPixmap zoomPixmap (imageZoomCursor);
01487     QCursor zoomCursor (zoomPixmap);
01488     myPlot->canvas()->setCursor( zoomCursor );
01489     op = ZoomId;
01490   }
01491   else if ( btn == panBtn ) {
01492     myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
01493     op = PanId;
01494   }
01495   else if ( btn == fitBtn ) {
01496     myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
01497     op = FitAreaId;
01498   }
01499   return op;
01500 }
01501 
01505 void Plot2d_ViewFrame::onSettings()
01506 {
01507 #ifdef TEST_AUTOASSIGN
01508   typedef QMap<int,int> IList;
01509   typedef QMap<QString,int> SList;
01510   IList mars, lins;
01511   SList cols;
01512   cols[ "red-min" ]   = 1000;
01513   cols[ "red-max" ]   = -1;
01514   cols[ "green-min" ] = 1000;
01515   cols[ "green-max" ] = -1;
01516   cols[ "blue-min" ]  = 1000;
01517   cols[ "blue-max" ]  = -1;
01518   for ( unsigned i = 0; i < 10000; i++ ) {
01519     QwtSymbol::Style typeMarker;
01520     QColor           color;
01521     Qt::PenStyle     typeLine;
01522     myPlot->getNextMarker( typeMarker, color, typeLine );
01523     if ( mars.contains(typeMarker) )
01524       mars[ typeMarker ] = mars[ typeMarker ]+1;
01525     else
01526       mars[ typeMarker ] = 0;
01527     if ( lins.contains(typeLine) )
01528       lins[ typeLine ] = lins[ typeLine ]+1;
01529     else
01530       lins[ typeLine ] = 0;
01531     if ( cols[ "red-max" ] < color.red() )
01532       cols[ "red-max" ] = color.red();
01533     if ( cols[ "red-min" ] > color.red() )
01534       cols[ "red-min" ] = color.red();
01535     if ( cols[ "green-max" ] < color.green() )
01536       cols[ "green-max" ] = color.green();
01537     if ( cols[ "green-min" ] > color.green() )
01538       cols[ "green-min" ] = color.green();
01539     if ( cols[ "blue-max" ] < color.blue() )
01540       cols[ "blue-max" ] = color.blue();
01541     if ( cols[ "blue-min" ] > color.blue() )
01542       cols[ "blue-min" ] = color.blue();
01543   }
01544 #endif
01545   
01546   Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
01547   dlg->setMainTitle( myTitleEnabled, myTitle );
01548   dlg->setXTitle( myXTitleEnabled, myXTitle );
01549   dlg->setYTitle( myYTitleEnabled, myYTitle );
01550   if (mySecondY)
01551     dlg->setY2Title( myY2TitleEnabled, myY2Title );
01552   dlg->setCurveType( myCurveType );
01553   dlg->setLegend( myShowLegend, myLegendPos, myLegendFont, myLegendColor );
01554   dlg->setMarkerSize( myMarkerSize );
01555   dlg->setBackgroundColor( myBackground );
01556   dlg->setScaleMode(myXMode, myYMode);
01557   dlg->setLMinNormMode(myNormLMin);
01558   dlg->setLMaxNormMode(myNormLMax);
01559   dlg->setRMinNormMode(myNormRMin);
01560   dlg->setRMaxNormMode(myNormRMax);
01561 
01562   QVariant v = myPlot->property(PLOT2D_DEVIATION_LW);
01563   int lw = v.isValid() ? v.toInt() : 1;
01564 
01565   v = myPlot->property(PLOT2D_DEVIATION_TS);
01566   int ts = v.isValid() ? v.toInt() : 2;
01567 
01568   v = myPlot->property(PLOT2D_DEVIATION_COLOR);
01569   QColor cl =  v.isValid() ? v.value<QColor>() : QColor(255,0,0);
01570 
01571   dlg->setDeviationMarkerLw(lw);
01572   dlg->setDeviationMarkerTs(ts);
01573   dlg->setDeviationMarkerCl(cl);
01574 
01575   //
01576   dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
01577          myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
01578          myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
01579   dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
01580          myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
01581          myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
01582   if ( dlg->exec() == QDialog::Accepted ) {
01583     // horizontal axis title
01584     setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
01585     // vertical left axis title
01586     setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
01587     if (mySecondY) // vertical right axis title
01588       setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
01589 
01590     // main title
01591     if( dlg->isMainTitleEnabled() && myTitle != dlg->getMainTitle() ) 
01592       myIsDefTitle = false;
01593     setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
01594     // curve type
01595     if ( myCurveType != dlg->getCurveType() ) {
01596       setCurveType( dlg->getCurveType(), false );
01597     }
01598     // legend
01599     if ( myShowLegend != dlg->isLegendEnabled() ) {
01600       showLegend( dlg->isLegendEnabled(), false );
01601     }
01602     if ( myLegendPos != dlg->getLegendPos() ) {
01603       setLegendPos( dlg->getLegendPos() );
01604     }
01605        if ( myLegendFont != dlg->getLegendFont() ) {
01606       setLegendFont( dlg->getLegendFont() );
01607     }
01608        if ( myLegendColor != dlg->getLegendColor() ) {
01609       setLegendFontColor( dlg->getLegendColor() );
01610     }
01611 
01612     // marker size
01613     if ( myMarkerSize != dlg->getMarkerSize() ) {
01614       setMarkerSize( dlg->getMarkerSize(), false );
01615     }
01616     // background color
01617     if ( myBackground != dlg->getBackgroundColor() ) {
01618       setBackgroundColor( dlg->getBackgroundColor() );
01619     }
01620     // grid
01621     bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
01622          aY2GridMajorEnabled, aY2GridMinorEnabled;
01623     int  aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
01624          aY2GridMaxMajor, aY2GridMaxMinor;
01625     dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
01626                        aY2GridMajorEnabled, aY2GridMaxMajor);
01627     dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
01628                        aY2GridMinorEnabled, aY2GridMaxMinor);
01629     setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
01630     setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
01631               aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
01632     if ( myXMode != dlg->getXScaleMode() ) {
01633       setHorScaleMode( dlg->getXScaleMode() );
01634     }
01635     if ( myYMode != dlg->getYScaleMode() ) {
01636       setVerScaleMode( dlg->getYScaleMode() );
01637     }
01638     if ( myNormLMin != dlg->getLMinNormMode() ) {
01639       setNormLMinMode( dlg->getLMinNormMode() );
01640     }
01641     if ( myNormLMax != dlg->getLMaxNormMode() ) {
01642       setNormLMaxMode( dlg->getLMaxNormMode() );
01643     }
01644     if ( myNormRMin != dlg->getRMinNormMode() ) {
01645       setNormRMinMode( dlg->getRMinNormMode() );
01646     }
01647     if ( myNormRMax != dlg->getRMaxNormMode() ) {
01648       setNormRMaxMode( dlg->getRMaxNormMode() );
01649     }
01650 
01651     myPlot->setProperty(PLOT2D_DEVIATION_COLOR, 
01652                         dlg->getDeviationMarkerCl());
01653     myPlot->setProperty(PLOT2D_DEVIATION_LW, 
01654                         dlg->getDeviationMarkerLw());
01655     myPlot->setProperty(PLOT2D_DEVIATION_TS, 
01656                          dlg->getDeviationMarkerTs());
01657 
01658 
01659     // update view
01660     myPlot->replot();
01661     // update preferences
01662     if ( dlg->isSetAsDefault() ) 
01663       writePreferences();
01664   }
01665   delete dlg;
01666 }
01667 
01671 void Plot2d_ViewFrame::onAnalyticalCurve()
01672 {
01673 #ifndef DISABLE_PYCONSOLE
01674   Plot2d_AnalyticalCurveDlg dlg( this, this );
01675   dlg.exec();
01676   updateAnalyticalCurves();
01677 #endif
01678 }
01679 
01680 void Plot2d_ViewFrame::addAnalyticalCurve( Plot2d_AnalyticalCurve* theCurve)
01681 {
01682 #ifndef DISABLE_PYCONSOLE
01683        myAnalyticalCurves.append(theCurve);
01684 #endif
01685 }
01686 
01687 void Plot2d_ViewFrame::removeAnalyticalCurve( Plot2d_AnalyticalCurve* theCurve)
01688 {
01689 #ifndef DISABLE_PYCONSOLE
01690        theCurve->setAction(Plot2d_AnalyticalCurve::ActRemoveFromView);
01691 #endif
01692 }
01693 
01694 /*
01695   Update Analytical curve
01696 */
01697 void Plot2d_ViewFrame::updateAnalyticalCurve(Plot2d_AnalyticalCurve* c, bool updateView)
01698 {
01699 #ifndef DISABLE_PYCONSOLE
01700   if(!c) return;
01701   QwtScaleDiv* div = myPlot->axisScaleDiv(QwtPlot::xBottom);
01702   c->setRangeBegin(div->lowerBound());
01703   c->setRangeEnd(div->upperBound());
01704   c->calculate();
01705   c->setMarkerSize(myMarkerSize);
01706   QwtPlotItem* item = c->plotItem();
01707   
01708   switch( c->getAction() ) {
01709   case Plot2d_AnalyticalCurve::ActAddInView:
01710     if( c->isActive() ) {
01711       c->updatePlotItem();
01712       item->attach( myPlot );
01713       item->show();
01714     }
01715     c->setAction(Plot2d_AnalyticalCurve::ActNothing);
01716     break;
01717     
01718   case Plot2d_AnalyticalCurve::ActUpdateInView:
01719     if(c->isActive()) {
01720       c->updatePlotItem();
01721       item->show();
01722     } else {      
01723       item->hide();
01724       item->detach();
01725     }
01726     
01727     c->setAction(Plot2d_AnalyticalCurve::ActNothing);
01728     break;    
01729   case Plot2d_AnalyticalCurve::ActRemoveFromView:
01730     item->hide();
01731     item->detach();
01732     myAnalyticalCurves.removeAll(c);
01733     delete c;
01734     break;
01735   }
01736 
01737   if(updateView)
01738     myPlot->replot();
01739 #endif
01740 }
01741 
01742 /*
01743   Update Analytical curves
01744 */
01745 void Plot2d_ViewFrame::updateAnalyticalCurves()
01746 {
01747 #ifndef DISABLE_PYCONSOLE
01748   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
01749   for( ; it != myAnalyticalCurves.end(); it++) {
01750     updateAnalyticalCurve(*it);
01751   }
01752   myPlot->replot();
01753 #endif
01754 }
01755 
01759 AnalyticalCurveList Plot2d_ViewFrame::getAnalyticalCurves() const
01760 {
01761   return myAnalyticalCurves;
01762 }
01763 
01767 Plot2d_AnalyticalCurve* Plot2d_ViewFrame::getAnalyticalCurve(QwtPlotItem * theItem) {
01768 #ifndef DISABLE_PYCONSOLE
01769   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
01770   for( ; it != myAnalyticalCurves.end(); it++) {
01771     if((*it)->plotItem() == theItem);
01772               return (*it);
01773   }
01774   return 0;
01775 #endif
01776 }
01777 
01781 void Plot2d_ViewFrame::onFitData()
01782 {
01783   Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
01784   double xMin,xMax,yMin,yMax,y2Min,y2Max;
01785   getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
01786   
01787   dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
01788   if ( dlg->exec() == QDialog::Accepted ) {
01789     int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
01790     fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
01791   }
01792   delete dlg;
01793   updateAnalyticalCurves();
01794 }
01795 
01799 void Plot2d_ViewFrame::onChangeBackground()
01800 {
01801   QColor selColor = QColorDialog::getColor ( backgroundColor(), this ); 
01802   if ( selColor.isValid() ) {
01803     setBackgroundColor( selColor );
01804   }
01805 }
01806 
01810 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
01811 {
01812   myCurveType = curveType;
01813   CurveDict aCurves = getCurves();
01814   CurveDict::iterator it = aCurves.begin();
01815   for ( ; it != aCurves.end(); it++ ) {
01816     QwtPlotCurve* crv = it.key();
01817     if ( crv )
01818       setCurveType( crv, myCurveType );
01819   }
01820   if ( update )
01821     myPlot->replot();
01822   emit vpCurveChanged();
01823 }
01824 
01828 int Plot2d_ViewFrame::getCurveType() const
01829 {
01830   return myCurveType;
01831 }
01832 
01838 void Plot2d_ViewFrame::setCurveTitle( Plot2d_Curve* curve, const QString& title ) 
01839 {
01840   setObjectTitle( curve, title );
01841 }
01842 
01848 void Plot2d_ViewFrame::setObjectTitle( Plot2d_Object* object, const QString& title ) 
01849 { 
01850   if ( object && hasPlotObject( object ) )
01851     getPlotObject( object )->setTitle( title );
01852 }   
01853 
01857 void Plot2d_ViewFrame::showLegend( bool show, bool update )
01858 {
01859   myShowLegend = show;
01860   if ( myShowLegend ) {
01861     QwtLegend* legend = myPlot->legend();
01862     if ( !legend ) {
01863       legend = new QwtLegend( myPlot );
01864       legend->setFrameStyle( QFrame::Box | QFrame::Sunken );      
01865     }
01866     legend->setItemMode( QwtLegend::ClickableItem );
01867     myPlot->insertLegend( legend );
01868     setLegendPos( myLegendPos );
01869     setLegendFont( myLegendFont );
01870     setLegendFontColor( myLegendColor );  
01871   }
01872   else
01873     myPlot->insertLegend( 0 );
01874   if ( update )
01875     myPlot->replot();
01876 }
01877 
01881 void Plot2d_ViewFrame::setLegendPos( int pos )
01882 {
01883   myLegendPos = pos;
01884   QwtLegend* legend = myPlot->legend();
01885   if ( legend ) {
01886     switch( pos ) {
01887     case 0:
01888       myPlot->insertLegend( legend, QwtPlot::LeftLegend );
01889       break;
01890     case 1:
01891       myPlot->insertLegend( legend, QwtPlot::RightLegend );
01892       break;
01893     case 2:
01894       myPlot->insertLegend( legend, QwtPlot::TopLegend );
01895       break;
01896     case 3:
01897       myPlot->insertLegend( legend, QwtPlot::BottomLegend );
01898       break;
01899     }
01900   }
01901 }
01902 
01906 int Plot2d_ViewFrame::getLegendPos() const
01907 {
01908   return myLegendPos;
01909 }
01910 
01914 void Plot2d_ViewFrame::setLegendFont( const QFont& fnt )
01915 {
01916   myLegendFont = fnt;
01917   QwtLegend* legend = myPlot->legend();
01918   if ( legend ) {
01919     legend->setFont(fnt);
01920   }
01921 }
01922 
01926 QFont Plot2d_ViewFrame::getLegendFont() const
01927 {
01928   return myLegendFont;
01929 }
01930 
01934 QColor Plot2d_ViewFrame::getLegendFontColor() const
01935 {
01936   return myLegendColor;
01937 }
01938 
01942 void Plot2d_ViewFrame::setLegendFontColor( const QColor& col )
01943 {
01944   myLegendColor = col;
01945   QwtLegend* legend = myPlot->legend();
01946   if ( legend ) {
01947     QPalette pal = legend->palette();
01948     pal.setColor( QPalette::Text, col );
01949     legend->setPalette( pal );
01950   }
01951 }
01952 
01956 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
01957 {
01958   if ( myMarkerSize != size )
01959   {
01960     myMarkerSize = size;
01961     CurveDict aCurves = getCurves();
01962     CurveDict::iterator it = aCurves.begin();
01963     for ( ; it != aCurves.end(); it++ ) {
01964       QwtPlotCurve* crv = it.key();
01965       if ( crv )
01966       {
01967         QwtSymbol aSymbol = crv->symbol();
01968         aSymbol.setSize( myMarkerSize, myMarkerSize );
01969         crv->setSymbol( aSymbol );
01970        if(it.value())
01971          it.value()->setMarkerSize( myMarkerSize );
01972       }
01973     }
01974     if ( update )
01975       myPlot->replot();
01976   }
01977 }
01978 
01982 int Plot2d_ViewFrame::getMarkerSize() const
01983 {
01984   return myMarkerSize;
01985 }
01986 
01990 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
01991 {
01992   myBackground = color;
01993   myPlot->canvas()->setPalette( myBackground );
01994   myPlot->setPalette( myBackground );
01995   if ( myPlot->getLegend() ) {
01996     QPalette aPal = myPlot->getLegend()->palette();
01997     for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
01998       aPal.setColor( QPalette::Base, myBackground );
01999       aPal.setColor( QPalette::Background, myBackground );
02000     }
02001     myPlot->getLegend()->setPalette( aPal );
02002     updateLegend();
02003   }
02004   Repaint();
02005 }
02009 QColor Plot2d_ViewFrame::backgroundColor() const
02010 {
02011   return myBackground;
02012 }
02016 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax, 
02017          bool xMinorEnabled, const int xMinorMax, 
02018          bool update )
02019 {
02020   myXGridMajorEnabled = xMajorEnabled;
02021   myXGridMinorEnabled = xMinorEnabled;
02022   myXGridMaxMajor = xMajorMax;
02023   myXGridMaxMinor = xMinorMax;
02024 
02025   myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
02026   myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
02027 
02028   QwtPlotGrid* grid = myPlot->grid();
02029   if ( myPlot->axisScaleDiv( QwtPlot::xBottom ) )
02030     grid->setXDiv( *myPlot->axisScaleDiv( QwtPlot::xBottom ) );
02031   grid->enableX( myXGridMajorEnabled );
02032   grid->enableXMin( myXGridMinorEnabled );
02033 
02034   if ( update )
02035     myPlot->replot();
02036 }
02040 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax, 
02041                                  bool yMinorEnabled, const int yMinorMax,
02042                                  bool y2MajorEnabled, const int y2MajorMax, 
02043                                  bool y2MinorEnabled, const int y2MinorMax, 
02044                                  bool update )
02045 {
02046   myYGridMajorEnabled = yMajorEnabled;
02047   myYGridMinorEnabled = yMinorEnabled;
02048   myYGridMaxMajor = yMajorMax;
02049   myYGridMaxMinor = yMinorMax;
02050 
02051   if (mySecondY) {
02052     myY2GridMajorEnabled = y2MajorEnabled;
02053     myY2GridMinorEnabled = y2MinorEnabled;
02054     myY2GridMaxMajor = y2MajorMax;
02055     myY2GridMaxMinor = y2MinorMax;
02056   }
02057   myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
02058   myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
02059 
02060   if (mySecondY) {
02061     myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
02062     myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
02063   }
02064 
02065   QwtPlotGrid* grid = myPlot->grid();
02066   if ( myPlot->axisScaleDiv( QwtPlot::yLeft ) )
02067     grid->setYDiv( *myPlot->axisScaleDiv( QwtPlot::yLeft ) );
02068 
02069   if (mySecondY) {
02070     if (myYGridMajorEnabled) {
02071       grid->enableY( myYGridMajorEnabled );
02072       grid->enableYMin( myYGridMinorEnabled );
02073     }
02074     else if (myY2GridMajorEnabled) {
02075       if ( myPlot->axisScaleDiv( QwtPlot::yRight ) )
02076         grid->setYDiv( *myPlot->axisScaleDiv( QwtPlot::yRight ) );
02077       grid->enableY( myY2GridMajorEnabled );
02078       grid->enableYMin( myY2GridMinorEnabled );
02079     }
02080     else {
02081       grid->enableY( false );
02082       grid->enableYMin( false );
02083     }
02084   }
02085   else {
02086     grid->enableY( myYGridMajorEnabled );
02087     grid->enableYMin( myYGridMinorEnabled );
02088   }
02089   if ( update )
02090     myPlot->replot();
02091 }
02092 
02096 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
02097                                  ObjectType type, bool update )
02098 {
02099   switch (type) {
02100     case MainTitle:
02101       myTitleEnabled = enabled;
02102       myTitle = title;
02103       myPlot->setTitle( myTitleEnabled ? myTitle : QString() );
02104       break;
02105     case XTitle:
02106       myXTitleEnabled = enabled;
02107       myXTitle = title;
02108       myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString() );
02109       break;
02110     case YTitle:
02111       myYTitleEnabled = enabled;
02112       myYTitle = title;
02113       myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString() );
02114       break;
02115     case Y2Title:
02116       myY2TitleEnabled = enabled;
02117       myY2Title = title;
02118       myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString() );
02119       break;
02120     default:
02121       break;
02122   }
02123   if ( update )
02124     myPlot->replot();
02125 }
02129 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
02130 {
02131   QString title = "";
02132   switch (type) {
02133     case MainTitle:
02134       title = myTitle;   break;
02135     case XTitle:
02136       title = myXTitle;  break;
02137     case YTitle:
02138       title = myYTitle;  break;
02139     case Y2Title:
02140       title = myY2Title; break;
02141     default:
02142       break;
02143   }
02144   return title;
02145 }
02149 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
02150 {
02151   switch (type) {
02152     case MainTitle:
02153       myPlot->title().setFont(font);
02154       break;
02155     case XTitle:
02156        myPlot->axisTitle(QwtPlot::xBottom).setFont(font); break;
02157     case YTitle:
02158       myPlot->axisTitle(QwtPlot::yLeft).setFont(font);    break;
02159     case Y2Title:
02160       myPlot->axisTitle(QwtPlot::yRight).setFont(font);   break;
02161     case XAxis:
02162       myPlot->setAxisFont(QwtPlot::xBottom, font);        break;
02163     case YAxis:
02164       myPlot->setAxisFont(QwtPlot::yLeft, font);          break;
02165     case Y2Axis:
02166       myPlot->setAxisFont(QwtPlot::yRight, font);         break;
02167   }
02168   if ( update )
02169     myPlot->replot();
02170 }
02171 
02175 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
02176 {
02177   if ( myXMode == mode )
02178     return;
02179 
02180   // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
02181   // it crashes if switched to X/Y logarithmic mode, when one or more points have
02182   // non-positive X/Y coordinate
02183   if ( mode && !isXLogEnabled() ){
02184     SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"));
02185     return;
02186   }
02187 
02188   myXMode = mode;
02189 
02190   myPlot->setLogScale(QwtPlot::xBottom, myXMode != 0);
02191 
02192   if ( update )
02193     fitAll();
02194   emit vpModeHorChanged();
02195 }
02196 
02200 int Plot2d_ViewFrame::getHorScaleMode() const
02201 {
02202   return myXMode;
02203 }
02204 
02208 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
02209 {
02210   if ( myYMode == mode )
02211     return;
02212 
02213   // san -- Protection against QwtCurve bug in Qwt 0.4.x: 
02214   // it crashes if switched to X/Y logarithmic mode, when one or more points have
02215   // non-positive X/Y coordinate
02216   if ( mode && !isYLogEnabled() ){
02217     SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"));
02218     return;
02219   }
02220 
02221   myYMode = mode;
02222   myPlot->setLogScale(QwtPlot::yLeft, myYMode != 0);
02223   if (mySecondY)
02224     myPlot->setLogScale( QwtPlot::yRight, myYMode != 0 );
02225 
02226   if ( update )
02227     fitAll();
02228   emit vpModeVerChanged();
02229 }
02230 
02234 int Plot2d_ViewFrame::getVerScaleMode() const
02235 {
02236   return myYMode;
02237 }
02238 
02242 void Plot2d_ViewFrame::setNormLMaxMode( bool mode, bool update )
02243 {
02244   if ( myNormLMax == mode )
02245     return;
02246 
02247   myNormLMax = mode;
02248   processFiltering(true);
02249   if ( update )
02250     fitAll();
02251   emit vpNormLModeChanged();
02252 }
02253 
02257 bool Plot2d_ViewFrame::getNormLMaxMode() const
02258 {
02259   return myNormLMax;
02260 }
02261 
02265 void Plot2d_ViewFrame::setNormLMinMode( bool mode, bool update )
02266 {
02267   if ( myNormLMin == mode )
02268     return;
02269 
02270   myNormLMin = mode;
02271   processFiltering(true);
02272   if ( update )
02273     fitAll();
02274   emit vpNormLModeChanged();
02275 }
02276 
02280 bool Plot2d_ViewFrame::getNormLMinMode() const
02281 {
02282   return myNormLMax;
02283 }
02284 
02288 void Plot2d_ViewFrame::setNormRMaxMode( bool mode, bool update )
02289 {
02290   if ( myNormRMax == mode )
02291     return;
02292 
02293   myNormRMax = mode;
02294   processFiltering(true);
02295   if ( update )
02296     fitAll();
02297   emit vpNormRModeChanged();
02298 }
02299 
02303 bool Plot2d_ViewFrame::getNormRMaxMode() const
02304 {
02305   return myNormRMax;
02306 }
02307 
02311 void Plot2d_ViewFrame::setNormRMinMode( bool mode, bool update )
02312 {
02313   if ( myNormRMin == mode )
02314     return;
02315 
02316   myNormRMin = mode;
02317   processFiltering(true);
02318   if ( update )
02319     fitAll();
02320   emit vpNormRModeChanged();
02321 }
02322 
02326 bool Plot2d_ViewFrame::getNormRMinMode() const
02327 {
02328   return myNormRMax;
02329 }
02330 
02334 bool Plot2d_ViewFrame::isModeHorLinear()
02335 {
02336   return (myXMode == 0 ? true : false);
02337 }
02338 
02342 bool Plot2d_ViewFrame::isModeVerLinear()
02343 {
02344   return (myYMode == 0 ? true : false);
02345 }
02346 
02350 bool Plot2d_ViewFrame::isNormLMaxMode()
02351 {
02352   return (myNormLMax ? true : false);
02353 }
02354 
02358 bool Plot2d_ViewFrame::isNormLMinMode()
02359 {
02360   return (myNormLMin ? true : false);
02361 }
02362 
02366 bool Plot2d_ViewFrame::isNormRMaxMode()
02367 {
02368   return (myNormRMax ? true : false);
02369 }
02370 
02374 bool Plot2d_ViewFrame::isNormRMinMode()
02375 {
02376   return (myNormRMin ? true : false);
02377 }
02378 
02382 bool Plot2d_ViewFrame::isLegendShow() const
02383 {
02384   return myShowLegend;
02385 }
02386 
02390 void Plot2d_ViewFrame::plotMousePressed( const QMouseEvent& me )
02391 {
02392   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
02393   if (aParent)
02394      aParent->putInfo(getInfo(me.pos()));
02395   if ( myOperation == NoOpId )
02396     myOperation = testOperation( me );
02397   if ( myOperation != NoOpId ) {
02398     myPnt = me.pos();
02399     if ( myOperation == GlPanId ) {
02400       myPlot->setAxisScale( QwtPlot::yLeft,
02401           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2, 
02402           myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2 );
02403       myPlot->setAxisScale( QwtPlot::xBottom, 
02404           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2, 
02405           myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
02406       if (mySecondY)
02407         myPlot->setAxisScale( QwtPlot::yRight,
02408           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2, 
02409           myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2 );
02410       myPlot->replot();
02411     }
02412   }
02413   else {
02414     int btn = me.button() | me.modifiers();
02415     if (btn == Qt::RightButton) {
02416       QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
02417                                             me.pos(), me.button(), me.buttons(), me.modifiers() );
02418       // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
02419       parent()->eventFilter(this, aEvent);
02420     }
02421   }
02422   setFocus(); 
02423 }
02427 bool Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
02428 {
02429   int    dx = me.pos().x() - myPnt.x();
02430   int    dy = me.pos().y() - myPnt.y();
02431 
02432   bool aRes = false;
02433   if ( myOperation != NoOpId) {
02434     if ( myOperation == ZoomId ) {
02435       this->incrementalZoom( dx, dy ); 
02436       myPnt = me.pos();
02437       aRes = true;
02438     }
02439     else if ( myOperation == PanId ) {
02440       this->incrementalPan( dx, dy );
02441       myPnt = me.pos();
02442       aRes = true;
02443     }
02444   }
02445   else {
02446      Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
02447      if (aParent)
02448        aParent->putInfo(getInfo(me.pos()));
02449   }
02450   return aRes;
02451 }
02455 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
02456 {
02457   if ( myOperation == NoOpId && me.button() == Qt::RightButton && me.modifiers() != Qt::ControlModifier )
02458   {
02459     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
02460                               me.pos(), me.globalPos() );
02461     emit contextMenuRequested( &aEvent );
02462   } 
02463   else {
02464     updateAnalyticalCurves();
02465   }
02466   myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
02467   myPlot->defaultPicker();
02468 
02469   Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
02470    if (aParent)
02471      aParent->putInfo(tr("INF_READY"));
02472   myOperation = NoOpId;
02473 }
02477 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
02478 { 
02479   double aDelta = event->delta();
02480   double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
02481 
02482   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
02483   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
02484 
02485   if ( ((yMap.s2() - yMap.s1()) < 10e-13 || (xMap.s2() - xMap.s1()) < 10e-13 ) && aScale < 1 )
02486     return;
02487 
02488   myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(), yMap.s1() + aScale*(yMap.s2() - yMap.s1()) );
02489   myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(), xMap.s1() + aScale*(xMap.s2() - xMap.s1()) );
02490   if (mySecondY) {
02491     QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
02492     if ( ((y2Map.s2() - y2Map.s1()) < 10e-13  ) && aScale < 1 ) return;
02493     myPlot->setAxisScale( QwtPlot::yRight, y2Map.s1(), y2Map.s1() + aScale*(y2Map.s2() - y2Map.s1()) );
02494   }
02495   myPlot->replot();
02496   if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
02497   myPnt = event->pos();
02498   updateAnalyticalCurves();
02499 }
02500 
02504 QwtPlotCurve* Plot2d_ViewFrame::getPlotCurve( Plot2d_Curve* curve ) const
02505 {
02506   return dynamic_cast<QwtPlotCurve*>( getPlotObject( curve ) );
02507 }
02511 bool Plot2d_ViewFrame::hasPlotCurve( Plot2d_Curve* curve ) const
02512 {
02513   return hasPlotObject( curve );
02514 }
02515 
02519 QwtPlotItem* Plot2d_ViewFrame::getPlotObject( Plot2d_Object* object ) const
02520 {
02521   ObjectDict::const_iterator it = myObjects.begin();
02522   for ( ; it != myObjects.end(); it++ ) {
02523     if ( it.value() == object )
02524       return it.key();
02525   }
02526   return 0;
02527 }
02531 bool Plot2d_ViewFrame::hasPlotObject( Plot2d_Object* object ) const
02532 {
02533   ObjectDict::const_iterator it = myObjects.begin();
02534   for ( ; it != myObjects.end(); it++ ) {
02535     if ( it.value() == object )
02536       return true;
02537   }
02538   return false;
02539 }
02540 
02544 void Plot2d_ViewFrame::setCurveType( QwtPlotCurve* curve, int curveType )
02545 {
02546   if ( !curve )
02547     return;
02548   if ( myCurveType == 0 )
02549     curve->setStyle( QwtPlotCurve::Dots );//QwtCurve::NoCurve
02550   else if ( myCurveType == 1 ) {
02551     curve->setStyle( QwtPlotCurve::Lines );
02552     curve->setCurveAttribute( QwtPlotCurve::Fitted, false );
02553   }
02554   else if ( myCurveType == 2 ) {
02555     curve->setStyle( QwtPlotCurve::Lines );
02556     QwtSplineCurveFitter* fitter = new QwtSplineCurveFitter();
02557     fitter->setSplineSize( 250 );
02558     curve->setCurveAttribute( QwtPlotCurve::Fitted, true );
02559     curve->setCurveFitter( fitter );
02560   }
02561 }
02562 
02566 void Plot2d_ViewFrame::onViewPan()
02567 { 
02568   QCursor panCursor (Qt::SizeAllCursor);
02569   myPlot->canvas()->setCursor( panCursor );
02570   myOperation = PanId;
02571 }
02575 void Plot2d_ViewFrame::onViewZoom() 
02576 {
02577   QPixmap zoomPixmap (imageZoomCursor);
02578   QCursor zoomCursor (zoomPixmap);
02579   myPlot->canvas()->setCursor( zoomCursor );
02580   myOperation = ZoomId;
02581 }
02585 void Plot2d_ViewFrame::onViewFitAll() 
02586 { 
02587   fitAll();
02588 }
02592 void Plot2d_ViewFrame::onViewFitArea() 
02593 {
02594   myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
02595   myOperation = FitAreaId;
02596   myPlot->setPickerMousePattern( Qt::LeftButton );
02597 }
02601 void Plot2d_ViewFrame::onViewGlobalPan() 
02602 {
02603   QPixmap globalPanPixmap (imageCrossCursor);
02604   QCursor glPanCursor (globalPanPixmap);
02605   myPlot->canvas()->setCursor( glPanCursor );
02606   myPlot->setLogScale(QwtPlot::xBottom, false);
02607   myPlot->setLogScale(QwtPlot::yLeft, false);
02608   if (mySecondY)
02609     myPlot->setLogScale(QwtPlot::yRight, false);
02610   myPlot->replot();
02611   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
02612   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
02613 
02614   myXDistance = xMap.s2() - xMap.s1();
02615   myYDistance = yMap.s2() - yMap.s1();
02616 
02617   if (mySecondY) {
02618     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
02619     myYDistance2 = yMap2.s2() - yMap2.s1();
02620   }
02621   fitAll();
02622   myOperation = GlPanId;
02623 }
02624 
02628 bool Plot2d_ViewFrame::isXLogEnabled() const
02629 {
02630   bool allPositive = true;
02631   ObjectDict::const_iterator it = myObjects.begin();
02632   for ( ; allPositive && it != myObjects.end(); it++ )
02633     allPositive = ( it.value()->getMinX() > 0. );
02634   return allPositive;
02635 }
02636 
02640 bool Plot2d_ViewFrame::isYLogEnabled() const
02641 {
02642   bool allPositive = true;
02643   ObjectDict::const_iterator it = myObjects.begin();
02644   for ( ; allPositive && it != myObjects.end(); it++ )
02645     allPositive = ( it.value()->getMinY() > 0. );
02646   return allPositive;
02647 }
02648 
02652 void Plot2d_ViewFrame::setEnableAxis( QwtPlot::Axis theAxis, bool isEnable )
02653 {
02654   if ( myPlot->axisEnabled( theAxis ) == isEnable )
02655     return;
02656   myPlot->enableAxis( theAxis, isEnable );
02657   if ( theAxis == QwtPlot::yRight )
02658     mySecondY = isEnable;
02659 }
02660 
02661 class Plot2d_QwtPlotZoomer : public QwtPlotZoomer
02662 {
02663 public:
02664   Plot2d_QwtPlotZoomer( int xAxis, int yAxis, QwtPlotCanvas* canvas )
02665   : QwtPlotZoomer( xAxis, yAxis, canvas )
02666   {
02667     qApp->installEventFilter( this );
02668     // now picker working after only a button pick.
02669     // after click on button FitArea in toolbar of the ViewFrame.
02670   };
02671   ~Plot2d_QwtPlotZoomer() {};
02672 };
02673 
02677 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
02678   : QwtPlot( parent ),
02679     myIsPolished( false )
02680 {
02681   // Create alternative scales
02682   setAxisScaleDraw( QwtPlot::yLeft,   new Plot2d_ScaleDraw() );
02683   setAxisScaleDraw( QwtPlot::xBottom, new Plot2d_ScaleDraw() );
02684   setAxisScaleDraw( QwtPlot::yRight,  new Plot2d_ScaleDraw() );
02685 
02686   myPlotZoomer = new Plot2d_QwtPlotZoomer( QwtPlot::xBottom, QwtPlot::yLeft, canvas() );
02687   myPlotZoomer->setSelectionFlags( QwtPicker::DragSelection | QwtPicker::CornerToCorner );
02688   myPlotZoomer->setTrackerMode( QwtPicker::AlwaysOff );
02689   myPlotZoomer->setRubberBand( QwtPicker::RectRubberBand );
02690   myPlotZoomer->setRubberBandPen( QColor( Qt::green ) );
02691 
02692   defaultPicker();
02693 
02694   // auto scaling by default
02695   setAxisAutoScale( QwtPlot::yLeft );
02696   setAxisAutoScale( QwtPlot::yRight );
02697   setAxisAutoScale( QwtPlot::xBottom );
02698 
02699 // grid
02700   myGrid = new QwtPlotGrid();
02701   QPen aMajPen = myGrid->majPen();
02702   aMajPen.setStyle( Qt::DashLine );
02703   myGrid->setPen( aMajPen );
02704 
02705   myGrid->enableX( false );
02706   myGrid->enableXMin( false );
02707   myGrid->enableY( false );
02708   myGrid->enableYMin( false );
02709 
02710   myGrid->attach( this );
02711 
02712   setMouseTracking( false );
02713   canvas()->setMouseTracking( true );
02714 
02715   myPlotZoomer->setEnabled( true );
02716   myPlotZoomer->setZoomBase();
02717 
02718   setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
02719 }
02720 
02721 Plot2d_Plot2d::~Plot2d_Plot2d()
02722 {
02723 }
02724 
02728 void Plot2d_Plot2d::setLogScale( int axisId, bool log10 )
02729 {
02730   if ( log10 )
02731     setAxisScaleEngine( axisId, new QwtLog10ScaleEngine() );
02732   else
02733     setAxisScaleEngine( axisId, new QwtLinearScaleEngine() );
02734 }
02735 
02739 void Plot2d_Plot2d::replot()
02740 {
02741   // the following code is intended to enable only axes
02742   // that are really used by displayed objects
02743   bool enableXBottom = false, enableXTop   = false;
02744   bool enableYLeft   = false, enableYRight = false;
02745   const QwtPlotItemList& items = itemList();
02746   QwtPlotItemIterator it;
02747   for ( it = items.begin(); it != items.end(); it++ ) {
02748     QwtPlotItem* item = *it;
02749     if ( item ) {
02750       enableXBottom |= item->xAxis() == QwtPlot::xBottom;
02751       enableXTop    |= item->xAxis() == QwtPlot::xTop;
02752       enableYLeft   |= item->yAxis() == QwtPlot::yLeft;
02753       enableYRight  |= item->yAxis() == QwtPlot::yRight;
02754     }
02755   }
02756   enableAxis( QwtPlot::xBottom, enableXBottom );
02757   enableAxis( QwtPlot::xTop,    enableXTop );
02758   enableAxis( QwtPlot::yLeft,   enableYLeft );
02759   enableAxis( QwtPlot::yRight,  enableYRight );
02760 
02761   updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
02762   QwtPlot::replot(); 
02763 }
02764 
02768 QwtLegend* Plot2d_Plot2d::getLegend()
02769 {
02770 #if QWT_VERSION < 0x040200
02771   return d_legend;
02772 #else  
02773   return legend(); /* mpv: porting to the Qwt 4.2.0 */
02774 #endif
02775 }
02776 
02780 QSize Plot2d_Plot2d::sizeHint() const
02781 {
02782   return QwtPlot::minimumSizeHint();
02783 }
02784 
02788 QSize Plot2d_Plot2d::minimumSizeHint() const
02789 {
02790   return QSize( 0, 0 );
02791 //  QSize aSize = QwtPlot::minimumSizeHint();
02792 //  return QSize(aSize.width()*3/4, aSize.height());
02793 }
02794 
02795 void Plot2d_Plot2d::defaultPicker()
02796 {
02797   myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1,
02798                                  Qt::RightButton, Qt::ControlModifier ); // zooming button
02799   for ( int i = QwtEventPattern::MouseSelect2; i < QwtEventPattern::MouseSelect6; i++ )
02800     myPlotZoomer->setMousePattern( i, Qt::NoButton, Qt::NoButton );
02801 }
02802 
02803 void Plot2d_Plot2d::setPickerMousePattern( int button, int state )
02804 {
02805   myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1, button, state );
02806 }
02807 
02811 void Plot2d_Plot2d::createMarkerAndTooltip( QwtSymbol symbol,
02812                                             double    X,
02813                                             double    Y,
02814                                             QString & tooltip,
02815                                             Plot2d_QwtPlotPicker *picker)
02816 {
02817   QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
02818 
02819   aPlotMarker->setSymbol( symbol );  // symbol must have a color
02820   aPlotMarker->setLabelAlignment( Qt::AlignTop);
02821   aPlotMarker->setXValue(X);
02822   aPlotMarker->setYValue(Y);
02823   //
02824   aPlotMarker->attach(this);
02825                      
02826   // Associate a tooltip with the point's marker
02827   // PB: how to obtain a tooltip with a rectangular frame ?
02828   //QwtText tooltip ("X=" + QString::number(X) + " Y=" + QString::number(Y) );
02829 
02830   QwtText text (tooltip);
02831   //QColor tooltipColor( 245, 222, 179);            // Wheat  -RGB (0 a 255)
02832   QColor tooltipColor( 253, 245, 230);            // OldLace
02833   text.setBackgroundBrush( QBrush(tooltipColor)); //, Qt::SolidPattern));
02834   //
02835   picker->pMarkers.append( aPlotMarker); 
02836   picker->pMarkersToolTip[ aPlotMarker] = text;
02837 }
02838 
02839 bool Plot2d_Plot2d::polished() const
02840 {
02841   return myIsPolished;
02842 }
02843 
02844 QwtPlotGrid* Plot2d_Plot2d::grid() const
02845 {
02846   return myGrid;
02847 };
02848 
02849 QwtPlotZoomer* Plot2d_Plot2d::zoomer() const
02850 {
02851   return myPlotZoomer;
02852 }
02853 
02857 void Plot2d_Plot2d::onScaleDivChanged()
02858 {
02859   QwtScaleWidget* aSW = 0;
02860   if ( ( aSW = dynamic_cast<QwtScaleWidget*>(sender()) ) ) {
02861     int axisId = -1;
02862     switch ( aSW->alignment() ) {
02863     case QwtScaleDraw::BottomScale:
02864       axisId = QwtPlot::xBottom;
02865       break;
02866     case QwtScaleDraw::LeftScale:
02867       axisId = QwtPlot::yLeft;
02868       break;
02869     case QwtScaleDraw::RightScale:
02870       axisId = QwtPlot::yRight;
02871       break;
02872     default:
02873       break;
02874     }
02875 
02876     if ( axisId >= 0 ) {
02877       QwtScaleMap map = canvasMap(axisId);
02878       double aDist = fabs(map.s2()-map.s1()) / (axisMaxMajor(axisId)*axisMaxMinor(axisId));
02879 
02880       QString aDistStr;
02881       aDistStr.sprintf("%e",aDist);
02882       int aPrecision = aDistStr.right(aDistStr.length()-aDistStr.indexOf('e')-2).toInt();
02883 
02884       QwtScaleDraw* aQwtSD = axisScaleDraw(axisId);
02885       Plot2d_ScaleDraw* aPlot2dSD = dynamic_cast<Plot2d_ScaleDraw*>(aQwtSD);
02886       if ( ( !aPlot2dSD && aPrecision > 6 ) || ( aPlot2dSD && aPlot2dSD->precision() != aPrecision ) )
02887         setAxisScaleDraw( axisId, new Plot2d_ScaleDraw(*aQwtSD, 'f', aPrecision) );
02888     }
02889   }
02890 }
02891 
02895 void Plot2d_Plot2d::updateYAxisIdentifiers()
02896 {
02897   bool enableYLeft = false, enableYRight = false;
02898   const QwtPlotItemList& items = itemList();
02899   QwtPlotItemIterator it;
02900   for ( it = items.begin(); it != items.end(); it++ ) {
02901     QwtPlotItem* item = *it;
02902     if ( item ) {
02903       enableYLeft  |= item->yAxis() == QwtPlot::yLeft;
02904       enableYRight |= item->yAxis() == QwtPlot::yRight;
02905     }
02906   }
02907 
02908   // if several curves are attached to different axes
02909   // display corresponding identifiers in the legend,
02910   // otherwise hide them
02911   for ( it = items.begin(); it != items.end(); it++ ) {
02912     QwtPlotItem* item = *it;
02913     if ( Plot2d_QwtPlotCurve* aPCurve = dynamic_cast<Plot2d_QwtPlotCurve*>( item ) )
02914       aPCurve->setYAxisIdentifierEnabled( enableYLeft && enableYRight );
02915     if ( item && item->isVisible() && legend() )
02916       item->updateLegend( legend() );
02917   }
02918 }
02919 
02923 void Plot2d_Plot2d::polish()
02924 {
02925   QwtPlot::polish();
02926   myIsPolished = true;
02927 }
02928 
02929 // Methods to manage axis graduations
02930 
02931 /* Create definition and graduations of axes
02932  */
02933 void Plot2d_Plot2d::createAxisScaleDraw()
02934 {
02935   myScaleDraw = new Plot2d_AxisScaleDraw( this);
02936 }
02937 
02938 
02939 /* Stock X axis's ticks in the drawing zone
02940 */
02941 void Plot2d_Plot2d::applyTicks()
02942 {
02943   myScaleDraw->applyTicks();
02944 }
02945 
02946 
02947 /* Unactivate automatic ticks drawing (call to method Plot2d_AxisScaleDraw::draw() )
02948  * Parameters :
02949  * - number call to ticks drawing (for information) : numcall
02950  */
02951 void Plot2d_Plot2d::unactivAxisScaleDraw( int numcall)
02952 {
02953   // Memorize X axis (myScaleDraw already exists) in the drawing zone
02954   //setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw);  // heritage of QwtPlot
02955 
02956   myScaleDraw->unactivTicksDrawing( numcall);
02957 }
02958 
02959 
02960 /* Draw ticks and labels on X axis of the drawing zone
02961  * Draw systems' names under the X axis of the drawing zone
02962  * Draw vertical segments between X axis's intervals of the systems
02963  * Parameters :
02964  * - left and right margins for ticks : XLeftMargin, XRightMargin
02965  * - for each named system :
02966  *     positions and labels for ticksĀ on X axis : devicesPosLabelTicks
02967  *
02968  * The true drawings will be realized by the method Plot2d_AxisScaleDraw::draw()
02969  * PB: who call il ?
02970  */
02971 void Plot2d_Plot2d::displayXTicksAndLabels(
02972                       double XLeftMargin, double XRightMargin,
02973                       const QList< QPair< QString, QMap<double, QString> > > & devicesPosLabelTicks)
02974                       //                    name        position  label
02975                       //                   system         tick    tick
02976 {
02977   //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
02978 
02979   int nbDevices = devicesPosLabelTicks.size();
02980   //
02981   //std::cout << "  Nombre de systemes = " << nbDevices << std::endl;
02982   if (nbDevices == 0)  return;
02983 
02984   // For drawing systems' names, their positions must be in the allTicks list
02985   // (cf class Plot2d_AxisScaleDraw)
02986 
02987   // Liste of ticks' positions and systems' names
02988   QList<double> allTicks;
02989 
02990   double devXmin, devXmax;  // X interval of a system
02991   double gapXmin, gapXmax;  // X interval between two systems
02992   double devLabPos;         // Label's position of a system
02993   double segmentPos;  // Position of the vertical segment between current system and the next
02994 
02995   // 1)- Search for the system whose X interval is the most to the left
02996 
02997   int ileftDev = 0;
02998   double XminMin = 1.e+12;
02999 
03000   if (nbDevices > 1)
03001   {
03002       for (int idev=0; idev < nbDevices; idev++)
03003       {
03004           QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
03005 
03006           QString deviceLabel = paire.first;
03007 
03008           // Ticks' map of the system
03009           QMap<double,QString> devPosLabelTicks = paire.second;
03010 
03011           QList<double> posTicks = devPosLabelTicks.keys();
03012 
03013           // List's items increasing sorting
03014           qSort( posTicks.begin(), posTicks.end() );  // iterators
03015 
03016           // X interval for the system
03017           devXmin = posTicks.first();
03018           devXmax = posTicks.last();
03019 
03020           if (devXmin < XminMin)
03021           {
03022               XminMin = devXmin;
03023               ileftDev = idev;
03024           }
03025       }
03026   }
03027 
03028   // 2)- Ticks, systems' names, verticals segments
03029 
03030   for (int idev=0; idev < nbDevices; idev++)
03031   {
03032       QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
03033 
03034       QString deviceLabel = paire.first;
03035 
03036       std::string std_label = deviceLabel.toStdString();
03037       //const char *c_label = std_label.c_str();
03038       //std::cout << "  deviceLabel: |" << c_label << "|" << std::endl;
03039 
03040       // Ticks' map of the system
03041       QMap<double,QString> devPosLabelTicks = paire.second;
03042 
03043       int nbTicks = devPosLabelTicks.size();
03044 
03045       QList<double> posTicks = devPosLabelTicks.keys();
03046 
03047       // List's items increasing sorting
03048       qSort( posTicks.begin(), posTicks.end() );  // iterators
03049 
03050       // X interval for the system
03051       devXmin = posTicks.first();
03052       devXmax = posTicks.last();
03053 
03054       // Stock ticks' positions and labels on X axis
03055       double pos;
03056       QString label;
03057       //
03058       for (int itic=0; itic < nbTicks; itic++)
03059       {
03060           pos   = posTicks.at(itic);
03061           label = devPosLabelTicks[pos];
03062 
03063           myScaleDraw->setLabelTick( pos, label, false);
03064 
03065           std::string std_label = label.toStdString();
03066           //const char *c_label = std_label.c_str();
03067           //std::cout << "    tick " << itic << " : pos= " << pos << ", label= |" << c_label << "|" << std::endl;
03068       }
03069       allTicks.append( posTicks);
03070 
03071       // Compute the position of the system's label
03072       if (idev == ileftDev)
03073       {
03074           devLabPos = devXmin + 0.25*(devXmax - devXmin);
03075       }
03076       else
03077       {
03078           devLabPos = devXmin + 0.50*(devXmax - devXmin);
03079       }
03080       allTicks.append( devLabPos);
03081 
03082       // Stock position and name of the system under X axis
03083       myScaleDraw->setLabelTick( devLabPos, deviceLabel, true);
03084 
03085       if (idev > 0)
03086       {
03087           // Create the vertical segment between the current system and the next
03088           gapXmax = devXmin;
03089           segmentPos = gapXmin + 0.5*(gapXmax - gapXmin);
03090 
03091           createSeparationLine( segmentPos);
03092       }
03093       gapXmin = devXmax;
03094   }
03095 
03096   // List's items increasing sorting
03097   qSort( allTicks.begin(), allTicks.end() );  // iterators
03098 
03099   // Stock the interval of X's values
03100   double lowerBound = allTicks.first() - XLeftMargin;
03101   double upperBound = allTicks.last() + XRightMargin;
03102   myScaleDraw->setInterval( lowerBound, upperBound);
03103 
03104   // For each system, stock the position of the X's ticks and those of the name
03105   myScaleDraw->setTicks( allTicks);  // do not draw the ticks
03106 
03107   // Memorize the X axis in the drawing zone
03108   setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw);  // heritage of QwtPlot
03109 
03110   //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
03111 }
03112 
03113 
03114 /* Create vertical segment between two curves
03115  */
03116 void Plot2d_Plot2d::createSeparationLine( double Xpos)
03117 {
03118   QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
03119 
03120   aPlotMarker->setLineStyle( QwtPlotMarker::VLine);
03121   aPlotMarker->setXValue( Xpos);
03122   aPlotMarker->setLinePen( QPen(Qt::black));
03123   aPlotMarker->attach(this);  // Add to drawing zone
03124 }
03125 
03130 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
03131 {
03132   return 0;
03133 }
03134 
03139 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
03140 {
03141   if( !vf )
03142     return;
03143 
03144   myCurveType = vf->myCurveType;
03145   myShowLegend = vf->myShowLegend;
03146   myLegendPos = vf->myLegendPos;
03147   myMarkerSize = vf->myMarkerSize;
03148   myBackground = vf->myBackground;
03149   myTitle = vf->myTitle; 
03150   myXTitle = vf->myXTitle;
03151   myYTitle = vf->myYTitle;
03152   myY2Title = vf->myY2Title;
03153   myTitleEnabled = vf->myTitleEnabled;
03154   myXTitleEnabled = vf->myXTitleEnabled;
03155   myYTitleEnabled = vf->myYTitleEnabled;
03156   myY2TitleEnabled = vf->myY2TitleEnabled;
03157   myXGridMajorEnabled = vf->myXGridMajorEnabled;
03158   myYGridMajorEnabled = vf->myYGridMajorEnabled;
03159   myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
03160   myXGridMinorEnabled = vf->myXGridMinorEnabled;
03161   myYGridMinorEnabled = vf->myYGridMinorEnabled;
03162   myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
03163   myXGridMaxMajor = vf->myXGridMaxMajor;
03164   myYGridMaxMajor = vf->myYGridMaxMajor;
03165   myY2GridMaxMajor = vf->myY2GridMaxMajor;
03166   myXGridMaxMinor = vf->myXGridMaxMinor;
03167   myYGridMaxMinor = vf->myYGridMaxMinor;
03168   myY2GridMaxMinor = vf->myY2GridMaxMinor;
03169   myXMode = vf->myXMode;
03170   myYMode = vf->myYMode;
03171   mySecondY = vf->mySecondY;
03172 }
03173 
03177 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
03178 void Plot2d_ViewFrame::updateTitles() 
03179 {
03180   ObjectDict::iterator it = myObjects.begin();
03181   QStringList aXTitles;
03182   QStringList aYTitles;
03183   QStringList aY2Titles;
03184   QStringList aXUnits;
03185   QStringList aYUnits;
03186   QStringList aY2Units;
03187   QStringList aTables;
03188   int i = 0;
03189 
03190   Plot2d_Object* anObject;
03191   for ( ; it != myObjects.end(); it++ ) {
03192     // collect titles and units from all curves...
03193     anObject = it.value();
03194     QString xTitle = anObject->getHorTitle().trimmed();
03195     QString yTitle = anObject->getVerTitle().trimmed();
03196     QString xUnits = anObject->getHorUnits().trimmed();
03197     QString yUnits = anObject->getVerUnits().trimmed();
03198     
03199     if ( anObject->getYAxis() == QwtPlot::yLeft ) {
03200       if ( !aYTitles.contains( yTitle ) )
03201         aYTitles.append( yTitle );
03202       if ( !aYUnits.contains( yUnits ) )
03203         aYUnits.append( yUnits );
03204     }
03205     else {
03206       if ( !aY2Titles.contains( yTitle ) )
03207         aY2Titles.append( yTitle );
03208       if ( !aY2Units.contains( yUnits ) )
03209         aY2Units.append( yUnits );
03210     }
03211     if ( !aXTitles.contains( xTitle ) )
03212       aXTitles.append( xTitle );
03213     if ( !aXUnits.contains( xUnits ) )
03214       aXUnits.append( xUnits );
03215 
03216     QString aName = anObject->getTableTitle();
03217     if( !aName.isEmpty() && !aTables.contains( aName ) )
03218       aTables.append( aName );
03219     ++i;
03220   }
03221   // ... and update plot 2d view
03222   QString xUnits, yUnits, y2Units;
03223   if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
03224     xUnits = BRACKETIZE( aXUnits[0] );
03225   if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
03226     yUnits = BRACKETIZE( aYUnits[0] );
03227   if ( aY2Units.count() == 1 && !aY2Units[0].isEmpty())
03228     y2Units = BRACKETIZE( aY2Units[0] );
03229   QString xTitle, yTitle, y2Title;
03230   if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
03231     xTitle = aXTitles[0];
03232   if ( aYTitles.count() == 1 )
03233     yTitle = aYTitles[0];
03234   if ( mySecondY && aY2Titles.count() == 1 )
03235     y2Title = aY2Titles[0];
03236 
03237   if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
03238     xTitle += " ";
03239   if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
03240     yTitle += " ";
03241   if ( !y2Title.isEmpty() && !y2Units.isEmpty() )
03242     y2Title += " ";
03243 
03244   setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
03245   setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
03246   if ( mySecondY )
03247     setTitle( myY2TitleEnabled, y2Title + y2Units, Y2Title, true );
03248   if( myIsDefTitle ) 
03249     setTitle( true, aTables.join("; "), MainTitle, true );
03250 }
03251 
03257 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
03258 {
03259 #ifdef WIN32
03260   return false;
03261 
03262 #else
03263   bool res = false;
03264   if( myPlot )
03265   {
03266     QPaintDevice* pd = 0;
03267     if( format=="PS" || format=="EPS" )
03268     {
03269       QPrinter* pr = new QPrinter( QPrinter::HighResolution );
03270       pr->setPageSize( QPrinter::A4 );
03271       pr->setOutputFileName( file );
03272       pr->setPrintProgram( "" );
03273       pd = pr;
03274     }
03275 
03276     if( pd )
03277     {
03278       myPlot->print( *pd );
03279       res = true;
03280       delete pd;
03281     }
03282   }
03283   return res;
03284 #endif
03285 }
03286 
03290 void Plot2d_ViewFrame::printPlot( QPainter* p, const QRect& rect,
03291                                   const QwtPlotPrintFilter& filter ) const
03292 {
03293   myPlot->print( p, rect, filter );
03294 }
03295 
03299 QString Plot2d_ViewFrame::getVisualParameters()
03300 {
03301 
03302   return getXmlVisualParameters();
03303 
03304   /*
03305   RNV: Old case, now visual parameters stored in the XML format.
03306   //
03307   double xmin, xmax, ymin, ymax, y2min, y2max;
03308   getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
03309   QString retStr;
03310   //Store font in the visual parameters string as:
03311   //  
03312   // ...*FontFamily|FontSize|B|I|U|r:g:b*...
03313   
03314   retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%s|%i|%i|%i|%i|%i:%i:%i",
03315                 myXMode, myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max,
03316                 qPrintable(myLegendFont.family()), myLegendFont.pointSize(),myLegendFont.bold(),
03317                 myLegendFont.italic(), myLegendFont.underline(),myLegendColor.red(),
03318                 myLegendColor.green(), myLegendColor.blue());
03319   
03320  //store all Analytical curves
03321   //store each curve in the following format
03322   // ...*Name|isActive|Expresion|NbInervals|isAutoAssign[|MarkerType|LineType|LineWidth|r:g:b]
03323   // parameters in the [ ] is optional in case if isAutoAssign == true
03324   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
03325   Plot2d_AnalyticalCurve* c = 0;
03326   bool isAuto; 
03327   for( ; it != myAnalyticalCurves.end(); it++) {
03328     c = (*it);
03329     if(!c) continue;
03330     QString curveString("");
03331     isAuto = c->isAutoAssign();
03332     curveString.sprintf("*%s|%i|%s|%i|%i",
03333                      qPrintable(c->getName()),
03334                      c->isActive(),
03335                      qPrintable(c->getExpression()),
03336                      c->getNbIntervals(),
03337                      isAuto);
03338 
03339     retStr+=curveString;
03340     if(!isAuto) {
03341       QString optCurveString("");
03342       optCurveString.sprintf("|%i|%i|%i|%i:%i:%i",
03343                           (int)c->getMarker(),
03344                           (int)c->getLine(),
03345                           c->getLineWidth(),
03346                           c->getColor().red(),
03347                           c->getColor().green(),
03348                           c->getColor().blue());
03349       retStr+=optCurveString;
03350     }
03351   }
03352   retStr += QString( "*%1" ).arg( Qtx::colorToString( backgroundColor() ) );
03353   return retStr; 
03354   */
03355 }
03356 
03360 void Plot2d_ViewFrame::setVisualParameters( const QString& parameters )
03361 {
03362   if(setXmlVisualParameters(parameters))
03363     return;
03364 
03365   double xmin, xmax;
03366   QStringList paramsLst = parameters.split( '*' );
03367   if ( paramsLst.size() >= 9 ) {
03368     double ymin, ymax, y2min, y2max;
03369     myXMode = paramsLst[0].toInt();
03370     myYMode = paramsLst[1].toInt();
03371     mySecondY = (bool)paramsLst[2].toInt();
03372     xmin =  paramsLst[3].toDouble();
03373     xmax =  paramsLst[4].toDouble();
03374     ymin =  paramsLst[5].toDouble();
03375     ymax =  paramsLst[6].toDouble();
03376     y2min = paramsLst[7].toDouble();
03377     y2max = paramsLst[8].toDouble();
03378 
03379     if (mySecondY)
03380       setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
03381     setHorScaleMode( myXMode, /*update=*/false );
03382     setVerScaleMode( myYMode, /*update=*/false );
03383     
03384     if (mySecondY) {
03385       QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
03386       myYDistance2 = yMap2.s2() - yMap2.s1();
03387     }
03388     
03389     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
03390     fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
03391   }
03392 
03393   //Restore legend font
03394   if(paramsLst.size() >= 10) {
03395     QStringList fontList = paramsLst[9].split( '|' );
03396     if(fontList.size() == 6) {
03397       myLegendFont = QFont(fontList[0]);
03398       myLegendFont.setPointSize(fontList[1].toInt());
03399       myLegendFont.setBold(fontList[2].toInt());
03400       myLegendFont.setItalic(fontList[3].toInt());
03401       myLegendFont.setUnderline(fontList[4].toInt());
03402       QStringList colorList = fontList[5].split(":");
03403       setLegendFont( myLegendFont );
03404 
03405       if(colorList.size() == 3) {
03406              myLegendColor = QColor(colorList[0].toInt(),
03407                                               colorList[1].toInt(),
03408                                               colorList[2].toInt());
03409              setLegendFontColor( myLegendColor );
03410       }
03411     }    
03412   }
03413 
03414   //Restore all Analytical curves
03415   int startCurveIndex = 10;
03416   if( paramsLst.size() >= startCurveIndex+1 ) {
03417     for( int i=startCurveIndex; i<paramsLst.size() ; i++ ) {
03418       QStringList curveLst = paramsLst[i].split("|");
03419       if( curveLst.size() == 5 || curveLst.size() == 9 ) {
03420        Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
03421        c->setName(curveLst[0]);
03422        c->setActive(curveLst[1].toInt());
03423        c->setExpression(curveLst[2]);
03424        c->setNbIntervals(curveLst[3].toLong());
03425        c->setAutoAssign(curveLst[4].toInt());
03426        if( !c->isAutoAssign() ) {
03427          c->setMarker((Plot2d::MarkerType)curveLst[5].toInt());
03428          c->setLine((Plot2d::LineType)curveLst[6].toInt());
03429          c->setLineWidth(curveLst[7].toInt());
03430          QStringList colorList = curveLst[8].split(":");
03431          if( colorList.size() == 3 ) {
03432            c->setColor(QColor(colorList[0].toInt(),
03433                             colorList[1].toInt(),
03434                             colorList[2].toInt()));
03435          }
03436        } else {
03437          c->autoFill( myPlot );
03438        }
03439        addAnalyticalCurve(c);
03440        updateAnalyticalCurve(c);
03441       }
03442       else if( curveLst.size() == 1 ) {
03443        // background color can be set here
03444        QColor c;
03445        if ( Qtx::stringToColor( paramsLst[i], c ) )
03446          setBackgroundColor( c );
03447       }
03448     }
03449     myPlot->replot();
03450   }
03451 }
03452 
03456 QString Plot2d_ViewFrame::getXmlVisualParameters() {
03457   QString retStr;
03458   QXmlStreamWriter aWriter(&retStr);
03459   aWriter.setAutoFormatting(true);
03460 
03461   //Ranges
03462   aWriter.writeStartDocument();
03463   aWriter.writeStartElement("ViewState");
03464   aWriter.writeStartElement("Range");
03465   double xmin, xmax, ymin, ymax, y2min, y2max;
03466   getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
03467   aWriter.writeAttribute("Xmin", QString("").sprintf("%.12e",xmin));
03468   aWriter.writeAttribute("Xmax", QString("").sprintf("%.12e",xmax));
03469   aWriter.writeAttribute("Ymin", QString("").sprintf("%.12e",ymin));
03470   aWriter.writeAttribute("Ymax", QString("").sprintf("%.12e",ymax));
03471   aWriter.writeAttribute("Y2min", QString("").sprintf("%.12e",y2min));
03472   aWriter.writeAttribute("Y2max", QString("").sprintf("%.12e",y2max));
03473   aWriter.writeEndElement();
03474 
03475   //Display mode
03476   aWriter.writeStartElement("DisplayMode");
03477   aWriter.writeAttribute("SecondAxis", QString("").sprintf("%d",mySecondY));
03478   aWriter.writeStartElement("ScaleMode");
03479   aWriter.writeAttribute("Xscale", QString("").sprintf("%d",myXMode));
03480   aWriter.writeAttribute("Yscale", QString("").sprintf("%d",myYMode));
03481   aWriter.writeEndElement();
03482   aWriter.writeStartElement("NormalizationMode");
03483   aWriter.writeAttribute("LeftMin", QString("").sprintf("%d",myNormLMin));
03484   aWriter.writeAttribute("LeftMax", QString("").sprintf("%d",myNormLMax));
03485   aWriter.writeAttribute("RightMin", QString("").sprintf("%d",myNormRMin));
03486   aWriter.writeAttribute("RightMax", QString("").sprintf("%d",myNormRMax));
03487   aWriter.writeEndElement();
03488   aWriter.writeEndElement();
03489 
03490   //Legend
03491   aWriter.writeStartElement("Legend");
03492   aWriter.writeAttribute("Visibility", QString("").sprintf("%d", myShowLegend));
03493   aWriter.writeStartElement("LegendFont");
03494   aWriter.writeAttribute("Family", myLegendFont.family());
03495   aWriter.writeAttribute("Size", QString("").sprintf("%d",myLegendFont.pointSize()));
03496   aWriter.writeAttribute("Bold", QString("").sprintf("%d",myLegendFont.bold()));
03497   aWriter.writeAttribute("Italic", QString("").sprintf("%d",myLegendFont.italic()));
03498   aWriter.writeAttribute("Underline", QString("").sprintf("%d",myLegendFont.underline()));
03499   aWriter.writeAttribute("R", QString("").sprintf("%d",myLegendColor.red()));
03500   aWriter.writeAttribute("G", QString("").sprintf("%d",myLegendColor.green()));
03501   aWriter.writeAttribute("B", QString("").sprintf("%d",myLegendColor.blue()));
03502   aWriter.writeEndElement();
03503   aWriter.writeEndElement();
03504 
03505   //AnalyticalCurve
03506   aWriter.writeStartElement("AnalyticalCurves");  
03507   AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
03508   Plot2d_AnalyticalCurve* c = 0;
03509   bool isAuto; 
03510   int id = 1;
03511   for( ; it != myAnalyticalCurves.end(); it++) {
03512     c = (*it);
03513     if(!c) continue;
03514     aWriter.writeStartElement(QString("AnalyticalCurve_%1").arg(id));
03515     isAuto = c->isAutoAssign();
03516     aWriter.writeAttribute("Name",c->getName());
03517     aWriter.writeAttribute("IsActive", QString("").sprintf("%d",      c->isActive()));
03518               aWriter.writeAttribute("Expression", c->getExpression());
03519     aWriter.writeAttribute("NbIntervals", QString("").sprintf("%d",   c->getNbIntervals()));
03520     aWriter.writeAttribute("isAuto", QString("").sprintf("%d",isAuto));
03521     if(!isAuto) {
03522       aWriter.writeAttribute("Marker", QString("").sprintf("%d",(int)c->getMarker()));
03523       aWriter.writeAttribute("Line", QString("").sprintf("%d",(int)c->getLine()));
03524       aWriter.writeAttribute("LineWidth", QString("").sprintf("%d",c->getLineWidth()));
03525       aWriter.writeAttribute("R", QString("").sprintf("%d",c->getColor().red()));
03526       aWriter.writeAttribute("G", QString("").sprintf("%d",c->getColor().green()));
03527       aWriter.writeAttribute("B", QString("").sprintf("%d",c->getColor().blue()));
03528     }
03529     aWriter.writeEndElement();
03530     id++;
03531   }
03532   aWriter.writeEndElement(); //AnalyticalCurve
03533 
03534   //Background
03535   aWriter.writeStartElement(QString("Background").arg(id));
03536   aWriter.writeStartElement(QString("BackgroundColor").arg(id));
03537   aWriter.writeAttribute("R", QString("").sprintf("%d",backgroundColor().red()));
03538   aWriter.writeAttribute("G", QString("").sprintf("%d",backgroundColor().green()));
03539   aWriter.writeAttribute("B", QString("").sprintf("%d",backgroundColor().blue()));
03540   aWriter.writeEndElement();
03541   aWriter.writeEndElement();
03542 
03543 
03544   aWriter.writeEndDocument();
03545   return retStr;
03546 }
03550 bool Plot2d_ViewFrame::setXmlVisualParameters(const QString& parameters) {
03551   QXmlStreamReader aReader(parameters);
03552   double xmin, xmax, ymin, ymax, y2min, y2max;
03553   bool leftMin,leftMax,rightMin,rightMax;
03554   leftMin = leftMax = rightMin = rightMax = false;
03555   while(!aReader.atEnd()) {
03556       aReader.readNext();
03557       if (aReader.isStartElement()) {
03558       QXmlStreamAttributes aAttr = aReader.attributes();
03559         if(aReader.name() == "Range") {
03560           xmin = aAttr.value("Xmin").toString().toDouble();
03561           xmax = aAttr.value("Xmax").toString().toDouble();
03562           ymin = aAttr.value("Ymin").toString().toDouble();
03563           ymax = aAttr.value("Ymax").toString().toDouble();
03564           y2min = aAttr.value("Y2min").toString().toDouble();
03565           y2max = aAttr.value("Y2max").toString().toDouble();
03566         } else if(aReader.name() == "DisplayMode") {
03567           mySecondY = aAttr.value("Y2max").toString().toDouble();
03568         } else if(aReader.name() == "ScaleMode") {
03569            myXMode = aAttr.value("Xscale").toString().toInt();
03570            myYMode = aAttr.value("Yscale").toString().toInt();
03571         } else if(aReader.name() == "NormalizationMode") {
03572             leftMin = (bool)aAttr.value("LeftMin").toString().toInt();
03573             leftMax = (bool)aAttr.value("LeftMax").toString().toInt();
03574             rightMin = (bool)aAttr.value("RightMin").toString().toInt();
03575             rightMax = (bool)aAttr.value("RightMax").toString().toInt();
03576         } else if(aReader.name() == "Legend") {
03577           myShowLegend = (bool)aAttr.value("Visibility").toString().toInt();
03578         } else if (aReader.name() == "LegendFont") {
03579             myLegendFont = QFont(aAttr.value("Family").toString());
03580             myLegendFont.setPointSize(aAttr.value("Size").toString().toInt());
03581             myLegendFont.setBold((bool)aAttr.value("Bold").toString().toInt());
03582             myLegendFont.setItalic((bool)aAttr.value("Italic").toString().toInt());
03583             myLegendFont.setUnderline((bool)aAttr.value("Underline").toString().toInt());
03584              myLegendColor = QColor(aAttr.value("R").toString().toInt(),
03585                                                   aAttr.value("G").toString().toInt(),
03586                                                   aAttr.value("B").toString().toInt());
03587                  setLegendFontColor( myLegendColor );
03588             setLegendFont(myLegendFont);
03589         } else if(aReader.name().toString().indexOf("AnalyticalCurve_") >= 0) {
03590             Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
03591                  c->setName(aAttr.value("Name").toString());
03592                  c->setActive((bool)aAttr.value("IsActive").toString().toInt());
03593                  c->setExpression(aAttr.value("Expression").toString());
03594                  c->setNbIntervals(aAttr.value("NbIntervals").toString().toLong());
03595                  c->setAutoAssign((bool)aAttr.value("isAuto").toString().toInt());
03596                  if( !c->isAutoAssign() ) {
03597                    c->setMarker((Plot2d::MarkerType)aAttr.value("Marker").toString().toInt());
03598                    c->setLine((Plot2d::LineType)aAttr.value("Line").toString().toInt());
03599                    c->setLineWidth(aAttr.value("LineWidth").toString().toInt());               
03600                    c->setColor(QColor(aAttr.value("R").toString().toInt(),
03601                                                 aAttr.value("G").toString().toInt(),
03602                                                 aAttr.value("B").toString().toInt()));
03603             } else {
03604                    c->autoFill( myPlot );
03605                  }
03606                  addAnalyticalCurve(c);
03607                  updateAnalyticalCurve(c);
03608         } else if(aReader.name().toString() == "BackgroundColor") {
03609           setBackgroundColor(QColor(aAttr.value("R").toString().toInt(),
03610                                                    aAttr.value("G").toString().toInt(),
03611                                                    aAttr.value("B").toString().toInt()));
03612         }
03613       }
03614   }
03615 
03616   if(aReader.hasError())
03617     return false;
03618 
03619   if (mySecondY)
03620     setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
03621   setHorScaleMode( myXMode, /*update=*/false );
03622   setVerScaleMode( myYMode, /*update=*/false );    
03623   if (mySecondY) {
03624     QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
03625     myYDistance2 = yMap2.s2() - yMap2.s1();
03626   }    
03627   setNormLMinMode(leftMin);
03628   setNormLMaxMode(leftMax);
03629   setNormRMinMode(rightMin);
03630   setNormRMaxMode(rightMax);
03631 
03632   showLegend( myShowLegend, false );
03633 
03634   fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );  
03635   return true;
03636 }
03637 
03641 void Plot2d_ViewFrame::incrementalPan( const int incrX, const int incrY ) {
03642   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
03643   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
03644   
03645   myPlot->setAxisScale( QwtPlot::yLeft, 
03646                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s1() )-incrY ), 
03647                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() )-incrY ) );
03648   myPlot->setAxisScale( QwtPlot::xBottom, 
03649                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s1() )-incrX ),
03650                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() )-incrX ) ); 
03651   if (mySecondY) {
03652     QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
03653     myPlot->setAxisScale( QwtPlot::yRight,
03654                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s1() )-incrY ), 
03655                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() )-incrY ) );
03656   }
03657   myPlot->replot();
03658 }
03659 
03663 void Plot2d_ViewFrame::incrementalZoom( const int incrX, const int incrY ) {
03664   QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
03665   QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
03666   
03667   myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(), 
03668                         myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() ) + incrY ) );
03669   myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(), 
03670                         myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() ) - incrX ) );
03671   if (mySecondY) {
03672     QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
03673     myPlot->setAxisScale( QwtPlot::yRight, y2Map.s1(),
03674                           myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() ) + incrY ) );
03675   }
03676   myPlot->replot();
03677 }
03678 
03679 /*
03680   Update plot item 
03681 */
03682 void Plot2d_ViewFrame::updatePlotItem(Plot2d_Object* theObject, QwtPlotItem* theItem) {
03683   theObject->updatePlotItem( theItem );
03684   Plot2d_Curve* c = dynamic_cast<Plot2d_Curve*>(theObject);
03685   QwtPlotCurve* cu = dynamic_cast<QwtPlotCurve*>(theItem);
03686   Plot2d_NormalizeAlgorithm* aNormAlgo;
03687   if(c && cu) {
03688     if(c->getYAxis() == QwtPlot::yRight)
03689       aNormAlgo = myRNormAlgo;
03690     else
03691       aNormAlgo = myLNormAlgo;
03692     if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
03693       AlgoPlot2dOutputData aResultData =  aNormAlgo->getOutput();
03694       AlgoPlot2dOutputData::iterator itTmp = aResultData.find(theObject);
03695       double *xNew,*yNew;
03696       int size = itTmp.value().size();
03697       xNew = new double[size];
03698       yNew = new double[size];
03699       int j = 0;
03700       for (; j < size; ++j) {
03701         xNew[j] = itTmp.value().at(j).first;
03702         yNew[j] = itTmp.value().at(j).second;
03703       }
03704       cu->setData(xNew, yNew,j);
03705       delete xNew;
03706       delete yNew;
03707       if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
03708         QString name = c->getName().isEmpty() ? c->getVerTitle() : c->getName();
03709         name = name + QString("(B=%1, K=%2)");
03710         name = name.arg(aNormAlgo->getBkoef(c)).arg(aNormAlgo->getKkoef(c));
03711         cu->setTitle(name);
03712       }
03713     }
03714   }
03715 }
03716 
03720 QwtPlotCanvas* Plot2d_ViewFrame::getPlotCanvas() const
03721 {
03722   return myPlot ? myPlot->canvas() : 0;
03723 }
03724 
03728 Plot2d_Curve* Plot2d_ViewFrame::getClosestCurve( QPoint p, double& distance, int& index ) const
03729 {
03730   CurveDict aCurves = getCurves();
03731   CurveDict::iterator it = aCurves.begin();
03732   QwtPlotCurve* aCurve;
03733   for ( ; it != aCurves.end(); it++ ) {
03734     aCurve = it.key();
03735     if ( !aCurve )
03736       continue;
03737     index = aCurve->closestPoint( p, &distance );
03738     if ( index > -1 )
03739       return it.value();
03740   }
03741   return 0;
03742 }
03743 
03747 void Plot2d_ViewFrame::deselectAnalyticalCurves() {
03748   foreach(Plot2d_AnalyticalCurve* c, myAnalyticalCurves) {
03749    c->setSelected(false);
03750   }
03751 }
03752 
03756 void Plot2d_ViewFrame::deselectObjects() {
03757   ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end();
03758   for ( ; it != aLast; it++ ) {
03759          it.value()->setSelected(false);
03760    }
03761 }
03762 
03763 #define INCREMENT_FOR_OP 10
03764 
03768 void Plot2d_ViewFrame::onPanLeft()
03769 {
03770   this->incrementalPan( -INCREMENT_FOR_OP, 0 );
03771   updateAnalyticalCurves();
03772 }
03773 
03777 void Plot2d_ViewFrame::onPanRight()
03778 {
03779   this->incrementalPan( INCREMENT_FOR_OP, 0 );
03780   updateAnalyticalCurves();
03781 }
03782 
03786 void Plot2d_ViewFrame::onPanUp()
03787 {
03788   this->incrementalPan( 0, -INCREMENT_FOR_OP );
03789   updateAnalyticalCurves();
03790 }
03791 
03795 void Plot2d_ViewFrame::onPanDown()
03796 {
03797   this->incrementalPan( 0, INCREMENT_FOR_OP );
03798   updateAnalyticalCurves();
03799 }
03800 
03804 void Plot2d_ViewFrame::onZoomIn()
03805 {
03806   this->incrementalZoom( INCREMENT_FOR_OP, INCREMENT_FOR_OP );
03807   updateAnalyticalCurves();
03808 }
03809 
03813 void Plot2d_ViewFrame::onZoomOut()
03814 {
03815   this->incrementalZoom( -INCREMENT_FOR_OP, -INCREMENT_FOR_OP );
03816   updateAnalyticalCurves();
03817 }
03818 
03824 void Plot2d_ViewFrame::customEvent( QEvent* ce )
03825 {
03826   if ( ce->type() == FITALL_EVENT )
03827     fitAll();
03828 }
03829 
03830 
03835 Plot2d_Object* Plot2d_ViewFrame::getPlotObject( QwtPlotItem* plotItem ) const {
03836   
03837   ObjectDict::const_iterator it = myObjects.begin();
03838   for( ; it != myObjects.end(); ++it ) {
03839     if ( it.key() == plotItem ) {
03840       return it.value();
03841     }
03842   }
03843   return 0;
03844 }
03845 
03846 Plot2d_ScaleDraw::Plot2d_ScaleDraw( char f, int prec )
03847   : QwtScaleDraw(),
03848     myFormat(f),
03849     myPrecision(prec)
03850 {
03851   invalidateCache();
03852 }
03853 
03854 Plot2d_ScaleDraw::Plot2d_ScaleDraw( const QwtScaleDraw& scaleDraw, char f, int prec )
03855   : QwtScaleDraw(scaleDraw),
03856     myFormat(f),
03857     myPrecision(prec)
03858 {
03859   invalidateCache();
03860 }
03861 
03862 QwtText Plot2d_ScaleDraw::label( double value ) const
03863 {
03864   QwtScaleMap m = map();
03865   QString str1 = QwtScaleDraw::label( m.s1() ).text();
03866   QString str2 = QwtScaleDraw::label( m.s2() ).text();
03867   if ( str1 == str2 ) {
03868     double aDist = fabs(map().s2()-map().s1())/5;
03869     int precision = 0;
03870     while (aDist < 1 ) {
03871       precision++; 
03872       aDist *= 10.; 
03873     }
03874     if ( precision > 0 && value > 0 )
03875       return QLocale::system().toString( value,'f', precision );
03876   }
03877 
03878   return QwtScaleDraw::label( value );
03879 }
03880 
03881 /* Definition of X axis graduations
03882  */
03883 const QString Plot2d_AxisScaleDraw::DEVICE_FONT = QString("Times");
03884 const int     Plot2d_AxisScaleDraw::DEVICE_FONT_SIZE = 12;
03885 const int     Plot2d_AxisScaleDraw::DEVICE_BY = 40;
03886 
03887 Plot2d_AxisScaleDraw::Plot2d_AxisScaleDraw( Plot2d_Plot2d* plot)
03888 : myPlot(plot)
03889 {
03890   myLowerBound = -1;
03891   myUpperBound = -1;
03892   setLabelAlignment(Qt::AlignRight);
03893   setLabelRotation(45.);
03894 
03895   applyTicks();
03896 
03897   myActivTicksDrawing   = true;
03898   myNumTicksDrawingCall = 1;
03899 }
03900 
03901 
03902 Plot2d_AxisScaleDraw::~Plot2d_AxisScaleDraw()
03903 {
03904 }
03905 
03906 
03907 /* Unactivate automatic ticks drawing
03908  */
03909 void Plot2d_AxisScaleDraw::unactivTicksDrawing( int numcall)
03910 {
03911   myActivTicksDrawing   = false;
03912   myNumTicksDrawingCall = numcall;
03913 }
03914 
03915 
03916 /* Draw X ticks and labels.
03917  * Draw systems names under X axis.
03918  * Overload the same name QwtScaleDraw method.
03919  * (PB: who call automaticaly this method)
03920  */
03921 void Plot2d_AxisScaleDraw::draw( QPainter* painter, const QPalette & palette) const
03922 {
03923   //std::cout << "Plot2d_AxisScaleDraw::draw() : activ= " << myActivTicksDrawing
03924   //                           << "  numcall= " << myNumTicksDrawingCall << std::endl;
03925 
03926   if (!myActivTicksDrawing)  return;
03927 
03928   //std::cout << "Plot2d_AxisScaleDraw::draw()" << std::endl;
03929 
03930   QList<double> major_ticks  = scaleDiv().ticks(QwtScaleDiv::MajorTick);
03931   QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
03932   QList<double> minor_ticks  = scaleDiv().ticks(QwtScaleDiv::MinorTick);
03933 
03934   medium_ticks.clear();
03935   minor_ticks.clear();
03936   major_ticks.clear();
03937 
03938   major_ticks.append( myTicks);
03939   myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MajorTick,  major_ticks);
03940   myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
03941   myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MinorTick,  minor_ticks);
03942   QwtScaleDraw *scale = myPlot->axisScaleDraw(QwtPlot::xBottom);
03943   ((Plot2d_AxisScaleDraw*)(scale))->applyTicks();
03944 
03945   QwtScaleDraw::draw( painter, palette);
03946 
03947   for (int i = 0; i < myTicks.size(); i++)
03948   {
03949       drawLabel( painter, myTicks[i]);                 
03950   }      
03951               
03952   //std::cout << "Ok for Plot2d_AxisScaleDraw::draw()" << std::endl;
03953 }
03954 
03955 
03956 QwtText Plot2d_AxisScaleDraw::label( double value) const
03957 {
03958   if (myLabelX.contains(value))
03959           return myLabelX[value];
03960 
03961   return QwtText(QString::number(value, 'f', 1));
03962 }
03963 
03964 
03965 /* Stock position and label of a X tick
03966  */
03967 void Plot2d_AxisScaleDraw::setLabelTick( double value, QString label, bool isDevice)
03968 {
03969   //qDebug()<< "setLabelTick ( " << value << ","<< label <<" )";
03970   if ( isDevice )
03971   {
03972       // For systems names under X axis
03973       myLabelDevice[value] = label;
03974   }
03975   else
03976   {
03977       // For X axis graduations
03978       myLabelX[value] = label;
03979   }
03980 }
03981 
03982 
03983 /* Stock ticks positions of a system, and draw them
03984  */
03985 void Plot2d_AxisScaleDraw::setTicks(const QList<double> aTicks)
03986 {
03987   //std::cout << "  Plot2d_AxisScaleDraw::setTicks()" << std::endl;
03988   myTicks = aTicks;
03989 
03990   applyTicks();
03991 }
03992 
03993 
03994 void Plot2d_AxisScaleDraw::setInterval(double lowerBound, double upperBound)
03995 {
03996   myLowerBound = lowerBound;
03997   myUpperBound = upperBound;
03998   myPlot->setAxisScale( QwtPlot::xBottom, myLowerBound, myUpperBound );
03999 }
04000 
04001 
04002 /* Stock X ticks in drawing zone
04003  */
04004 void Plot2d_AxisScaleDraw::applyTicks()
04005 {
04006   //std::cout << "  Plot2d_AxisScaleDraw::applyTicks()" << std::endl;
04007 
04008   QList<double> major_ticks = scaleDiv().ticks(QwtScaleDiv::MajorTick);
04009   QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
04010   QList<double> minor_ticks = scaleDiv().ticks(QwtScaleDiv::MinorTick);
04011 
04012   medium_ticks.clear();
04013   minor_ticks.clear();
04014 
04015   myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MajorTick, myTicks);
04016   myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
04017   myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MinorTick, minor_ticks);
04018 
04019   QwtScaleDiv* aScaleDiv = (QwtScaleDiv*) &scaleDiv();
04020 
04021   aScaleDiv->setTicks(QwtScaleDiv::MajorTick, myTicks);
04022   aScaleDiv->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
04023   aScaleDiv->setTicks(QwtScaleDiv::MinorTick, minor_ticks);
04024 
04025   if (myLowerBound != -1 && myUpperBound != -1)
04026               aScaleDiv->setInterval(myLowerBound, myUpperBound);
04027               
04028   //for (int i = 0; i < myTicks.size(); i++){
04029   //  QPoint p = labelPosition( i );
04030   //  qDebug() << i<< ") applyTicks -> LABEL" <<p;
04031   //}
04032 }
04033 
04034 
04035 void Plot2d_AxisScaleDraw::drawLabel( QPainter* painter, double value) const
04036 {
04037   //std::cout << "  Plot2d_AxisScaleDraw::drawLabel( " << value << " ) : "; //<< std::endl;
04038 
04039   //qDebug() << "drawLabel  ( " <<value<<" )";
04040   if ( myLabelDevice.contains(value) )
04041   {
04042       QString deviceLabel = myLabelDevice[value];
04043       //
04044       std::string std_label = deviceLabel.toStdString();
04045       //const char *c_label = std_label.c_str();
04046       //std::cout << "    deviceLabel= |" << c_label << "|" << std::endl;
04047 
04048       QPoint p = labelPosition( value );
04049       p += QPoint(0, DEVICE_BY);
04050       QFont  prevf = painter->font();
04051       //QColor prevc = (painter->pen()).color();
04052                 
04053       QFont devicef( DEVICE_FONT, DEVICE_FONT_SIZE, QFont::Bold);
04054       //
04055       //painter->setPen( QColor("blue") );
04056       painter->setFont( devicef );
04057       painter->drawText( p, myLabelDevice[value] );
04058       //painter->setPen( prevc );
04059       painter->setFont( prevf );
04060   }
04061   if ( myLabelX.contains(value) )
04062   {
04063       QString xLabel = myLabelX[value];
04064       //
04065       std::string std_label = xLabel.toStdString();
04066       //const char *c_label = std_label.c_str();
04067       //std::cout << "    xLabel= |" << c_label << "|" << std::endl;
04068 
04069       QwtScaleDraw::drawLabel( painter, value );
04070   }
04071 }
04072     
04073 
04074 void Plot2d_AxisScaleDraw::drawTick( QPainter* painter, double value, int len) const
04075 {
04076   //qDebug() << "drawTick  ( " <<value<<" , "<<len<<" )  " ;
04077   //qDebug() << "myLabelX" << myLabelX;
04078   //
04079   if ( myLabelX.contains(value) )
04080   {
04081       QwtScaleDraw::drawTick( painter, value, len);
04082   } 
04083 }
04084 
04085 
04086 /* Management of tooltips associated with markers for curves points or others points
04087  */
04088 const double Plot2d_QwtPlotPicker::BOUND_HV_SIZE = 0.2;
04089  
04090 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int            xAxis,
04091                                             int            yAxis,
04092                                             int            selectionFlags,
04093                                             RubberBand     rubberBand,
04094                                             DisplayMode    trackerMode,
04095                                             QwtPlotCanvas *canvas)
04096 : QwtPlotPicker( xAxis,
04097                  yAxis,
04098                  selectionFlags,
04099                  rubberBand,
04100                  trackerMode,
04101                  canvas)    // of drawing zone QwtPlot
04102 {
04103 }
04104   
04105 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int            xAxis,
04106                                             int            yAxis,
04107                                             QwtPlotCanvas *canvas)
04108 : QwtPlotPicker( xAxis,
04109                  yAxis,
04110                  canvas)
04111 {
04112 }
04113 
04114 Plot2d_QwtPlotPicker::~Plot2d_QwtPlotPicker()
04115 {
04116 }
04117 // http://www.qtcentre.org/threads/22751-How-do-i-select-a-QwtPlotMarker-using-a-QPlotPicker
04118 
04119 /* Return the tooltip associated with a point when the mouse cursor pass near
04120  */
04121 QwtText Plot2d_QwtPlotPicker::trackerText( const QwtDoublePoint & pos ) const
04122 {
04123   for (QList<QwtPlotMarker* >::const_iterator pMarkerIt = pMarkers.begin();
04124                                               pMarkerIt != pMarkers.end();
04125                                               ++pMarkerIt )
04126   {
04127       QwtPlotMarker* pMarker = *pMarkerIt;
04128       if ( pMarker != NULL )
04129       {
04130           QwtDoubleRect  bound0        = pMarker->boundingRect();
04131           QwtDoublePoint center_bound0 = bound0.center();
04132           double left = center_bound0.x()-(BOUND_HV_SIZE/2.);
04133           double top  = center_bound0.y()-(BOUND_HV_SIZE/2.);
04134          
04135           QwtDoubleRect  bound( left, top , BOUND_HV_SIZE, BOUND_HV_SIZE);
04136          
04137           if( bound.contains(pos) )
04138           {
04139             //QString toolTip =  "X="  + QString::number( pMarker->xValue() )
04140             //                 + " Y=" + QString::number( pMarker->yValue() );
04141             return pMarkersToolTip[pMarker];
04142           }
04143       }       
04144   }
04145       
04146   return QwtText();      
04147 }