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