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