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