Salome HOME
Porting to Mandrake 10.1 and new products:
[modules/kernel.git] / src / Plot2d / Plot2d_ViewFrame.cxx
1 //  Copyright (C) 2003  CEA/DEN, EDF R&D
2 //
3 //
4 //
5 //  File   : Plot2d_ViewFrame.cxx
6 //  Author : Vadim SANDLER
7 //  Module : SALOME
8 //  $Header$
9
10 #include "Plot2d_ViewFrame.h"
11 #include "Plot2d_SetupViewDlg.h"
12 #include "Plot2d_Prs.h"
13
14 #include "QAD_Desktop.h"
15 #include "QAD_ResourceMgr.h"
16 #include "QAD_FileDlg.h"
17 #include "QAD_Tools.h"
18 #include "QAD_MessageBox.h"
19 #include "QAD_Config.h"
20 #include "SALOME_Selection.h"
21 #include "Plot2d_CurveContainer.h"
22 #include "Plot2d_Curve.h"
23 #include "Plot2d_FitDataDlg.h"
24 #include "utilities.h"
25 #include "qapplication.h"
26 #include <qtoolbar.h>
27 #include <qtoolbutton.h>
28 #include <qcursor.h>
29 #include <qcolordialog.h>
30 #include <qwt_math.h>
31 #include <qwt_plot_canvas.h>
32 #include <stdlib.h>
33 #include "utilities.h"
34
35 // IDL headers
36 #include <SALOMEconfig.h>
37 #include CORBA_SERVER_HEADER(SALOMEDS)
38 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
39 using namespace std;
40
41 #define DEFAULT_LINE_WIDTH     0     // (default) line width
42 #define DEFAULT_MARKER_SIZE    9     // default marker size
43 #define MIN_RECT_SIZE          11    // min sensibility area size
44
45 /* XPM */
46 const char* imageZoomCursor[] = { 
47 "32 32 3 1",
48 ". c None",
49 "a c #000000",
50 "# c #ffffff",
51 "................................",
52 "................................",
53 ".#######........................",
54 "..aaaaaaa.......................",
55 "................................",
56 ".............#####..............",
57 "...........##.aaaa##............",
58 "..........#.aa.....a#...........",
59 ".........#.a.........#..........",
60 ".........#a..........#a.........",
61 "........#.a...........#.........",
62 "........#a............#a........",
63 "........#a............#a........",
64 "........#a............#a........",
65 "........#a............#a........",
66 ".........#...........#.a........",
67 ".........#a..........#a.........",
68 ".........##.........#.a.........",
69 "........#####.....##.a..........",
70 ".......###aaa#####.aa...........",
71 "......###aa...aaaaa.......#.....",
72 ".....###aa................#a....",
73 "....###aa.................#a....",
74 "...###aa...............#######..",
75 "....#aa.................aa#aaaa.",
76 ".....a....................#a....",
77 "..........................#a....",
78 "...........................a....",
79 "................................",
80 "................................",
81 "................................",
82 "................................"};
83
84
85 //=================================================================================
86 // Plot2d_ViewFrame implementation
87 //=================================================================================
88
89 /*!
90   Constructor
91 */
92 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
93      : QAD_ViewFrame( parent, title ),
94        myOperation( NoOpId ), 
95        myCurveType( 1 ), 
96        myShowLegend( true ), myLegendPos( 1 ),
97        myMarkerSize( DEFAULT_MARKER_SIZE ),
98        myTitle( "" ), myXTitle( "" ), myYTitle( "" ),
99        myBackground( white ),
100        myTitleEnabled( true ), myXTitleEnabled( true ), myYTitleEnabled( true ),
101        myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), 
102        myXGridMinorEnabled( false ), myYGridMinorEnabled( false ),
103        myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ),
104        myXMode( 0 ), myYMode( 0 )
105        
106 {
107   myCurves.setAutoDelete( true );
108   /* Plot 2d View */
109   myPlot = new Plot2d_Plot2d( this );
110   setCentralWidget( myPlot );
111
112   createActions();
113
114   connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
115            this,   SLOT( plotMouseMoved( const QMouseEvent& ) ) );
116   connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
117            this,   SLOT( plotMousePressed( const QMouseEvent& ) ) );
118   connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
119            this,   SLOT( plotMouseReleased( const QMouseEvent& ) ) );
120   connect( myPlot, SIGNAL( legendClicked( long ) ),
121            this,   SLOT( onLegendClicked( long ) ) );
122
123   /* Initial Setup - get from the preferences */
124   readPreferences();
125
126   myPlot->setMargin( 5 );
127   setCurveType( myCurveType, false );
128   setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
129   setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor, false );
130   setMainTitle( myTitleEnabled, myTitle, false );
131   setXTitle( myXTitleEnabled, myXTitle, false );
132   setYTitle( myYTitleEnabled, myYTitle, false );
133   setHorScaleMode( myXMode, false );
134   setVerScaleMode( myYMode, false );
135   setBackgroundColor( myBackground );
136   setLegendPos( myLegendPos );
137   showLegend( myShowLegend, false );
138   myPlot->replot();
139
140   if ( parent ) {
141     resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
142   }
143 }
144 /*!
145   Destructor
146 */
147 Plot2d_ViewFrame::~Plot2d_ViewFrame()
148 {
149   myActions.clear();
150   qApp->removeEventFilter( this );
151 }
152 /*!
153   Creates popup menu actions
154 */
155 void Plot2d_ViewFrame::createActions()
156 {
157   QAD_ResourceMgr* rmgr = QAD_Desktop::getResourceManager();
158   /* Linear/logarithmic mode */
159   // Horizontal axis
160   QActionPGroup* modeHorGrp = new QActionPGroup( this );
161   modeHorGrp->setExclusive( TRUE );
162   QActionP* linearXAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LINEAR_HOR"),
163                                          rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LINEAR_HOR") ) ,
164                                          tr( "MEN_PLOT2D_MODE_LINEAR_HOR" ), 0, modeHorGrp );
165   linearXAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LINEAR_HOR" ) );
166   linearXAction->setToggleAction( true );
167   myActions.insert( ModeXLinearId, linearXAction );
168   QActionP* logXAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LOGARITHMIC_HOR"),
169                                       rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LOGARITHMIC_HOR") ) ,
170                                       tr( "MEN_PLOT2D_MODE_LOGARITHMIC_HOR" ), 0, modeHorGrp );
171   logXAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LOGARITHMIC_HOR" ) );
172   logXAction->setToggleAction( true );
173   myActions.insert( ModeXLogarithmicId, logXAction );
174   connect( modeHorGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onHorMode() ) );
175
176   // Vertical axis
177   QActionPGroup* modeVerGrp = new QActionPGroup( this );
178   modeVerGrp->setExclusive( TRUE );
179   QActionP* linearYAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LINEAR_VER"),
180                                          rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LINEAR_VER") ) ,
181                                          tr( "MEN_PLOT2D_MODE_LINEAR_VER" ), 0, modeVerGrp );
182   linearYAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LINEAR_VER" ) );
183   linearYAction->setToggleAction( true );
184   myActions.insert( ModeYLinearId, linearYAction );
185   QActionP* logYAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LOGARITHMIC_VER"),
186                                       rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LOGARITHMIC_VER") ) ,
187                                       tr( "MEN_PLOT2D_MODE_LOGARITHMIC_VER" ), 0, modeVerGrp );
188   logYAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LOGARITHMIC_VER" ) );
189   logYAction->setToggleAction( true );
190   myActions.insert( ModeYLogarithmicId, logYAction );
191   connect( modeVerGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onVerMode() ) );
192
193   /* Legend */
194   QActionP* legendAction = new QActionP ( tr( "TOT_PLOT2D_SHOW_LEGEND"),
195                                         rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_SHOW_LEGEND") ) ,
196                                         tr( "MEN_PLOT2D_SHOW_LEGEND" ), 0, this );
197   legendAction->setStatusTip ( tr( "PRP_PLOT2D_SHOW_LEGEND" ) );
198   legendAction->setToggleAction( true );
199   myActions.insert( LegendId, legendAction );
200   connect( legendAction, SIGNAL( activated() ), this, SLOT( onLegend() ) );
201
202   /* Curve type */
203   QActionPGroup* curveGrp = new QActionPGroup( this );
204   curveGrp->setExclusive( TRUE );
205   QActionP* pointsAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_POINTS"),
206                                         rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_POINTS") ) ,
207                                         tr( "MEN_PLOT2D_CURVES_POINTS" ), 0, curveGrp );
208   pointsAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_POINTS" ) );
209   pointsAction->setToggleAction( true );
210   myActions.insert( CurvePointsId, pointsAction );
211   QActionP* linesAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_LINES"),
212                                        rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_LINES") ) ,
213                                        tr( "MEN_PLOT2D_CURVES_LINES" ), 0, curveGrp );
214   linesAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_LINES" ) );
215   linesAction->setToggleAction( true );
216   myActions.insert( CurveLinesId, linesAction );
217   QActionP* splinesAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_SPLINES"),
218                                          rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_SPLINES") ) ,
219                                          tr( "MEN_PLOT2D_CURVES_SPLINES" ), 0, curveGrp );
220   splinesAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_SPLINES" ) );
221   splinesAction->setToggleAction( true );
222   myActions.insert( CurveSplinesId, splinesAction );
223   connect( curveGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onCurves() ) );
224
225   // Settings
226   QActionP* settingsAction = new QActionP ( tr( "TOT_PLOT2D_SETTINGS"),
227                                           rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_SETTINGS") ) ,
228                                           tr( "MEN_PLOT2D_SETTINGS" ), 0, this );
229   settingsAction->setStatusTip ( tr( "PRP_PLOT2D_SETTINGS" ) );
230   myActions.insert( SettingsId, settingsAction );
231   connect( settingsAction, SIGNAL( activated() ), this, SLOT( onSettings() ) );
232
233   // Fit Data
234   QActionP* fitDataAction = new QActionP ( tr( "TOT_PLOT2D_FITDATA"),
235                                          rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_FITDATA") ) ,
236                                          tr( "MEN_PLOT2D_FITDATA" ), 0, this );
237   fitDataAction->setStatusTip ( tr( "PRP_PLOT2D_FITDATA" ) );
238   myActions.insert( FitDataId, fitDataAction );
239   connect( fitDataAction, SIGNAL( activated() ), this, SLOT( onFitData() ) );
240
241   // Change background
242   QActionP* changeBGAction = new QActionP ( tr( "TOT_PLOT2D_CHANGE_BACKGROUND"),
243                                             tr( "MEN_PLOT2D_CHANGE_BACKGROUND" ), 0, this );
244   fitDataAction->setStatusTip ( tr( "PRP_PLOT2D_CHANGE_BACKGROUND" ) );
245   myActions.insert( ChangeBackgroundId, changeBGAction );
246   connect( changeBGAction, SIGNAL( activated() ), this, SLOT( onChangeBackground() ) );
247
248   // Dump View
249   QActionP* dumpViewAction = new QActionP ( tr( "MEN_VP3D_DUMPVIEW"),
250                                             tr( "MEN_VP3D_DUMPVIEW" ), 0, this );
251   dumpViewAction->setStatusTip ( tr( "MEN_VP3D_DUMPVIEW" ) );
252   myActions.insert( DumpViewId, dumpViewAction );
253   connect( dumpViewAction, SIGNAL( activated() ), this, SLOT( onProcessViewDump() ) );
254 }
255 /*!
256   Gets window's central widget
257 */
258 QWidget* Plot2d_ViewFrame::getViewWidget()
259 {
260   return (QWidget*)myPlot;
261 }
262 /* Popup management : sets Popup server */
263 void Plot2d_ViewFrame::setPopupServer( QAD_Application* App )
264 {
265 //  QAD_PopupClientServer::setPopupServer( (QAD_PopupServer*)App );
266 }
267 /*!
268   Popup menu creation
269 */
270 void Plot2d_ViewFrame::onCreatePopup()
271 {
272   if ( myPopup ) {
273     myPopup->clear();
274     // scaling
275     QPopupMenu* scalingPopup = new QPopupMenu( myPopup );
276     myActions[ ModeXLinearId ]->addTo( scalingPopup );
277     myActions[ ModeXLogarithmicId ]->addTo( scalingPopup );
278     scalingPopup->insertSeparator();
279     myActions[ ModeYLinearId ]->addTo( scalingPopup );
280     myActions[ ModeYLogarithmicId ]->addTo( scalingPopup );
281     myActions[ FitDataId ]->addTo( myPopup );
282     myPopup->insertItem( tr( "SCALING_POPUP" ), scalingPopup );
283     // curve type
284     QPopupMenu* curTypePopup = new QPopupMenu( myPopup );
285     myActions[ CurvePointsId ]->addTo( curTypePopup );
286     myActions[ CurveLinesId ]->addTo( curTypePopup );
287     myActions[ CurveSplinesId ]->addTo( curTypePopup );
288     myPopup->insertItem( tr( "CURVE_TYPE_POPUP" ), curTypePopup );
289     // legend
290     myPopup->insertSeparator();
291     myActions[ LegendId ]->addTo( myPopup );
292     // settings
293     myPopup->insertSeparator();
294     myActions[ SettingsId ]->addTo( myPopup );
295     // Change background
296     myPopup->insertSeparator();
297     myActions[ ChangeBackgroundId ]->addTo( myPopup );
298     myActions[ DumpViewId ]->addTo( myPopup );
299   }
300 }
301 /*!
302   Renames curve if it is found
303 */
304 void Plot2d_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName ) 
305 {
306   Plot2d_Curve* curve = getCurveByIO( IObject );
307   if ( curve ) {
308     curve->setVerTitle( newName );
309     int key = hasCurve( curve );
310     if ( key ) {
311       myPlot->setCurveTitle( key, newName );
312 //      int legendIndex = myPlot->getLegend()->findFirstKey( key );
313 //      if ( legendIndex != myPlot->getLegend()->itemCnt() )
314 //      myPlot->getLegend()->setText( legendIndex, aSymbol );
315     }
316   }
317   updateTitles();
318 }
319 /*!
320   Returns true if interactive object is presented in the viewer
321 */
322 bool Plot2d_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) 
323 {
324   if( getCurveByIO( IObject ) != NULL )
325     return 1;
326   else{
327     if(!IObject.IsNull()){
328       QIntDictIterator<Plot2d_Curve> it(myCurves);
329       for(; it.current();++it){
330         if(it.current()->hasIO() && it.current()->getTableIO()->isSame(IObject))
331           return 1;
332       }}
333   }
334   return 0;
335 }
336 /*!
337   Returns true if interactive object is presented in the viewer and displayed
338 */
339 bool Plot2d_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) 
340 {
341   Plot2d_Curve* curve = getCurveByIO( IObject );
342   if ( curve ) {
343     int key = hasCurve( curve );
344     if ( key )
345       return myPlot->curve( key )->enabled();
346   }
347   return false;
348 }
349 /*!
350   Return interactive obeject if is presented in the viewer
351 */
352 Handle(SALOME_InteractiveObject) Plot2d_ViewFrame::FindIObject( const char* Entry )
353 {
354   Handle(SALOME_InteractiveObject) o;
355   QIntDictIterator<Plot2d_Curve> it( myCurves );
356   for ( ; it.current(); ++it ) {
357     if ( it.current()->hasIO() && !strcmp( it.current()->getIO()->getEntry(), Entry ) ) {
358       o = it.current()->getIO();
359       break;
360     }
361   }
362   return o;
363 }
364 /*!
365   Actually this method just re-displays curves which refers to the <IObject>
366 */
367 void Plot2d_ViewFrame::Display( const Handle(SALOME_InteractiveObject)& IObject, bool update )
368 {
369   Plot2d_Curve* curve = getCurveByIO( IObject );
370   if ( curve )
371     updateCurve( curve, update );
372 }
373 /*!
374   Actually this method just erases all curves which don't refer to <IOBject> 
375   and re-displays curve which is of <IObject>
376 */
377 void Plot2d_ViewFrame::DisplayOnly( const Handle(SALOME_InteractiveObject)& IObject )
378 {
379   Plot2d_Curve* curve = getCurveByIO( IObject );
380   QList<Plot2d_Curve> clist;
381   getCurves( clist );
382   for ( int i = 0; i < clist.count(); i++ ) {
383     if ( clist.at( i ) != curve )
384       eraseCurve( curve );
385     else
386       updateCurve( curve, false );
387   }
388   myPlot->replot();
389 }
390 /*!
391   Removes from the viewer the curves which refer to <IObject>
392 */
393 void Plot2d_ViewFrame::Erase( const Handle(SALOME_InteractiveObject)& IObject, bool update )
394 {
395   Plot2d_Curve* curve = getCurveByIO( IObject );
396   if ( curve )
397     eraseCurve( curve, update );
398   // it can be table or container object selected
399   QAD_Study* activeStudy = QAD_Application::getDesktop()->getActiveStudy();
400   SALOMEDS::SObject_var aSO = activeStudy->getStudyDocument()->FindObjectID(IObject->getEntry());
401   if ( !aSO->_is_nil() ) {
402     SALOMEDS::ChildIterator_var aIter = activeStudy->getStudyDocument()->NewChildIterator( aSO );
403     for ( ; aIter->More(); aIter->Next() ) {
404       SALOMEDS::SObject_var aChildSO = aIter->Value();
405       SALOMEDS::SObject_var refSO;
406       if ( aChildSO->ReferencedObject( refSO ) && !refSO->_is_nil() )
407         aChildSO = refSO;
408       curve = getCurveByIO( new SALOME_InteractiveObject( aChildSO->GetID(), "", "" ) );
409       if ( curve )
410         eraseCurve( curve, update );
411     }
412   }
413 }
414 /*!
415   Actually this method just re-displays all curves which are presented in the viewer
416 */
417 void Plot2d_ViewFrame::DisplayAll()
418 {
419   QList<Plot2d_Curve> clist;
420   getCurves( clist );
421   for ( int i = 0; i < clist.count(); i++ ) {
422     updateCurve( clist.at( i ), false );
423    }
424   myPlot->replot();
425 }
426 /*!
427    Removes all curves from the view
428 */
429 void Plot2d_ViewFrame::EraseAll() 
430 {
431   myPlot->clear();
432   myCurves.clear();
433   myPlot->replot();
434 }
435 /*!
436   Redraws viewframe contents
437 */
438 void Plot2d_ViewFrame::Repaint()
439 {
440   myPlot->replot();
441 }
442 /*!
443   Event filter
444 */
445 bool Plot2d_ViewFrame::eventFilter( QObject* o, QEvent* e )
446 {
447   if ( ( e->type() == QEvent::MouseButtonPress || e->type() == QEvent::KeyPress ) && o != myPlot->canvas() ) {
448     myOperation = NoOpId;
449     qApp->removeEventFilter( this );
450   }
451   return QMainWindow::eventFilter( o, e );
452 }
453 /*!
454   Sets title
455 */
456 void Plot2d_ViewFrame::setTitle( const QString& title )
457 {
458   setMainTitle( myTitleEnabled, title, true );
459 }
460 /*!
461   Reads Plot2d view settings from the preferences
462 */
463 void Plot2d_ViewFrame::readPreferences()
464 {
465   if ( QAD_CONFIG->hasSetting( "Plot2d:CurveType" ) ) {                                          // curve type
466     myCurveType = QAD_CONFIG->getSetting( "Plot2d:CurveType" ).toInt();                             
467     if ( myCurveType < 0 || myCurveType > 2 ) myCurveType = 1;
468   }
469   if ( QAD_CONFIG->hasSetting( "Plot2d:ShowLegend" ) ) {                                          
470     myShowLegend = QAD_CONFIG->getSetting( "Plot2d:ShowLegend" ) == QString( "true" );           // show legend
471   }
472   if ( QAD_CONFIG->hasSetting( "Plot2d:LegendPos" ) ) {                                          // legend position
473     myLegendPos  = QAD_CONFIG->getSetting( "Plot2d:LegendPos" ).toInt();                            
474     if ( myLegendPos < 0 || myLegendPos > 3 ) myLegendPos = 1;
475   }
476   if ( QAD_CONFIG->hasSetting( "Plot2d:MarkerSize" ) ) {                                         // marker size
477     myMarkerSize = QAD_CONFIG->getSetting( "Plot2d:MarkerSize" ).toInt();                           
478   }
479   if ( QAD_CONFIG->hasSetting( "Plot2d:Background" ) ) {                                         // background color
480     QString bgString = QAD_CONFIG->getSetting( "Plot2d:Background" );                               
481     QStringList bgData = QStringList::split( ":", bgString, true );
482     int bgRed = 0, bgGreen = 0, bgBlue = 0;
483     if ( bgData.count() > 0 ) bgRed   = bgData[ 0 ].toInt();
484     if ( bgData.count() > 1 ) bgGreen = bgData[ 1 ].toInt();
485     if ( bgData.count() > 2 ) bgBlue  = bgData[ 2 ].toInt();
486     myBackground = QColor( bgRed, bgGreen, bgBlue );
487   }
488   if ( QAD_CONFIG->hasSetting( "Plot2d:ShowTitle" ) ) {                                          // main title
489     myTitleEnabled  = QAD_CONFIG->getSetting( "Plot2d:ShowTitle" ) == QString( "true" );               
490   }
491   if ( QAD_CONFIG->hasSetting( "Plot2d:ShowHorTitle" ) ) {                                       // hor.axis title
492     myXTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowHorTitle" ) == QString( "true" );
493   }
494   if ( QAD_CONFIG->hasSetting( "Plot2d:ShowVerTitle" ) ) {                                       // ver.axisn title
495     myYTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowVerTitle" ) == QString( "true" );
496   }
497   if ( QAD_CONFIG->hasSetting( "Plot2d:EnableHorMajorGrid" ) ) {                                 // grid
498     myXGridMajorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableHorMajorGrid" ) == QString( "true" ); 
499   }
500   if ( QAD_CONFIG->hasSetting( "Plot2d:EnableVerMajorGrid" ) ) {      
501     myYGridMajorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableVerMajorGrid" ) == QString( "true" );
502   }
503   if ( QAD_CONFIG->hasSetting( "Plot2d:EnableHorMinorGrid" ) ) {
504     myXGridMinorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableHorMinorGrid" ) == QString( "true" );
505   }
506   if ( QAD_CONFIG->hasSetting( "Plot2d:EnableVerMinorGrid" ) ) {
507     myYGridMinorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableVerMinorGrid" ) == QString( "true" );
508   }
509   if ( QAD_CONFIG->hasSetting( "Plot2d:HorMajorGridMax" ) ) {
510     myXGridMaxMajor = QAD_CONFIG->getSetting( "Plot2d:HorMajorGridMax" ).toInt();
511   }
512   if ( QAD_CONFIG->hasSetting( "Plot2d:VerMajorGridMax" ) ) {
513     myYGridMaxMajor = QAD_CONFIG->getSetting( "Plot2d:VerMajorGridMax" ).toInt();
514   }
515   if ( QAD_CONFIG->hasSetting( "Plot2d:HorMinorGridMax" ) ) {
516     myXGridMaxMinor = QAD_CONFIG->getSetting( "Plot2d:HorMinorGridMax" ).toInt();
517   }
518   if ( QAD_CONFIG->hasSetting( "Plot2d:VerMinorGridMax" ) ) {
519     myYGridMaxMinor = QAD_CONFIG->getSetting( "Plot2d:VerMinorGridMax" ).toInt();
520   }
521   if ( QAD_CONFIG->hasSetting( "Plot2d:HorScaleMode" ) ) {                                       // scale mode
522     myXMode = QAD_CONFIG->getSetting( "Plot2d:HorScaleMode" ).toInt();                             
523     if ( myXMode < 0 || myXMode > 1 ) myXMode = 0;
524   }
525   if ( QAD_CONFIG->hasSetting( "Plot2d:VerScaleMode" ) ) {                                       
526     myYMode = QAD_CONFIG->getSetting( "Plot2d:VerScaleMode" ).toInt();
527     if ( myYMode < 0 || myYMode > 1 ) myYMode = 0;
528   }
529 }
530 /*!
531   Writes Plot2d view settings to the preferences
532 */
533 void Plot2d_ViewFrame::writePreferences()
534 {
535   QAD_CONFIG->addSetting( "Plot2d:CurveType",  myCurveType );                                     // curve type
536   QAD_CONFIG->addSetting( "Plot2d:ShowLegend", myShowLegend ? "true" : "false" );                 // show legend
537   QAD_CONFIG->addSetting( "Plot2d:LegendPos",  myLegendPos );                                     // legend position
538   QAD_CONFIG->addSetting( "Plot2d:MarkerSize", myMarkerSize );                                    // marker size
539   QStringList bgData; 
540   bgData.append( QString::number( myBackground.red() ) );
541   bgData.append( QString::number( myBackground.green() ) );
542   bgData.append( QString::number( myBackground.blue() ) );
543   QAD_CONFIG->addSetting( "Plot2d:Background",   bgData.join( ":" ) );                            // background color
544   QAD_CONFIG->addSetting( "Plot2d:ShowTitle",    myTitleEnabled ?  "true" : "false" );            // titles
545   QAD_CONFIG->addSetting( "Plot2d:ShowHorTitle", myXTitleEnabled ? "true" : "false" ); 
546   QAD_CONFIG->addSetting( "Plot2d:ShowVerTitle", myYTitleEnabled ? "true" : "false" ); 
547   QAD_CONFIG->addSetting( "Plot2d:EnableHorMajorGrid", myXGridMajorEnabled ? "true" : "false" );  // grid
548   QAD_CONFIG->addSetting( "Plot2d:EnableVerMajorGrid", myYGridMajorEnabled ? "true" : "false" );  
549   QAD_CONFIG->addSetting( "Plot2d:EnableHorMinorGrid", myXGridMinorEnabled ? "true" : "false" );  
550   QAD_CONFIG->addSetting( "Plot2d:EnableVerMinorGrid", myYGridMinorEnabled ? "true" : "false" );  
551   QAD_CONFIG->addSetting( "Plot2d:HorMajorGridMax", myXGridMaxMajor );
552   QAD_CONFIG->addSetting( "Plot2d:VerMajorGridMax", myYGridMaxMajor );
553   QAD_CONFIG->addSetting( "Plot2d:HorMinorGridMax", myXGridMaxMinor );
554   QAD_CONFIG->addSetting( "Plot2d:VerMinorGridMax", myYGridMaxMinor );
555   QAD_CONFIG->addSetting( "Plot2d:HorScaleMode", myXMode );                                       // scale mode
556   QAD_CONFIG->addSetting( "Plot2d:VerScaleMode", myYMode );
557 }
558 /*!
559   Prints mouse cursor coordinates into string
560 */
561 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt ) 
562 {
563   bool xFound = false, yFound = false;
564   double xCoord, yCoord;
565   const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
566   for ( int i = 0; i < aXscale->majCnt(); i++ ) {
567     double majXmark = aXscale->majMark( i );
568     int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
569     if ( xmark-2 == pnt.x() ) {
570       xCoord = majXmark; 
571       xFound = true;
572       MESSAGE("Plot2d_ViewFrame::getInfo : close maj X mark("<<i<<") = "<<majXmark<<" "<<xmark<<" "<<pnt.x());
573       break;
574     }
575   }
576   if ( !xFound ) {
577     for ( int i = 0; i < aXscale->minCnt(); i++ ) {
578       double minXmark = aXscale->minMark( i );
579       int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
580       if ( xmark-2 == pnt.x() ) {
581         xCoord = minXmark; 
582         xFound = true;
583         MESSAGE("Plot2d_ViewFrame::getInfo : close min X mark("<<i<<") = "<<minXmark<<" "<<xmark<<" "<<pnt.x());
584         break;
585       }
586     }
587   }  
588   const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
589   for ( int i = 0; i < aYscale->majCnt(); i++ ) {
590     double majYmark = aYscale->majMark( i );
591     int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
592     if ( ymark-2 == pnt.y() ) {
593       yCoord = majYmark; 
594       yFound = true;
595       break;
596     }
597   }
598   if ( !yFound ) {
599     for ( int i = 0; i < aYscale->minCnt(); i++ ) {
600       double minYmark = aYscale->minMark( i );
601       int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
602       if ( ymark-2 == pnt.y() ) {
603         yCoord = minYmark; 
604         yFound = true;
605         break;
606       }
607     }
608   }  
609   QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
610   if ( strX == "-0" )
611     strX = "0";
612   QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
613   if ( strY == "-0" )
614     strY = "0";
615   QString info = tr("INF_COORDINATES").arg( strX ).arg( strY );
616   return info;
617 }
618 /*!
619   Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
620 */
621 static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
622 {
623   QwtSymbol::Style ms = QwtSymbol::None;  
624   switch ( m ) {
625   case Plot2d_Curve::Circle:
626     ms = QwtSymbol::Ellipse;   break;
627   case Plot2d_Curve::Rectangle:
628     ms = QwtSymbol::Rect;      break;
629   case Plot2d_Curve::Diamond:
630     ms = QwtSymbol::Diamond;   break;
631   case Plot2d_Curve::DTriangle:
632     ms = QwtSymbol::DTriangle; break;
633   case Plot2d_Curve::UTriangle:
634     ms = QwtSymbol::UTriangle; break;
635   case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
636     ms = QwtSymbol::RTriangle; break;
637   case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
638     ms = QwtSymbol::LTriangle; break;
639   case Plot2d_Curve::Cross:
640     ms = QwtSymbol::Cross;     break;
641   case Plot2d_Curve::XCross:
642     ms = QwtSymbol::XCross;    break;
643   case Plot2d_Curve::None:
644   default:
645     ms = QwtSymbol::None;      break;
646   }
647   return ms;
648 }
649 /*!
650   Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
651 */
652 static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
653 {
654   Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;  
655   switch ( m ) {
656   case QwtSymbol::Ellipse:
657     ms = Plot2d_Curve::Circle;    break;
658   case QwtSymbol::Rect:
659     ms = Plot2d_Curve::Rectangle; break;
660   case QwtSymbol::Diamond:
661     ms = Plot2d_Curve::Diamond;   break;
662   case QwtSymbol::DTriangle:
663     ms = Plot2d_Curve::DTriangle; break;
664   case QwtSymbol::UTriangle:
665     ms = Plot2d_Curve::UTriangle; break;
666   case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
667     ms = Plot2d_Curve::LTriangle; break;
668   case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
669     ms = Plot2d_Curve::RTriangle; break;
670   case QwtSymbol::Cross:
671     ms = Plot2d_Curve::Cross;     break;
672   case QwtSymbol::XCross:
673     ms = Plot2d_Curve::XCross;    break;
674   case QwtSymbol::None:
675   default:
676     ms = Plot2d_Curve::None;      break;
677   }
678   return ms;
679 }
680 /*!
681   Converts Plot2d_Curve's line style to Qwt line style [ static ]
682 */
683 static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
684 {
685   Qt::PenStyle ps = Qt::NoPen;
686   switch ( p ) {
687   case Plot2d_Curve::Solid:
688     ps = Qt::SolidLine;      break;
689   case Plot2d_Curve::Dash:
690     ps = Qt::DashLine;       break;
691   case Plot2d_Curve::Dot:
692     ps = Qt::DotLine;        break;
693   case Plot2d_Curve::DashDot:
694     ps = Qt::DashDotLine;    break;
695   case Plot2d_Curve::DashDotDot:
696     ps = Qt::DashDotDotLine; break;
697   case Plot2d_Curve::NoPen:
698   default:
699     ps = Qt::NoPen;          break;
700   }
701   return ps;
702 }
703 /*!
704   Converts Qwt line style to Plot2d_Curve's line style [ static ]
705 */
706 static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
707 {
708   Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
709   switch ( p ) {
710   case Qt::SolidLine:
711     ps = Plot2d_Curve::Solid;      break;
712   case Qt::DashLine:
713     ps = Plot2d_Curve::Dash;       break;
714   case Qt::DotLine:
715     ps = Plot2d_Curve::Dot;        break;
716   case Qt::DashDotLine:
717     ps = Plot2d_Curve::DashDot;    break;
718   case Qt::DashDotDotLine:
719     ps = Plot2d_Curve::DashDotDot; break;
720   case Qt::NoPen:
721   default:
722     ps = Plot2d_Curve::NoPen;      break;
723   }
724   return ps;
725 }
726 /*!
727   Adds curve into view
728 */
729 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
730 {
731   if ( !curve )
732     return;
733   if ( hasCurve( curve ) ) {
734     updateCurve( curve, update );
735   }
736   else {
737     long curveKey = myPlot->insertCurve( curve->getVerTitle() );
738     myCurves.insert( curveKey, curve );
739     if ( curve->isAutoAssign() ) {
740       QwtSymbol::Style typeMarker;
741       QColor           color;
742       Qt::PenStyle     typeLine;
743       myPlot->getNextMarker( typeMarker, color, typeLine );
744       myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
745       myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker, 
746                                                    QBrush( color ), 
747                                                    QPen( color ), 
748                                                    QSize( myMarkerSize, myMarkerSize ) ) );
749       curve->setColor( color );
750       curve->setLine( qwt2plotLine( typeLine ) );
751       curve->setMarker( qwt2plotMarker( typeMarker ) );
752     }
753     else {
754       Qt::PenStyle     ps = plot2qwtLine( curve->getLine() );
755       QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
756       myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
757       myPlot->setCurveSymbol( curveKey, QwtSymbol( ms, 
758                                                    QBrush( curve->getColor() ), 
759                                                    QPen( curve->getColor() ), 
760                                                    QSize( myMarkerSize, myMarkerSize ) ) );
761     }
762     if ( myCurveType == 0 )
763       myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
764     else if ( myCurveType == 1 )
765       myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
766     else if ( myCurveType == 2 )
767       myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
768     myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
769   }
770   updateTitles();
771   if ( update )
772     myPlot->replot();
773 }
774 /*!
775   Adds curves into view
776 */
777 void Plot2d_ViewFrame::displayCurves( Plot2d_CurveContainer& curves, bool update )
778 {
779   myPlot->setUpdatesEnabled( false );
780   for ( int i = 0; i < curves.count(); i++ ) {
781     displayCurve( curves.curve( i ), false );
782   }
783 //  fitAll();
784   myPlot->setUpdatesEnabled( true );
785   if ( update )
786     myPlot->replot();
787 }
788 /*!
789   Erases curve
790 */
791 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
792 {
793   if ( !curve )
794     return;
795   int curveKey = hasCurve( curve );
796   if ( curveKey ) {
797     myPlot->removeCurve( curveKey );
798     myCurves.remove( curveKey );
799     updateTitles();
800     if ( update )
801       myPlot->replot();
802   }
803 }
804 /*!
805   Erases curves
806 */
807 void Plot2d_ViewFrame::eraseCurves( Plot2d_CurveContainer& curves, bool update )
808 {
809   for ( int i = 0; i < curves.count(); i++ ) {
810     eraseCurve( curves.curve( i ), false );
811   }
812 //  fitAll();
813   if ( update )
814     myPlot->replot();
815 }
816 /*!
817   Updates curves attributes
818 */
819 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
820 {
821   if ( !curve )
822     return;
823   int curveKey = hasCurve( curve );
824   if ( curveKey ) {
825     if ( !curve->isAutoAssign() ) {
826       Qt::PenStyle     ps = plot2qwtLine( curve->getLine() );
827       QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
828       myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
829       myPlot->setCurveSymbol( curveKey, QwtSymbol( ms, 
830                                                    QBrush( curve->getColor() ), 
831                                                    QPen( curve->getColor() ), 
832                                                    QSize( myMarkerSize, myMarkerSize ) ) );
833     }
834     myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
835     myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
836     myPlot->curve( curveKey )->setEnabled( true );
837     updateTitles();
838     if ( update )
839       myPlot->replot();
840   }
841 }
842 /*!
843   Returns curve key if is is displayed in the viewer and 0 otherwise
844 */
845 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
846 {
847   QIntDictIterator<Plot2d_Curve> it( myCurves );
848   for ( ; it.current(); ++it ) {
849     if ( it.current() == curve )
850       return it.currentKey();
851   }
852   return 0;
853 }
854 Plot2d_Curve* Plot2d_ViewFrame::getCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject )
855 {
856   if ( !theIObject.IsNull() ) {
857     QIntDictIterator<Plot2d_Curve> it( myCurves );
858     for ( ; it.current(); ++it ) {
859       if ( it.current()->hasIO() && it.current()->getIO()->isSame( theIObject ) )
860         return it.current();
861     }
862   }
863   return 0;
864 }
865 /*!
866   Gets lsit of displayed curves
867 */
868 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
869 {
870   clist.clear();
871   clist.setAutoDelete( false );
872   QIntDictIterator<Plot2d_Curve> it( myCurves );
873   for ( ; it.current(); ++it ) {
874     clist.append( it.current() );
875   }
876   return clist.count();
877 }
878
879 /*!
880   Updates titles according to curves
881 */
882 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
883 void Plot2d_ViewFrame::updateTitles() 
884 {
885   QAD_Study* activeStudy = QAD_Application::getDesktop()->getActiveStudy();
886   QIntDictIterator<Plot2d_Curve> it( myCurves );
887   QStringList aXTitles;
888   QStringList aYTitles;
889   QStringList aXUnits;
890   QStringList aYUnits;
891   QStringList aTables;
892   int i = 0;
893   while ( it.current() ) {
894     // collect titles and units from all curves...
895     QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
896     QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
897     QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
898     QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
899     
900     aYTitles.append( yTitle );
901     if ( aXTitles.find( xTitle ) == aXTitles.end() )
902       aXTitles.append( xTitle );
903     if ( aXUnits.find( xUnits ) == aXUnits.end() )
904       aXUnits.append( xUnits );
905     if ( aYUnits.find( yUnits ) == aYUnits.end() )
906       aYUnits.append( yUnits );
907
908     if ( activeStudy && it.current()->hasTableIO() ) { 
909       SALOMEDS::SObject_var SO = activeStudy->getStudyDocument()->FindObjectID( it.current()->getTableIO()->getEntry() );
910       if ( !SO->_is_nil() ) {
911         SALOMEDS::GenericAttribute_var anAttr;
912         if ( SO->FindAttribute( anAttr, "AttributeName" ) ) {
913           SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow( anAttr );
914           QString aName = aNameAttr->Value();
915           if ( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
916             aTables.append( aName );
917         }
918       }
919     }
920
921     ++it;
922     ++i;
923   }
924   // ... and update plot 2d view
925   QString xUnits, yUnits;
926   if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
927     xUnits = BRACKETIZE( aXUnits[0] );
928   if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
929     yUnits = BRACKETIZE( aYUnits[0] );
930   QString xTitle, yTitle;
931   if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
932     xTitle = aXTitles[0];
933   if ( aYTitles.count() == 1 )
934     yTitle = aYTitles[0];
935
936   if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
937     xTitle += " ";
938   if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
939     yTitle += " ";
940
941   setXTitle( myXTitleEnabled, xTitle + xUnits );
942   setYTitle( myYTitleEnabled, yTitle + yUnits );
943   setTitle( aTables.join("; ") );
944 }
945 /*!
946   Fits the view to see all data
947 */
948 void Plot2d_ViewFrame::fitAll()
949 {
950   myPlot->setAxisAutoScale( QwtPlot::yLeft );
951   myPlot->setAxisAutoScale( QwtPlot::xBottom );
952   myPlot->replot();
953 }
954 /*!
955   Fits the view to rectangle area (pixels)
956 */
957 void Plot2d_ViewFrame::fitArea( const QRect& area )
958 {
959   QRect rect = area.normalize();
960   if ( rect.width() < MIN_RECT_SIZE ) {
961     rect.setWidth( MIN_RECT_SIZE );
962     rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
963   }
964   if ( rect.height() < MIN_RECT_SIZE ) {
965     rect.setHeight( MIN_RECT_SIZE );
966     rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
967   }
968   myPlot->setAxisScale( QwtPlot::yLeft, 
969                         myPlot->invTransform( QwtPlot::yLeft, rect.top() ), 
970                         myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
971   myPlot->setAxisScale( QwtPlot::xBottom, 
972                         myPlot->invTransform( QwtPlot::xBottom, rect.left() ), 
973                         myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
974   myPlot->replot();
975 }
976 /*!
977   Tests if it is necessary to start operation on mouse action
978 */
979 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
980 {
981   int btn = me.button() | me.state();
982   int zoomBtn = ControlButton | LeftButton;
983   int panBtn  = ControlButton | MidButton;
984   int fitBtn  = ControlButton | RightButton;
985
986   if ( btn == zoomBtn )
987     return ZoomId;
988   if ( btn == panBtn ) 
989     return PanId;
990   if ( btn == fitBtn )
991     return FitAreaId;
992   return NoOpId;
993 }
994 /*!
995   Mode toolbar buttons slot - horizontal axis (<Linear>/<Logarithmic>)
996 */
997 void Plot2d_ViewFrame::onHorMode()
998 {
999   if ( myActions[ ModeXLinearId ]->isOn() )
1000     setHorScaleMode( 0 );
1001   else if ( myActions[ ModeXLogarithmicId ]->isOn() )
1002     setHorScaleMode( 1 );
1003 }
1004 /*!
1005   Mode toolbar buttons slot - vertical axis (<Linear>/<Logarithmic>)
1006 */
1007 void Plot2d_ViewFrame::onVerMode()
1008 {
1009   if ( myActions[ ModeYLinearId ]->isOn() )
1010     setVerScaleMode( 0 );
1011   else if ( myActions[ ModeYLogarithmicId ]->isOn() )
1012     setVerScaleMode( 1 );
1013 }
1014 /*!
1015   "Show/hide legend" toolbar action slot
1016 */
1017 void Plot2d_ViewFrame::onLegend()
1018 {
1019   showLegend( myActions[ LegendId ]->isOn() );
1020 }
1021 /*!
1022   "Curve type" toolbar action slot
1023 */
1024 void Plot2d_ViewFrame::onCurves()
1025 {
1026   if ( myActions[ CurvePointsId ]->isOn() )
1027     setCurveType( 0 );
1028   else if ( myActions[ CurveLinesId ]->isOn() )
1029     setCurveType( 1 );
1030   else if ( myActions[ CurveSplinesId ]->isOn() )
1031     setCurveType( 2 );
1032 }
1033 /*!
1034   "Settings" toolbar action slot
1035 */
1036 void Plot2d_ViewFrame::onSettings()
1037 {
1038 #ifdef TEST_AUTOASSIGN
1039   typedef QMap<int,int> IList;
1040   typedef QMap<QString,int> SList;
1041   IList mars, lins;
1042   SList cols;
1043   cols[ "red-min" ]   = 1000;
1044   cols[ "red-max" ]   = -1;
1045   cols[ "green-min" ] = 1000;
1046   cols[ "green-max" ] = -1;
1047   cols[ "blue-min" ]  = 1000;
1048   cols[ "blue-max" ]  = -1;
1049   for ( unsigned i = 0; i < 10000; i++ ) {
1050     QwtSymbol::Style typeMarker;
1051     QColor           color;
1052     Qt::PenStyle     typeLine;
1053     myPlot->getNextMarker( typeMarker, color, typeLine );
1054     if ( mars.contains(typeMarker) )
1055       mars[ typeMarker ] = mars[ typeMarker ]+1;
1056     else
1057       mars[ typeMarker ] = 0;
1058     if ( lins.contains(typeLine) )
1059       lins[ typeLine ] = lins[ typeLine ]+1;
1060     else
1061       lins[ typeLine ] = 0;
1062     if ( cols[ "red-max" ] < color.red() )
1063       cols[ "red-max" ] = color.red();
1064     if ( cols[ "red-min" ] > color.red() )
1065       cols[ "red-min" ] = color.red();
1066     if ( cols[ "green-max" ] < color.green() )
1067       cols[ "green-max" ] = color.green();
1068     if ( cols[ "green-min" ] > color.green() )
1069       cols[ "green-min" ] = color.green();
1070     if ( cols[ "blue-max" ] < color.blue() )
1071       cols[ "blue-max" ] = color.blue();
1072     if ( cols[ "blue-min" ] > color.blue() )
1073       cols[ "blue-min" ] = color.blue();
1074   }
1075   for (IList::Iterator it = mars.begin();  it != mars.end(); ++it)
1076     MESSAGE("markers( " << it.key() << ") = " << it.data() );
1077   for (IList::Iterator it = lins.begin();  it != lins.end(); ++it)
1078     MESSAGE("lines( " << it.key() << ") = " << it.data() );
1079   for (SList::Iterator it = cols.begin();  it != cols.end(); ++it)
1080     MESSAGE("colors( " << it.key() << ") = " << it.data() );
1081 #endif
1082   
1083   Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true );
1084   dlg->setMainTitle( myTitleEnabled, myTitle );
1085   dlg->setXTitle( myXTitleEnabled, myXTitle );
1086   dlg->setYTitle( myYTitleEnabled, myYTitle );
1087   dlg->setCurveType( myCurveType );
1088   dlg->setLegend( myShowLegend, myLegendPos );
1089   dlg->setMarkerSize( myMarkerSize );
1090   dlg->setBackgroundColor( myBackground );
1091   dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
1092                      myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ) );
1093   dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
1094                      myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ) );
1095   dlg->setScaleMode( myXMode, myYMode );
1096
1097   if ( dlg->exec() == QDialog::Accepted ) {
1098     // horizontal axis title
1099     setXTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), false );
1100     // vertical axis title
1101     setYTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), false );
1102     // main title
1103     setMainTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), true );
1104     // curve type
1105     if ( myCurveType != dlg->getCurveType() ) {
1106       setCurveType( dlg->getCurveType(), false );
1107     }
1108     // legend
1109     if ( myShowLegend != dlg->isLegendEnabled() ) {
1110       showLegend( dlg->isLegendEnabled(), false );
1111     }
1112     if ( myLegendPos != dlg->getLegendPos() ) {
1113       setLegendPos( dlg->getLegendPos() );
1114     }
1115     // marker size
1116     if ( myMarkerSize != dlg->getMarkerSize() ) {
1117       setMarkerSize( dlg->getMarkerSize(), false );
1118     }
1119     // background color
1120     if ( myBackground != dlg->getBackgroundColor() ) {
1121       setBackgroundColor( dlg->getBackgroundColor() );
1122     }
1123     // grid
1124     bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled;
1125     int  aXGridMaxMajor,     aXGridMaxMinor,     aYGridMaxMajor,     aYGridMaxMinor;
1126     dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor );
1127     dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor );
1128     setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1129     setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor, false );
1130     // scale mode
1131     if ( myXMode != dlg->getXScaleMode() ) {
1132       setHorScaleMode( dlg->getXScaleMode() );
1133     }
1134     if ( myYMode != dlg->getYScaleMode() ) {
1135       setVerScaleMode( dlg->getYScaleMode() );
1136     }
1137     // update view
1138     myPlot->replot();
1139     // update preferences
1140     if ( dlg->isSetAsDefault() ) 
1141       writePreferences();
1142   }
1143   delete dlg;
1144 }
1145 /*!
1146   "Fit Data" command slot
1147 */
1148 void Plot2d_ViewFrame::onFitData()
1149 {
1150   Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this );
1151   int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
1152   int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
1153   int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
1154   int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
1155   double xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
1156   double xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
1157   double yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
1158   double yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
1159   
1160   dlg->setRange( xMin, xMax, yMin, yMax );
1161   if ( dlg->exec() == QDialog::Accepted ) {
1162     int mode = dlg->getRange( xMin, xMax, yMin, yMax );
1163     if ( mode == 0 || mode == 2 ) 
1164       myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
1165     if ( mode == 0 || mode == 1 ) 
1166       myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax ); 
1167     myPlot->replot();
1168   }
1169   delete dlg;
1170 }
1171 /*!
1172   Change background color
1173 */
1174 void Plot2d_ViewFrame::onChangeBackground()
1175 {
1176   QColor selColor = QColorDialog::getColor ( backgroundColor(), this ); 
1177   if ( selColor.isValid() ) {
1178     setBackgroundColor( selColor );
1179   }
1180 }
1181 /*!
1182   Sets curve type
1183 */
1184 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1185 {
1186   myCurveType = curveType;
1187   if ( curveType == 0 )
1188     myActions[ CurvePointsId ]->setOn( true );
1189   else if ( curveType == 1 )
1190     myActions[ CurveLinesId ]->setOn( true );
1191   else if ( curveType == 2 )
1192     myActions[ CurveSplinesId ]->setOn( true );
1193   
1194   QArray<long> keys = myPlot->curveKeys();
1195   for ( int i = 0; i < keys.count(); i++ ) {
1196     if ( myCurveType == 0 )
1197       myPlot->setCurveStyle( keys[i], QwtCurve::NoCurve );
1198     else if ( myCurveType == 1 )
1199       myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1200     else if ( myCurveType == 2 )
1201       myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1202   }
1203   if ( update )
1204     myPlot->replot();
1205 }
1206 /*!
1207   Shows/hides legend
1208 */
1209 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1210 {
1211   myShowLegend = show;
1212   myActions[ LegendId ]->setOn( myShowLegend );
1213   {
1214     myPlot->setAutoLegend( myShowLegend );
1215     myPlot->enableLegend( myShowLegend );
1216   }
1217   if ( update )
1218     myPlot->replot();
1219 }
1220 /*!
1221   Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1222 */
1223 void Plot2d_ViewFrame::setLegendPos( int pos )
1224 {
1225   myLegendPos = pos;
1226   switch( pos ) {
1227   case 0:
1228     myPlot->setLegendPos( Qwt::Left );
1229     break;
1230   case 1:
1231     myPlot->setLegendPos( Qwt::Right );
1232     break;
1233   case 2:
1234     myPlot->setLegendPos( Qwt::Top );
1235     break;
1236   case 3:
1237     myPlot->setLegendPos( Qwt::Bottom );
1238     break;
1239   }
1240 }
1241 /*!
1242   Sets new marker size
1243 */
1244 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1245 {
1246   if ( myMarkerSize != size ) {
1247     myMarkerSize = size;
1248     QArray<long> keys = myPlot->curveKeys();
1249     for ( int i = 0; i < keys.count(); i++ ) {
1250       QwtPlotCurve* crv = myPlot->curve( keys[i] );
1251       if ( crv ) {
1252         QwtSymbol aSymbol = crv->symbol();
1253         aSymbol.setSize( myMarkerSize, myMarkerSize );
1254         crv->setSymbol( aSymbol );
1255         int legendIndex = myPlot->getLegend()->findFirstKey( keys[i] );
1256         if ( legendIndex != myPlot->getLegend()->itemCnt() )
1257           myPlot->getLegend()->setSymbol( legendIndex, aSymbol );
1258       }
1259     }
1260     if ( update )
1261       myPlot->replot();
1262   }
1263 }
1264 /*!
1265   Sets background color
1266 */
1267 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1268 {
1269   myBackground = color;
1270   //myPlot->setCanvasBackground( myBackground );
1271   myPlot->canvas()->setPalette( myBackground );
1272   myPlot->setPalette( myBackground );
1273   QPalette aPal = myPlot->getLegend()->palette();
1274   for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1275     QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1276     aPal.setColor( cg, QColorGroup::Base, myBackground );
1277     aPal.setColor( cg, QColorGroup::Background, myBackground );
1278   }
1279   myPlot->getLegend()->setPalette( aPal );
1280 }
1281 /*!
1282   Gets background color
1283 */
1284 QColor Plot2d_ViewFrame::backgroundColor() const
1285 {
1286   return myBackground;
1287 }
1288 /*!
1289   Sets hor.axis grid parameters
1290 */
1291 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax, 
1292                                  bool xMinorEnabled, const int xMinorMax, 
1293                                  bool update )
1294 {
1295   myXGridMajorEnabled = xMajorEnabled;
1296   myXGridMinorEnabled = xMinorEnabled;
1297   myXGridMaxMajor = xMajorMax;
1298   myXGridMaxMinor = xMinorMax;
1299   myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1300   myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1301   myPlot->enableGridX( myXGridMajorEnabled );
1302   myPlot->enableGridXMin( myXGridMinorEnabled );
1303   if ( update )
1304     myPlot->replot();
1305 }
1306 /*!
1307   Sets ver.axis grid parameters
1308 */
1309 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax, 
1310                                  bool yMinorEnabled, const int yMinorMax, 
1311                                  bool update )
1312 {
1313   myYGridMajorEnabled = yMajorEnabled;
1314   myYGridMinorEnabled = yMinorEnabled;
1315   myYGridMaxMajor = yMajorMax;
1316   myYGridMaxMinor = yMinorMax;
1317   myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1318   myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1319   myPlot->enableGridY( myYGridMajorEnabled );
1320   myPlot->enableGridYMin( myYGridMinorEnabled );
1321   if ( update )
1322     myPlot->replot();
1323 }
1324 /*!
1325   Sets main title
1326 */
1327 void Plot2d_ViewFrame::setMainTitle( bool enabled, const QString& title, bool update )
1328 {
1329   myTitleEnabled = enabled;
1330   myTitle = title;
1331   myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1332   if ( update )
1333     myPlot->replot();
1334 }
1335 /*!
1336   Sets hor.axis title
1337 */
1338 void Plot2d_ViewFrame::setXTitle( bool enabled, const QString& title, bool update )
1339 {
1340   myXTitleEnabled = enabled;
1341   myXTitle = title;
1342   myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1343   if ( update )
1344     myPlot->replot();
1345 }
1346 /*!
1347   Sets ver.axis title
1348 */
1349 void Plot2d_ViewFrame::setYTitle( bool enabled, const QString& title, bool update )
1350 {
1351   myYTitleEnabled = enabled;
1352   myYTitle = title;
1353   myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1354   if ( update )
1355     myPlot->replot();
1356 }
1357 /*!
1358   Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1359 */
1360 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1361 {
1362   myXMode = mode;
1363   if ( myXMode == 0 ) { // linear
1364     myActions[ ModeXLogarithmicId ]->setOn( false );
1365     myActions[ ModeXLinearId ]->setOn( true );
1366     myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1367   }
1368   else {               // logarithmic
1369     myActions[ ModeXLinearId ]->setOn( false );
1370     myActions[ ModeXLogarithmicId ]->setOn( true );
1371     myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
1372   }
1373   if ( update )
1374 //    myPlot->replot();
1375     fitAll();
1376 }
1377 /*!
1378   Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1379 */
1380 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1381 {
1382   myYMode = mode;
1383   if ( myYMode == 0 ) { // linear
1384     myActions[ ModeYLogarithmicId ]->setOn( false );
1385     myActions[ ModeYLinearId ]->setOn( true );
1386     myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1387   }
1388   else {               // logarithmic
1389     myActions[ ModeYLinearId ]->setOn( false );
1390     myActions[ ModeYLogarithmicId ]->setOn( true );
1391     myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
1392   }
1393   if ( update )
1394 //    myPlot->replot();
1395     fitAll();
1396 }
1397 /*!
1398   Slot, called when Legend item is clicked
1399 */
1400 void Plot2d_ViewFrame::onLegendClicked( long key )
1401 {
1402   Plot2d_Curve* curve = myCurves[ key ];
1403   if ( curve && curve->hasIO() ) {
1404     SALOME_Selection* Sel = SALOME_Selection::Selection( QAD_Application::getDesktop()->getActiveStudy()->getSelection() );
1405     Sel->ClearIObjects();
1406     Sel->AddIObject( curve->getIO(), true );
1407   }
1408 }
1409
1410 /*!
1411   Slot, called when user presses mouse button
1412 */
1413 void Plot2d_ViewFrame::plotMousePressed( const QMouseEvent& me )
1414 {
1415   if ( myOperation == NoOpId )
1416     myOperation = testOperation( me );
1417   if ( myOperation != NoOpId ) {
1418     myPnt = me.pos();
1419     if ( myOperation == ZoomId ) {
1420       myPlot->canvas()->setCursor( QCursor( QPixmap( imageZoomCursor ) ) );
1421     }
1422     else if ( myOperation == PanId ) {
1423       myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
1424     }
1425     else if ( myOperation == FitAreaId ) {
1426       myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1427       myPlot->setOutlineStyle( Qwt::Rect );
1428     }
1429   }
1430   else {
1431     int btn = me.button() | me.state();
1432     if ( btn == RightButton ) {
1433       createPopup();
1434       if ( myPopup ) {
1435         QAD_Tools::checkPopup( myPopup );
1436         if ( myPopup->count()>0 ) {
1437           myPopup->exec( QCursor::pos() );
1438         }
1439         destroyPopup();
1440       }
1441     }
1442     else {
1443       myPlot->setOutlineStyle( Qwt::Cross );
1444       QAD_Application::getDesktop()->putInfo( getInfo( me.pos() ) );
1445     }
1446   }
1447 }
1448 /*!
1449   Slot, called when user moves mouse
1450 */
1451 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1452 {
1453   int    dx = me.pos().x() - myPnt.x();
1454   int    dy = me.pos().y() - myPnt.y();
1455
1456   if ( myOperation != NoOpId) {
1457     if ( myOperation == ZoomId ) {
1458       this->incrementalZoom( dx, dy ); 
1459       myPnt = me.pos();
1460     }
1461     else if ( myOperation == PanId ) {
1462       this->incrementalPan( dx, dy );
1463       myPnt = me.pos();
1464     }
1465   }
1466   else {
1467     QAD_Application::getDesktop()->putInfo( getInfo( me.pos() ) );
1468   }
1469 }
1470 /*!
1471   Slot, called when user releases mouse
1472 */
1473 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1474 {
1475   if ( myOperation == FitAreaId ) {
1476     QRect rect( myPnt, me.pos() );
1477     fitArea( rect );
1478   }
1479   myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1480   myPlot->setOutlineStyle( Qwt::Triangle );
1481   QAD_Application::getDesktop()->putInfo( tr( "INF_READY" ) );
1482   myOperation = NoOpId;
1483 }
1484 /*!
1485   View operations : Pan view
1486 */
1487 void Plot2d_ViewFrame::onViewPan() 
1488
1489   myOperation = PanId;
1490   qApp->installEventFilter( this );
1491 }
1492 /*!
1493   View operations : Zoom view
1494 */
1495 void Plot2d_ViewFrame::onViewZoom() 
1496 {
1497   myOperation = ZoomId;
1498   qApp->installEventFilter( this );
1499 }
1500 /*!
1501   View operations : Fot All
1502 */
1503 void Plot2d_ViewFrame::onViewFitAll() 
1504
1505   fitAll();
1506 }
1507 /*!
1508   View operations : Fit Area
1509 */
1510 void Plot2d_ViewFrame::onViewFitArea() 
1511 {
1512   myOperation = FitAreaId;
1513   qApp->installEventFilter( this );
1514 }
1515 /*!
1516   View operations : Global panning
1517 */
1518 void Plot2d_ViewFrame::onViewGlobalPan() 
1519 { MESSAGE( "Plot2d_ViewFrame::onViewGlobalPan : NOT SUPPORTED" ); }
1520 /*!
1521   View operations : Rotate view
1522 */
1523 void Plot2d_ViewFrame::onViewRotate() 
1524 { MESSAGE( "Plot2d_ViewFrame::onViewRotate : NOT SUPPORTED" ); }
1525 /*!
1526   View operations : Reset view
1527 */
1528 void Plot2d_ViewFrame::onViewReset() 
1529 { MESSAGE( "Plot2d_ViewFrame::onViewReset : NOT SUPPORTED" ); }
1530 /*!
1531   View operations : View front
1532 */
1533 void Plot2d_ViewFrame::onViewFront() 
1534 { MESSAGE( "Plot2d_ViewFrame::onViewFront : NOT SUPPORTED" ); }
1535 /*!
1536   View operations : View back
1537 */
1538 void Plot2d_ViewFrame::onViewBack() 
1539 { MESSAGE( "Plot2d_ViewFrame::onViewBack : NOT SUPPORTED" ); }
1540 /*!
1541   View operations : View right
1542 */
1543 void Plot2d_ViewFrame::onViewRight() 
1544 { MESSAGE( "Plot2d_ViewFrame::onViewRight : NOT SUPPORTED" ); }
1545 /*!
1546   View operations : View left
1547 */
1548 void Plot2d_ViewFrame::onViewLeft() 
1549 { MESSAGE( "Plot2d_ViewFrame::onViewLeft : NOT SUPPORTED" ); }
1550 /*!
1551   View operations : View bottom
1552 */
1553 void Plot2d_ViewFrame::onViewBottom() 
1554 { MESSAGE( "Plot2d_ViewFrame::onViewBottom : NOT SUPPORTED" ); }
1555 /*!
1556   View operations : View top
1557 */
1558 void Plot2d_ViewFrame::onViewTop() 
1559 { MESSAGE( "Plot2d_ViewFrame::onViewTop : NOT SUPPORTED" ); }
1560 /*!
1561   View operations : Show/hide trihedron
1562 */
1563 void Plot2d_ViewFrame::onViewTrihedron() 
1564 { MESSAGE( "Plot2d_ViewFrame::onViewTrihedron : NOT SUPPORTED" ); }
1565
1566
1567 //=================================================================================
1568 // Plot2d_Plot2d implementation
1569 //=================================================================================
1570
1571 /*!
1572   Constructor
1573 */
1574 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1575      : QwtPlot( parent )
1576 {
1577   // outline
1578   enableOutline( true );
1579   setOutlineStyle( Qwt::Triangle );
1580   setOutlinePen( green );
1581   // legend
1582   setAutoLegend( false );
1583   setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1584   enableLegend( false );
1585   // grid
1586   enableGridX( false );
1587   enableGridXMin( false );
1588   enableGridY( false );
1589   enableGridYMin( false );
1590   // auto scaling by default
1591   setAxisAutoScale( QwtPlot::yLeft );
1592   setAxisAutoScale( QwtPlot::xBottom );
1593 }
1594 /*!
1595   Recalculates and redraws Plot 2d view 
1596 */
1597 void Plot2d_Plot2d::replot()
1598 {
1599   updateLayout();  // to fix bug(?) of Qwt - view is not updated when title is changed
1600   QwtPlot::replot(); 
1601 }
1602 /*!
1603   Checks if two colors are close to each other [ static ]
1604   uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1605 */
1606 const long COLOR_DISTANCE = 100;
1607 const int  MAX_ATTEMPTS   = 10;
1608 static bool closeColors( const QColor& color1, const QColor& color2 )
1609 {
1610   long tol = abs( color2.red()   - color1.red() ) + 
1611              abs( color2.green() - color1.green() ) +
1612              abs( color2.blue()  - color1.blue() );
1613
1614   return ( tol <= COLOR_DISTANCE );
1615 }
1616 /*!
1617   Gets new unique marker for item if possible
1618 */
1619 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine ) 
1620 {
1621   bool bOk = false;
1622   int cnt = 1;
1623   while ( !bOk ) {
1624     int aRed    = (int)( 256.0 * random() / RAND_MAX);    // generate random color
1625     int aGreen  = (int)( 256.0 * random() / RAND_MAX);    // ...
1626     int aBlue   = (int)( 256.0 * random() / RAND_MAX);    // ...
1627     int aMarker = (int)( 9.0 * random() / RAND_MAX) + 1;  // 9 markers types ( not including empty )
1628     int aLine   = (int)( 5.0 * random() / RAND_MAX) + 1;  // 5 line types ( not including empty )
1629
1630     typeMarker = ( QwtSymbol::Style )aMarker;
1631     color      = QColor( aRed, aGreen, aBlue );
1632     typeLine   = ( Qt::PenStyle )aLine;
1633
1634     cnt++;
1635     if ( cnt == MAX_ATTEMPTS )
1636       bOk = true;
1637     else
1638       bOk = !existMarker( typeMarker, color, typeLine );
1639   }
1640 /*
1641   static int aMarker = -1;
1642   static int aColor  = -1;
1643   static int aLine   = -1;
1644
1645   if ( myColors.isEmpty() ) {
1646     // creating colors list
1647     myColors.append( Qt::white );
1648     myColors.append( Qt::blue );
1649     myColors.append( Qt::gray );
1650     myColors.append( Qt::darkGreen );
1651     myColors.append( Qt::magenta );
1652     myColors.append( Qt::darkGray );
1653     myColors.append( Qt::red );
1654     myColors.append( Qt::darkBlue );
1655     myColors.append( Qt::darkYellow );
1656     myColors.append( Qt::cyan );
1657     myColors.append( Qt::darkRed );
1658     myColors.append( Qt::darkCyan );
1659     myColors.append( Qt::yellow );
1660     myColors.append( Qt::darkMagenta );
1661     myColors.append( Qt::green );
1662     myColors.append( Qt::black );
1663   }
1664
1665   int nbMarkers = 11;                   // QwtSymbol supports 11 marker types
1666   int nbLines   = 6;                    // Qt supports 6 line types
1667   int nbColors  = myColors.count();     // number of default colors supported
1668
1669   aMarker = ( aMarker + 1 ) % nbMarkers;  
1670   if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1671   aColor  = ( aColor  + 1 ) % nbColors;
1672   aLine   = ( aLine   + 1 ) % nbLines;    
1673   if ( aLine == Qt::NoPen ) aLine++;             
1674
1675   typeMarker = ( QwtSymbol::Style )aMarker;
1676   color      = myColors[ aColor ];
1677   typeLine   = ( Qt::PenStyle )aLine;
1678   if ( !existMarker( typeMarker, color, typeLine ) )
1679     return;
1680
1681   int i, j, k;
1682   for ( i = 0; i < nbMarkers; i++ ) {
1683     aMarker = ( aMarker + 1 ) % nbMarkers;
1684     if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1685     for ( j = 0; j < nbColors; j++ ) {
1686       aColor  = ( aColor  + 1 ) % nbColors;
1687       for ( k = 0; k < nbLines; k++ ) {
1688         aLine = ( aLine + 1 ) % nbLines;
1689         if ( aLine == Qt::NoPen ) aLine++;             
1690         if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1691           typeMarker = ( QwtSymbol::Style )aMarker;
1692           color      = myColors[ aColor ];
1693           typeLine   = ( Qt::PenStyle )aLine;
1694           return;
1695         }
1696       }
1697     }
1698   }
1699 */
1700 }
1701 /*!
1702   Checks if marker belongs to any enitity
1703 */
1704 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine ) 
1705 {
1706   // getting all curves
1707   QArray<long> keys = curveKeys();
1708   QColor aRgbColor;
1709
1710   if ( closeColors( color, backgroundColor() ) )
1711       return true;
1712   for ( int i = 0; i < keys.count(); i++ ) {
1713     QwtPlotCurve* crv = curve( keys[i] );
1714     if ( crv ) {
1715       QwtSymbol::Style aStyle = crv->symbol().style();
1716       QColor           aColor = crv->pen().color();
1717       Qt::PenStyle     aLine  = crv->pen().style();
1718 //      if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1719       if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1720         return true;
1721     }
1722   }
1723   return false;
1724 }
1725
1726 //==========================================================
1727 /*!
1728  *  Plot2d_ViewFrame::Display
1729  *  Display presentation
1730  */
1731 //==========================================================
1732 void Plot2d_ViewFrame::Display( const SALOME_Prs2d* prs )
1733 {
1734   // try do downcast object
1735   const Plot2d_Prs* aPlot2dPrs = dynamic_cast<const Plot2d_Prs*>( prs );
1736   if ( !aPlot2dPrs || aPlot2dPrs->IsNull() )
1737     return;
1738
1739   // display all curves from presentation
1740   Plot2d_CurveContainer aCurves = aPlot2dPrs->GetObjects();
1741   displayCurves( aCurves );
1742 }
1743
1744 //==========================================================
1745 /*!
1746  *  Plot2d_ViewFrame::Erase
1747  *  Erase presentation
1748  */
1749 //==========================================================
1750 void Plot2d_ViewFrame::Erase( const SALOME_Prs2d* prs, const bool )
1751 {
1752   // try do downcast object
1753   const Plot2d_Prs* aPlot2dPrs = dynamic_cast<const Plot2d_Prs*>( prs );
1754   if ( !aPlot2dPrs || aPlot2dPrs->IsNull() )
1755     return;
1756
1757   // erase all curves from presentation
1758   Plot2d_CurveContainer aCurves = aPlot2dPrs->GetObjects();
1759   eraseCurves( aCurves );
1760 }
1761   
1762 //==========================================================
1763 /*!
1764  *  Plot2d_ViewFrame::CreatePrs
1765  *  Create presentation by entry
1766  */
1767 //==========================================================
1768 SALOME_Prs* Plot2d_ViewFrame::CreatePrs( const char* entry )
1769 {
1770   Plot2d_Prs* prs = new Plot2d_Prs();
1771   if ( entry ) {
1772     QIntDictIterator<Plot2d_Curve> it( myCurves );
1773     for ( ; it.current(); ++it ) {
1774       if ( it.current()->hasIO() && !strcmp( it.current()->getIO()->getEntry(), entry ) ) {
1775         prs->AddObject( it.current() );
1776       }
1777     }
1778   }
1779   return prs;
1780 }
1781
1782 //==========================================================
1783 /*!
1784  *  Plot2d_ViewFrame::BeforeDisplay
1785  *  Axiluary method called before displaying of objects
1786  */
1787 //==========================================================
1788 void  Plot2d_ViewFrame::BeforeDisplay( SALOME_Displayer* d )
1789 {
1790   d->BeforeDisplay( this, SALOME_Plot2dViewType() );
1791 }
1792
1793 //==========================================================
1794 /*!
1795  *  Plot2d_ViewFrame::AfterDisplay
1796  *  Axiluary method called after displaying of objects
1797  */
1798 //==========================================================
1799 void  Plot2d_ViewFrame::AfterDisplay( SALOME_Displayer* d )
1800 {
1801   d->AfterDisplay( this, SALOME_Plot2dViewType() );
1802 }
1803
1804 #define INCREMENT_FOR_OP 10
1805
1806 //=======================================================================
1807 // Plot2d_ViewFrame::onPanLeft
1808 // Performs incremental panning to the left
1809 //=======================================================================
1810 void Plot2d_ViewFrame::onPanLeft()
1811 {
1812   this->incrementalPan( -INCREMENT_FOR_OP, 0 );
1813 }
1814
1815 //=======================================================================
1816 // Plot2d_ViewFrame::onPanRight
1817 // Performs incremental panning to the right
1818 //=======================================================================
1819 void Plot2d_ViewFrame::onPanRight()
1820 {
1821   this->incrementalPan( INCREMENT_FOR_OP, 0 );
1822 }
1823
1824 //=======================================================================
1825 // Plot2d_ViewFrame::onPanUp
1826 // Performs incremental panning to the top
1827 //=======================================================================
1828 void Plot2d_ViewFrame::onPanUp()
1829 {
1830   this->incrementalPan( 0, -INCREMENT_FOR_OP );
1831 }
1832
1833 //=======================================================================
1834 // Plot2d_ViewFrame::onPanDown
1835 // Performs incremental panning to the bottom
1836 //=======================================================================
1837 void Plot2d_ViewFrame::onPanDown()
1838 {
1839   this->incrementalPan( 0, INCREMENT_FOR_OP );
1840 }
1841
1842 //=======================================================================
1843 // Plot2d_ViewFrame::onZoomIn
1844 // Performs incremental zooming in
1845 //=======================================================================
1846 void Plot2d_ViewFrame::onZoomIn()
1847 {
1848   this->incrementalZoom( INCREMENT_FOR_OP, INCREMENT_FOR_OP );
1849 }
1850
1851 //=======================================================================
1852 // Plot2d_ViewFrame::onZoomOut
1853 // Performs incremental zooming out
1854 //=======================================================================
1855 void Plot2d_ViewFrame::onZoomOut()
1856 {
1857   this->incrementalZoom( -INCREMENT_FOR_OP, -INCREMENT_FOR_OP );
1858 }
1859
1860 //=======================================================================
1861 // Plot2d_ViewFrame::incrementalPan
1862 // Incremental zooming operation
1863 //=======================================================================
1864 void Plot2d_ViewFrame::incrementalPan( const int incrX, const int incrY ) {
1865   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1866   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1867   
1868   myPlot->setAxisScale( QwtPlot::yLeft,
1869                         myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-incrY ),
1870                         myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-incrY ) );
1871   myPlot->setAxisScale( QwtPlot::xBottom,
1872                         myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-incrX ),
1873                         myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-incrX ) );
1874   myPlot->replot();
1875 }
1876
1877 //=======================================================================
1878 // Plot2d_ViewFrame::incrementalZoom
1879 // Incremental panning operation
1880 //=======================================================================
1881 void Plot2d_ViewFrame::incrementalZoom( const int incrX, const int incrY ) {
1882   QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1883   QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1884   
1885   myPlot->setAxisScale( QwtPlot::yLeft,
1886                        myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1887                        myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + incrY ) );
1888   myPlot->setAxisScale( QwtPlot::xBottom,
1889                        myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1890                        myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - incrX ) );
1891   myPlot->replot();
1892 }
1893