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