1 // Copyright (C) 2003 CEA/DEN, EDF R&D
5 // File : Plot2d_ViewFrame.cxx
6 // Author : Vadim SANDLER
10 #include "Plot2d_ViewFrame.h"
11 #include "Plot2d_SetupViewDlg.h"
12 #include "Plot2d_Prs.h"
14 #include "QAD_Desktop.h"
15 #include "QAD_ResourceMgr.h"
16 #include "QAD_FileDlg.h"
17 #include "QAD_Tools.h"
18 #include "QAD_MessageBox.h"
19 #include "QAD_Config.h"
20 #include "SALOME_Selection.h"
21 #include "Plot2d_CurveContainer.h"
22 #include "Plot2d_Curve.h"
23 #include "Plot2d_FitDataDlg.h"
24 #include "utilities.h"
25 #include "qapplication.h"
27 #include <qtoolbutton.h>
29 #include <qcolordialog.h>
31 #include <qwt_plot_canvas.h>
33 #include "utilities.h"
36 #include <SALOMEconfig.h>
37 #include CORBA_SERVER_HEADER(SALOMEDS)
38 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
41 #define DEFAULT_LINE_WIDTH 0 // (default) line width
42 #define DEFAULT_MARKER_SIZE 9 // default marker size
43 #define MIN_RECT_SIZE 11 // min sensibility area size
46 const char* imageZoomCursor[] = {
51 "................................",
52 "................................",
53 ".#######........................",
54 "..aaaaaaa.......................",
55 "................................",
56 ".............#####..............",
57 "...........##.aaaa##............",
58 "..........#.aa.....a#...........",
59 ".........#.a.........#..........",
60 ".........#a..........#a.........",
61 "........#.a...........#.........",
62 "........#a............#a........",
63 "........#a............#a........",
64 "........#a............#a........",
65 "........#a............#a........",
66 ".........#...........#.a........",
67 ".........#a..........#a.........",
68 ".........##.........#.a.........",
69 "........#####.....##.a..........",
70 ".......###aaa#####.aa...........",
71 "......###aa...aaaaa.......#.....",
72 ".....###aa................#a....",
73 "....###aa.................#a....",
74 "...###aa...............#######..",
75 "....#aa.................aa#aaaa.",
76 ".....a....................#a....",
77 "..........................#a....",
78 "...........................a....",
79 "................................",
80 "................................",
81 "................................",
82 "................................"};
85 //=================================================================================
86 // Plot2d_ViewFrame implementation
87 //=================================================================================
92 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
93 : QAD_ViewFrame( parent, title ),
94 myOperation( NoOpId ),
96 myShowLegend( true ), myLegendPos( 1 ),
97 myMarkerSize( DEFAULT_MARKER_SIZE ),
98 myTitle( "" ), myXTitle( "" ), myYTitle( "" ),
99 myBackground( white ),
100 myTitleEnabled( true ), myXTitleEnabled( true ), myYTitleEnabled( true ),
101 myXGridMajorEnabled( true ), myYGridMajorEnabled( true ),
102 myXGridMinorEnabled( false ), myYGridMinorEnabled( false ),
103 myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ),
104 myXMode( 0 ), myYMode( 0 )
107 myCurves.setAutoDelete( true );
109 myPlot = new Plot2d_Plot2d( this );
110 setCentralWidget( myPlot );
114 connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
115 this, SLOT( plotMouseMoved( const QMouseEvent& ) ) );
116 connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
117 this, SLOT( plotMousePressed( const QMouseEvent& ) ) );
118 connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
119 this, SLOT( plotMouseReleased( const QMouseEvent& ) ) );
120 connect( myPlot, SIGNAL( legendClicked( long ) ),
121 this, SLOT( onLegendClicked( long ) ) );
123 /* Initial Setup - get from the preferences */
126 myPlot->setMargin( 5 );
127 setCurveType( myCurveType, false );
128 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
129 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor, false );
130 setMainTitle( myTitleEnabled, myTitle, false );
131 setXTitle( myXTitleEnabled, myXTitle, false );
132 setYTitle( myYTitleEnabled, myYTitle, false );
133 setHorScaleMode( myXMode, false );
134 setVerScaleMode( myYMode, false );
135 setBackgroundColor( myBackground );
136 setLegendPos( myLegendPos );
137 showLegend( myShowLegend, false );
141 resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
147 Plot2d_ViewFrame::~Plot2d_ViewFrame()
150 qApp->removeEventFilter( this );
153 Creates popup menu actions
155 void Plot2d_ViewFrame::createActions()
157 QAD_ResourceMgr* rmgr = QAD_Desktop::getResourceManager();
158 /* Linear/logarithmic mode */
160 QActionPGroup* modeHorGrp = new QActionPGroup( this );
161 modeHorGrp->setExclusive( TRUE );
162 QActionP* linearXAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LINEAR_HOR"),
163 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LINEAR_HOR") ) ,
164 tr( "MEN_PLOT2D_MODE_LINEAR_HOR" ), 0, modeHorGrp );
165 linearXAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LINEAR_HOR" ) );
166 linearXAction->setToggleAction( true );
167 myActions.insert( ModeXLinearId, linearXAction );
168 QActionP* logXAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LOGARITHMIC_HOR"),
169 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LOGARITHMIC_HOR") ) ,
170 tr( "MEN_PLOT2D_MODE_LOGARITHMIC_HOR" ), 0, modeHorGrp );
171 logXAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LOGARITHMIC_HOR" ) );
172 logXAction->setToggleAction( true );
173 myActions.insert( ModeXLogarithmicId, logXAction );
174 connect( modeHorGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onHorMode() ) );
177 QActionPGroup* modeVerGrp = new QActionPGroup( this );
178 modeVerGrp->setExclusive( TRUE );
179 QActionP* linearYAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LINEAR_VER"),
180 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LINEAR_VER") ) ,
181 tr( "MEN_PLOT2D_MODE_LINEAR_VER" ), 0, modeVerGrp );
182 linearYAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LINEAR_VER" ) );
183 linearYAction->setToggleAction( true );
184 myActions.insert( ModeYLinearId, linearYAction );
185 QActionP* logYAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LOGARITHMIC_VER"),
186 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LOGARITHMIC_VER") ) ,
187 tr( "MEN_PLOT2D_MODE_LOGARITHMIC_VER" ), 0, modeVerGrp );
188 logYAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LOGARITHMIC_VER" ) );
189 logYAction->setToggleAction( true );
190 myActions.insert( ModeYLogarithmicId, logYAction );
191 connect( modeVerGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onVerMode() ) );
194 QActionP* legendAction = new QActionP ( tr( "TOT_PLOT2D_SHOW_LEGEND"),
195 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_SHOW_LEGEND") ) ,
196 tr( "MEN_PLOT2D_SHOW_LEGEND" ), 0, this );
197 legendAction->setStatusTip ( tr( "PRP_PLOT2D_SHOW_LEGEND" ) );
198 legendAction->setToggleAction( true );
199 myActions.insert( LegendId, legendAction );
200 connect( legendAction, SIGNAL( activated() ), this, SLOT( onLegend() ) );
203 QActionPGroup* curveGrp = new QActionPGroup( this );
204 curveGrp->setExclusive( TRUE );
205 QActionP* pointsAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_POINTS"),
206 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_POINTS") ) ,
207 tr( "MEN_PLOT2D_CURVES_POINTS" ), 0, curveGrp );
208 pointsAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_POINTS" ) );
209 pointsAction->setToggleAction( true );
210 myActions.insert( CurvePointsId, pointsAction );
211 QActionP* linesAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_LINES"),
212 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_LINES") ) ,
213 tr( "MEN_PLOT2D_CURVES_LINES" ), 0, curveGrp );
214 linesAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_LINES" ) );
215 linesAction->setToggleAction( true );
216 myActions.insert( CurveLinesId, linesAction );
217 QActionP* splinesAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_SPLINES"),
218 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_SPLINES") ) ,
219 tr( "MEN_PLOT2D_CURVES_SPLINES" ), 0, curveGrp );
220 splinesAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_SPLINES" ) );
221 splinesAction->setToggleAction( true );
222 myActions.insert( CurveSplinesId, splinesAction );
223 connect( curveGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onCurves() ) );
226 QActionP* settingsAction = new QActionP ( tr( "TOT_PLOT2D_SETTINGS"),
227 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_SETTINGS") ) ,
228 tr( "MEN_PLOT2D_SETTINGS" ), 0, this );
229 settingsAction->setStatusTip ( tr( "PRP_PLOT2D_SETTINGS" ) );
230 myActions.insert( SettingsId, settingsAction );
231 connect( settingsAction, SIGNAL( activated() ), this, SLOT( onSettings() ) );
234 QActionP* fitDataAction = new QActionP ( tr( "TOT_PLOT2D_FITDATA"),
235 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_FITDATA") ) ,
236 tr( "MEN_PLOT2D_FITDATA" ), 0, this );
237 fitDataAction->setStatusTip ( tr( "PRP_PLOT2D_FITDATA" ) );
238 myActions.insert( FitDataId, fitDataAction );
239 connect( fitDataAction, SIGNAL( activated() ), this, SLOT( onFitData() ) );
242 QActionP* changeBGAction = new QActionP ( tr( "TOT_PLOT2D_CHANGE_BACKGROUND"),
243 tr( "MEN_PLOT2D_CHANGE_BACKGROUND" ), 0, this );
244 fitDataAction->setStatusTip ( tr( "PRP_PLOT2D_CHANGE_BACKGROUND" ) );
245 myActions.insert( ChangeBackgroundId, changeBGAction );
246 connect( changeBGAction, SIGNAL( activated() ), this, SLOT( onChangeBackground() ) );
249 Gets window's central widget
251 QWidget* Plot2d_ViewFrame::getViewWidget()
253 return (QWidget*)myPlot;
255 /* Popup management : sets Popup server */
256 void Plot2d_ViewFrame::setPopupServer( QAD_Application* App )
258 // QAD_PopupClientServer::setPopupServer( (QAD_PopupServer*)App );
263 void Plot2d_ViewFrame::onCreatePopup()
268 QPopupMenu* scalingPopup = new QPopupMenu( myPopup );
269 myActions[ ModeXLinearId ]->addTo( scalingPopup );
270 myActions[ ModeXLogarithmicId ]->addTo( scalingPopup );
271 scalingPopup->insertSeparator();
272 myActions[ ModeYLinearId ]->addTo( scalingPopup );
273 myActions[ ModeYLogarithmicId ]->addTo( scalingPopup );
274 myActions[ FitDataId ]->addTo( myPopup );
275 myPopup->insertItem( tr( "SCALING_POPUP" ), scalingPopup );
277 QPopupMenu* curTypePopup = new QPopupMenu( myPopup );
278 myActions[ CurvePointsId ]->addTo( curTypePopup );
279 myActions[ CurveLinesId ]->addTo( curTypePopup );
280 myActions[ CurveSplinesId ]->addTo( curTypePopup );
281 myPopup->insertItem( tr( "CURVE_TYPE_POPUP" ), curTypePopup );
283 myPopup->insertSeparator();
284 myActions[ LegendId ]->addTo( myPopup );
286 myPopup->insertSeparator();
287 myActions[ SettingsId ]->addTo( myPopup );
289 myPopup->insertSeparator();
290 myActions[ ChangeBackgroundId ]->addTo( myPopup );
294 Renames curve if it is found
296 void Plot2d_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
298 Plot2d_Curve* curve = getCurveByIO( IObject );
300 curve->setVerTitle( newName );
301 int key = hasCurve( curve );
303 myPlot->setCurveTitle( key, newName );
304 // int legendIndex = myPlot->getLegend()->findFirstKey( key );
305 // if ( legendIndex != myPlot->getLegend()->itemCnt() )
306 // myPlot->getLegend()->setText( legendIndex, aSymbol );
312 Returns true if interactive object is presented in the viewer
314 bool Plot2d_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject )
316 if( getCurveByIO( IObject ) != NULL )
319 if(!IObject.IsNull()){
320 QIntDictIterator<Plot2d_Curve> it(myCurves);
321 for(; it.current();++it){
322 if(it.current()->hasIO() && it.current()->getTableIO()->isSame(IObject))
329 Returns true if interactive object is presented in the viewer and displayed
331 bool Plot2d_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject )
333 Plot2d_Curve* curve = getCurveByIO( IObject );
335 int key = hasCurve( curve );
337 return myPlot->curve( key )->enabled();
342 Return interactive obeject if is presented in the viewer
344 Handle(SALOME_InteractiveObject) Plot2d_ViewFrame::FindIObject( const char* Entry )
346 Handle(SALOME_InteractiveObject) o;
347 QIntDictIterator<Plot2d_Curve> it( myCurves );
348 for ( ; it.current(); ++it ) {
349 if ( it.current()->hasIO() && !strcmp( it.current()->getIO()->getEntry(), Entry ) ) {
350 o = it.current()->getIO();
357 Actually this method just re-displays curves which refers to the <IObject>
359 void Plot2d_ViewFrame::Display( const Handle(SALOME_InteractiveObject)& IObject, bool update )
361 Plot2d_Curve* curve = getCurveByIO( IObject );
363 updateCurve( curve, update );
366 Actually this method just erases all curves which don't refer to <IOBject>
367 and re-displays curve which is of <IObject>
369 void Plot2d_ViewFrame::DisplayOnly( const Handle(SALOME_InteractiveObject)& IObject )
371 Plot2d_Curve* curve = getCurveByIO( IObject );
372 QList<Plot2d_Curve> clist;
374 for ( int i = 0; i < clist.count(); i++ ) {
375 if ( clist.at( i ) != curve )
378 updateCurve( curve, false );
383 Removes from the viewer the curves which refer to <IObject>
385 void Plot2d_ViewFrame::Erase( const Handle(SALOME_InteractiveObject)& IObject, bool update )
387 Plot2d_Curve* curve = getCurveByIO( IObject );
389 eraseCurve( curve, update );
392 Actually this method just re-displays all curves which are presented in the viewer
394 void Plot2d_ViewFrame::DisplayAll()
396 QList<Plot2d_Curve> clist;
398 for ( int i = 0; i < clist.count(); i++ ) {
399 updateCurve( clist.at( i ), false );
404 Removes all curves from the view
406 void Plot2d_ViewFrame::EraseAll()
413 Redraws viewframe contents
415 void Plot2d_ViewFrame::Repaint()
422 bool Plot2d_ViewFrame::eventFilter( QObject* o, QEvent* e )
424 if ( ( e->type() == QEvent::MouseButtonPress || e->type() == QEvent::KeyPress ) && o != myPlot->canvas() ) {
425 myOperation = NoOpId;
426 qApp->removeEventFilter( this );
428 return QMainWindow::eventFilter( o, e );
433 void Plot2d_ViewFrame::setTitle( const QString& title )
435 setMainTitle( myTitleEnabled, title, true );
438 Reads Plot2d view settings from the preferences
440 void Plot2d_ViewFrame::readPreferences()
442 if ( QAD_CONFIG->hasSetting( "Plot2d:CurveType" ) ) { // curve type
443 myCurveType = QAD_CONFIG->getSetting( "Plot2d:CurveType" ).toInt();
444 if ( myCurveType < 0 || myCurveType > 2 ) myCurveType = 1;
446 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowLegend" ) ) {
447 myShowLegend = QAD_CONFIG->getSetting( "Plot2d:ShowLegend" ) == QString( "true" ); // show legend
449 if ( QAD_CONFIG->hasSetting( "Plot2d:LegendPos" ) ) { // legend position
450 myLegendPos = QAD_CONFIG->getSetting( "Plot2d:LegendPos" ).toInt();
451 if ( myLegendPos < 0 || myLegendPos > 3 ) myLegendPos = 1;
453 if ( QAD_CONFIG->hasSetting( "Plot2d:MarkerSize" ) ) { // marker size
454 myMarkerSize = QAD_CONFIG->getSetting( "Plot2d:MarkerSize" ).toInt();
456 if ( QAD_CONFIG->hasSetting( "Plot2d:Background" ) ) { // background color
457 QString bgString = QAD_CONFIG->getSetting( "Plot2d:Background" );
458 QStringList bgData = QStringList::split( ":", bgString, true );
459 int bgRed = 0, bgGreen = 0, bgBlue = 0;
460 if ( bgData.count() > 0 ) bgRed = bgData[ 0 ].toInt();
461 if ( bgData.count() > 1 ) bgGreen = bgData[ 1 ].toInt();
462 if ( bgData.count() > 2 ) bgBlue = bgData[ 2 ].toInt();
463 myBackground = QColor( bgRed, bgGreen, bgBlue );
465 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowTitle" ) ) { // main title
466 myTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowTitle" ) == QString( "true" );
468 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowHorTitle" ) ) { // hor.axis title
469 myXTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowHorTitle" ) == QString( "true" );
471 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowVerTitle" ) ) { // ver.axisn title
472 myYTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowVerTitle" ) == QString( "true" );
474 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableHorMajorGrid" ) ) { // grid
475 myXGridMajorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableHorMajorGrid" ) == QString( "true" );
477 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableVerMajorGrid" ) ) {
478 myYGridMajorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableVerMajorGrid" ) == QString( "true" );
480 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableHorMinorGrid" ) ) {
481 myXGridMinorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableHorMinorGrid" ) == QString( "true" );
483 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableVerMinorGrid" ) ) {
484 myYGridMinorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableVerMinorGrid" ) == QString( "true" );
486 if ( QAD_CONFIG->hasSetting( "Plot2d:HorMajorGridMax" ) ) {
487 myXGridMaxMajor = QAD_CONFIG->getSetting( "Plot2d:HorMajorGridMax" ).toInt();
489 if ( QAD_CONFIG->hasSetting( "Plot2d:VerMajorGridMax" ) ) {
490 myYGridMaxMajor = QAD_CONFIG->getSetting( "Plot2d:VerMajorGridMax" ).toInt();
492 if ( QAD_CONFIG->hasSetting( "Plot2d:HorMinorGridMax" ) ) {
493 myXGridMaxMinor = QAD_CONFIG->getSetting( "Plot2d:HorMinorGridMax" ).toInt();
495 if ( QAD_CONFIG->hasSetting( "Plot2d:VerMinorGridMax" ) ) {
496 myYGridMaxMinor = QAD_CONFIG->getSetting( "Plot2d:VerMinorGridMax" ).toInt();
498 if ( QAD_CONFIG->hasSetting( "Plot2d:HorScaleMode" ) ) { // scale mode
499 myXMode = QAD_CONFIG->getSetting( "Plot2d:HorScaleMode" ).toInt();
500 if ( myXMode < 0 || myXMode > 1 ) myXMode = 0;
502 if ( QAD_CONFIG->hasSetting( "Plot2d:VerScaleMode" ) ) {
503 myYMode = QAD_CONFIG->getSetting( "Plot2d:VerScaleMode" ).toInt();
504 if ( myYMode < 0 || myYMode > 1 ) myYMode = 0;
508 Writes Plot2d view settings to the preferences
510 void Plot2d_ViewFrame::writePreferences()
512 QAD_CONFIG->addSetting( "Plot2d:CurveType", myCurveType ); // curve type
513 QAD_CONFIG->addSetting( "Plot2d:ShowLegend", myShowLegend ? "true" : "false" ); // show legend
514 QAD_CONFIG->addSetting( "Plot2d:LegendPos", myLegendPos ); // legend position
515 QAD_CONFIG->addSetting( "Plot2d:MarkerSize", myMarkerSize ); // marker size
517 bgData.append( QString::number( myBackground.red() ) );
518 bgData.append( QString::number( myBackground.green() ) );
519 bgData.append( QString::number( myBackground.blue() ) );
520 QAD_CONFIG->addSetting( "Plot2d:Background", bgData.join( ":" ) ); // background color
521 QAD_CONFIG->addSetting( "Plot2d:ShowTitle", myTitleEnabled ? "true" : "false" ); // titles
522 QAD_CONFIG->addSetting( "Plot2d:ShowHorTitle", myXTitleEnabled ? "true" : "false" );
523 QAD_CONFIG->addSetting( "Plot2d:ShowVerTitle", myYTitleEnabled ? "true" : "false" );
524 QAD_CONFIG->addSetting( "Plot2d:EnableHorMajorGrid", myXGridMajorEnabled ? "true" : "false" ); // grid
525 QAD_CONFIG->addSetting( "Plot2d:EnableVerMajorGrid", myYGridMajorEnabled ? "true" : "false" );
526 QAD_CONFIG->addSetting( "Plot2d:EnableHorMinorGrid", myXGridMinorEnabled ? "true" : "false" );
527 QAD_CONFIG->addSetting( "Plot2d:EnableVerMinorGrid", myYGridMinorEnabled ? "true" : "false" );
528 QAD_CONFIG->addSetting( "Plot2d:HorMajorGridMax", myXGridMaxMajor );
529 QAD_CONFIG->addSetting( "Plot2d:VerMajorGridMax", myYGridMaxMajor );
530 QAD_CONFIG->addSetting( "Plot2d:HorMinorGridMax", myXGridMaxMinor );
531 QAD_CONFIG->addSetting( "Plot2d:VerMinorGridMax", myYGridMaxMinor );
532 QAD_CONFIG->addSetting( "Plot2d:HorScaleMode", myXMode ); // scale mode
533 QAD_CONFIG->addSetting( "Plot2d:VerScaleMode", myYMode );
536 Prints mouse cursor coordinates into string
538 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt )
540 bool xFound = false, yFound = false;
541 double xCoord, yCoord;
542 const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
543 for ( int i = 0; i < aXscale->majCnt(); i++ ) {
544 double majXmark = aXscale->majMark( i );
545 int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
546 if ( xmark-2 == pnt.x() ) {
549 MESSAGE("Plot2d_ViewFrame::getInfo : close maj X mark("<<i<<") = "<<majXmark<<" "<<xmark<<" "<<pnt.x());
554 for ( int i = 0; i < aXscale->minCnt(); i++ ) {
555 double minXmark = aXscale->minMark( i );
556 int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
557 if ( xmark-2 == pnt.x() ) {
560 MESSAGE("Plot2d_ViewFrame::getInfo : close min X mark("<<i<<") = "<<minXmark<<" "<<xmark<<" "<<pnt.x());
565 const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
566 for ( int i = 0; i < aYscale->majCnt(); i++ ) {
567 double majYmark = aYscale->majMark( i );
568 int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
569 if ( ymark-2 == pnt.y() ) {
576 for ( int i = 0; i < aYscale->minCnt(); i++ ) {
577 double minYmark = aYscale->minMark( i );
578 int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
579 if ( ymark-2 == pnt.y() ) {
586 QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
589 QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
592 QString info = tr("INF_COORDINATES").arg( strX ).arg( strY );
596 Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
598 static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
600 QwtSymbol::Style ms = QwtSymbol::None;
602 case Plot2d_Curve::Circle:
603 ms = QwtSymbol::Ellipse; break;
604 case Plot2d_Curve::Rectangle:
605 ms = QwtSymbol::Rect; break;
606 case Plot2d_Curve::Diamond:
607 ms = QwtSymbol::Diamond; break;
608 case Plot2d_Curve::DTriangle:
609 ms = QwtSymbol::DTriangle; break;
610 case Plot2d_Curve::UTriangle:
611 ms = QwtSymbol::UTriangle; break;
612 case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
613 ms = QwtSymbol::RTriangle; break;
614 case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
615 ms = QwtSymbol::LTriangle; break;
616 case Plot2d_Curve::Cross:
617 ms = QwtSymbol::Cross; break;
618 case Plot2d_Curve::XCross:
619 ms = QwtSymbol::XCross; break;
620 case Plot2d_Curve::None:
622 ms = QwtSymbol::None; break;
627 Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
629 static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
631 Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;
633 case QwtSymbol::Ellipse:
634 ms = Plot2d_Curve::Circle; break;
635 case QwtSymbol::Rect:
636 ms = Plot2d_Curve::Rectangle; break;
637 case QwtSymbol::Diamond:
638 ms = Plot2d_Curve::Diamond; break;
639 case QwtSymbol::DTriangle:
640 ms = Plot2d_Curve::DTriangle; break;
641 case QwtSymbol::UTriangle:
642 ms = Plot2d_Curve::UTriangle; break;
643 case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
644 ms = Plot2d_Curve::LTriangle; break;
645 case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
646 ms = Plot2d_Curve::RTriangle; break;
647 case QwtSymbol::Cross:
648 ms = Plot2d_Curve::Cross; break;
649 case QwtSymbol::XCross:
650 ms = Plot2d_Curve::XCross; break;
651 case QwtSymbol::None:
653 ms = Plot2d_Curve::None; break;
658 Converts Plot2d_Curve's line style to Qwt line style [ static ]
660 static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
662 Qt::PenStyle ps = Qt::NoPen;
664 case Plot2d_Curve::Solid:
665 ps = Qt::SolidLine; break;
666 case Plot2d_Curve::Dash:
667 ps = Qt::DashLine; break;
668 case Plot2d_Curve::Dot:
669 ps = Qt::DotLine; break;
670 case Plot2d_Curve::DashDot:
671 ps = Qt::DashDotLine; break;
672 case Plot2d_Curve::DashDotDot:
673 ps = Qt::DashDotDotLine; break;
674 case Plot2d_Curve::NoPen:
676 ps = Qt::NoPen; break;
681 Converts Qwt line style to Plot2d_Curve's line style [ static ]
683 static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
685 Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
688 ps = Plot2d_Curve::Solid; break;
690 ps = Plot2d_Curve::Dash; break;
692 ps = Plot2d_Curve::Dot; break;
693 case Qt::DashDotLine:
694 ps = Plot2d_Curve::DashDot; break;
695 case Qt::DashDotDotLine:
696 ps = Plot2d_Curve::DashDotDot; break;
699 ps = Plot2d_Curve::NoPen; break;
706 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
710 if ( hasCurve( curve ) ) {
711 updateCurve( curve, update );
714 long curveKey = myPlot->insertCurve( curve->getVerTitle() );
715 myCurves.insert( curveKey, curve );
716 if ( curve->isAutoAssign() ) {
717 QwtSymbol::Style typeMarker;
719 Qt::PenStyle typeLine;
720 myPlot->getNextMarker( typeMarker, color, typeLine );
721 myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
722 myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker,
725 QSize( myMarkerSize, myMarkerSize ) ) );
726 curve->setColor( color );
727 curve->setLine( qwt2plotLine( typeLine ) );
728 curve->setMarker( qwt2plotMarker( typeMarker ) );
731 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
732 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
733 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
734 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
735 QBrush( curve->getColor() ),
736 QPen( curve->getColor() ),
737 QSize( myMarkerSize, myMarkerSize ) ) );
739 if ( myCurveType == 0 )
740 myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
741 else if ( myCurveType == 1 )
742 myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
743 else if ( myCurveType == 2 )
744 myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
745 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
752 Adds curves into view
754 void Plot2d_ViewFrame::displayCurves( Plot2d_CurveContainer& curves, bool update )
756 myPlot->setUpdatesEnabled( false );
757 for ( int i = 0; i < curves.count(); i++ ) {
758 displayCurve( curves.curve( i ), false );
761 myPlot->setUpdatesEnabled( true );
768 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
772 int curveKey = hasCurve( curve );
774 myPlot->removeCurve( curveKey );
775 myCurves.remove( curveKey );
784 void Plot2d_ViewFrame::eraseCurves( Plot2d_CurveContainer& curves, bool update )
786 for ( int i = 0; i < curves.count(); i++ ) {
787 eraseCurve( curves.curve( i ), false );
794 Updates curves attributes
796 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
800 int curveKey = hasCurve( curve );
802 if ( !curve->isAutoAssign() ) {
803 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
804 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
805 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
806 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
807 QBrush( curve->getColor() ),
808 QPen( curve->getColor() ),
809 QSize( myMarkerSize, myMarkerSize ) ) );
811 myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
812 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
813 myPlot->curve( curveKey )->setEnabled( true );
820 Returns curve key if is is displayed in the viewer and 0 otherwise
822 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
824 QIntDictIterator<Plot2d_Curve> it( myCurves );
825 for ( ; it.current(); ++it ) {
826 if ( it.current() == curve )
827 return it.currentKey();
831 Plot2d_Curve* Plot2d_ViewFrame::getCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject )
833 if ( !theIObject.IsNull() ) {
834 QIntDictIterator<Plot2d_Curve> it( myCurves );
835 for ( ; it.current(); ++it ) {
836 if ( it.current()->hasIO() && it.current()->getIO()->isSame( theIObject ) )
843 Gets lsit of displayed curves
845 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
848 clist.setAutoDelete( false );
849 QIntDictIterator<Plot2d_Curve> it( myCurves );
850 for ( ; it.current(); ++it ) {
851 clist.append( it.current() );
853 return clist.count();
857 Updates titles according to curves
859 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
860 void Plot2d_ViewFrame::updateTitles()
862 QAD_Study* activeStudy = QAD_Application::getDesktop()->getActiveStudy();
863 QIntDictIterator<Plot2d_Curve> it( myCurves );
864 QStringList aXTitles;
865 QStringList aYTitles;
870 while ( it.current() ) {
871 // collect titles and units from all curves...
872 QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
873 QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
874 QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
875 QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
877 aYTitles.append( yTitle );
878 if ( aXTitles.find( xTitle ) == aXTitles.end() )
879 aXTitles.append( xTitle );
880 if ( aXUnits.find( xUnits ) == aXUnits.end() )
881 aXUnits.append( xUnits );
882 if ( aYUnits.find( yUnits ) == aYUnits.end() )
883 aYUnits.append( yUnits );
885 if ( activeStudy && it.current()->hasTableIO() ) {
886 SALOMEDS::SObject_var SO = activeStudy->getStudyDocument()->FindObjectID( it.current()->getTableIO()->getEntry() );
887 if ( !SO->_is_nil() ) {
888 SALOMEDS::GenericAttribute_var anAttr;
889 if ( SO->FindAttribute( anAttr, "AttributeName" ) ) {
890 SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow( anAttr );
891 QString aName = aNameAttr->Value();
892 if ( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
893 aTables.append( aName );
901 // ... and update plot 2d view
902 QString xUnits, yUnits;
903 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
904 xUnits = BRACKETIZE( aXUnits[0] );
905 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
906 yUnits = BRACKETIZE( aYUnits[0] );
907 QString xTitle, yTitle;
908 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
909 xTitle = aXTitles[0];
910 if ( aYTitles.count() == 1 )
911 yTitle = aYTitles[0];
913 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
915 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
918 setXTitle( myXTitleEnabled, xTitle + xUnits );
919 setYTitle( myYTitleEnabled, yTitle + yUnits );
920 setTitle( aTables.join("; ") );
923 Fits the view to see all data
925 void Plot2d_ViewFrame::fitAll()
927 myPlot->setAxisAutoScale( QwtPlot::yLeft );
928 myPlot->setAxisAutoScale( QwtPlot::xBottom );
932 Fits the view to rectangle area (pixels)
934 void Plot2d_ViewFrame::fitArea( const QRect& area )
936 QRect rect = area.normalize();
937 if ( rect.width() < MIN_RECT_SIZE ) {
938 rect.setWidth( MIN_RECT_SIZE );
939 rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
941 if ( rect.height() < MIN_RECT_SIZE ) {
942 rect.setHeight( MIN_RECT_SIZE );
943 rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
945 myPlot->setAxisScale( QwtPlot::yLeft,
946 myPlot->invTransform( QwtPlot::yLeft, rect.top() ),
947 myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
948 myPlot->setAxisScale( QwtPlot::xBottom,
949 myPlot->invTransform( QwtPlot::xBottom, rect.left() ),
950 myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
954 Tests if it is necessary to start operation on mouse action
956 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
958 int btn = me.button() | me.state();
959 int zoomBtn = ControlButton | LeftButton;
960 int panBtn = ControlButton | MidButton;
961 int fitBtn = ControlButton | RightButton;
963 if ( btn == zoomBtn )
972 Mode toolbar buttons slot - horizontal axis (<Linear>/<Logarithmic>)
974 void Plot2d_ViewFrame::onHorMode()
976 if ( myActions[ ModeXLinearId ]->isOn() )
977 setHorScaleMode( 0 );
978 else if ( myActions[ ModeXLogarithmicId ]->isOn() )
979 setHorScaleMode( 1 );
982 Mode toolbar buttons slot - vertical axis (<Linear>/<Logarithmic>)
984 void Plot2d_ViewFrame::onVerMode()
986 if ( myActions[ ModeYLinearId ]->isOn() )
987 setVerScaleMode( 0 );
988 else if ( myActions[ ModeYLogarithmicId ]->isOn() )
989 setVerScaleMode( 1 );
992 "Show/hide legend" toolbar action slot
994 void Plot2d_ViewFrame::onLegend()
996 showLegend( myActions[ LegendId ]->isOn() );
999 "Curve type" toolbar action slot
1001 void Plot2d_ViewFrame::onCurves()
1003 if ( myActions[ CurvePointsId ]->isOn() )
1005 else if ( myActions[ CurveLinesId ]->isOn() )
1007 else if ( myActions[ CurveSplinesId ]->isOn() )
1011 "Settings" toolbar action slot
1013 void Plot2d_ViewFrame::onSettings()
1015 #ifdef TEST_AUTOASSIGN
1016 typedef QMap<int,int> IList;
1017 typedef QMap<QString,int> SList;
1020 cols[ "red-min" ] = 1000;
1021 cols[ "red-max" ] = -1;
1022 cols[ "green-min" ] = 1000;
1023 cols[ "green-max" ] = -1;
1024 cols[ "blue-min" ] = 1000;
1025 cols[ "blue-max" ] = -1;
1026 for ( unsigned i = 0; i < 10000; i++ ) {
1027 QwtSymbol::Style typeMarker;
1029 Qt::PenStyle typeLine;
1030 myPlot->getNextMarker( typeMarker, color, typeLine );
1031 if ( mars.contains(typeMarker) )
1032 mars[ typeMarker ] = mars[ typeMarker ]+1;
1034 mars[ typeMarker ] = 0;
1035 if ( lins.contains(typeLine) )
1036 lins[ typeLine ] = lins[ typeLine ]+1;
1038 lins[ typeLine ] = 0;
1039 if ( cols[ "red-max" ] < color.red() )
1040 cols[ "red-max" ] = color.red();
1041 if ( cols[ "red-min" ] > color.red() )
1042 cols[ "red-min" ] = color.red();
1043 if ( cols[ "green-max" ] < color.green() )
1044 cols[ "green-max" ] = color.green();
1045 if ( cols[ "green-min" ] > color.green() )
1046 cols[ "green-min" ] = color.green();
1047 if ( cols[ "blue-max" ] < color.blue() )
1048 cols[ "blue-max" ] = color.blue();
1049 if ( cols[ "blue-min" ] > color.blue() )
1050 cols[ "blue-min" ] = color.blue();
1052 for (IList::Iterator it = mars.begin(); it != mars.end(); ++it)
1053 MESSAGE("markers( " << it.key() << ") = " << it.data() );
1054 for (IList::Iterator it = lins.begin(); it != lins.end(); ++it)
1055 MESSAGE("lines( " << it.key() << ") = " << it.data() );
1056 for (SList::Iterator it = cols.begin(); it != cols.end(); ++it)
1057 MESSAGE("colors( " << it.key() << ") = " << it.data() );
1060 Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true );
1061 dlg->setMainTitle( myTitleEnabled, myTitle );
1062 dlg->setXTitle( myXTitleEnabled, myXTitle );
1063 dlg->setYTitle( myYTitleEnabled, myYTitle );
1064 dlg->setCurveType( myCurveType );
1065 dlg->setLegend( myShowLegend, myLegendPos );
1066 dlg->setMarkerSize( myMarkerSize );
1067 dlg->setBackgroundColor( myBackground );
1068 dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
1069 myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ) );
1070 dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
1071 myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ) );
1072 dlg->setScaleMode( myXMode, myYMode );
1074 if ( dlg->exec() == QDialog::Accepted ) {
1075 // horizontal axis title
1076 setXTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), false );
1077 // vertical axis title
1078 setYTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), false );
1080 setMainTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), true );
1082 if ( myCurveType != dlg->getCurveType() ) {
1083 setCurveType( dlg->getCurveType(), false );
1086 if ( myShowLegend != dlg->isLegendEnabled() ) {
1087 showLegend( dlg->isLegendEnabled(), false );
1089 if ( myLegendPos != dlg->getLegendPos() ) {
1090 setLegendPos( dlg->getLegendPos() );
1093 if ( myMarkerSize != dlg->getMarkerSize() ) {
1094 setMarkerSize( dlg->getMarkerSize(), false );
1097 if ( myBackground != dlg->getBackgroundColor() ) {
1098 setBackgroundColor( dlg->getBackgroundColor() );
1101 bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled;
1102 int aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor;
1103 dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor );
1104 dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor );
1105 setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1106 setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor, false );
1108 if ( myXMode != dlg->getXScaleMode() ) {
1109 setHorScaleMode( dlg->getXScaleMode() );
1111 if ( myYMode != dlg->getYScaleMode() ) {
1112 setVerScaleMode( dlg->getYScaleMode() );
1116 // update preferences
1117 if ( dlg->isSetAsDefault() )
1123 "Fit Data" command slot
1125 void Plot2d_ViewFrame::onFitData()
1127 Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this );
1128 int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
1129 int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
1130 int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
1131 int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
1132 double xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
1133 double xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
1134 double yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
1135 double yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
1137 dlg->setRange( xMin, xMax, yMin, yMax );
1138 if ( dlg->exec() == QDialog::Accepted ) {
1139 int mode = dlg->getRange( xMin, xMax, yMin, yMax );
1140 if ( mode == 0 || mode == 2 )
1141 myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
1142 if ( mode == 0 || mode == 1 )
1143 myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax );
1149 Change background color
1151 void Plot2d_ViewFrame::onChangeBackground()
1153 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
1154 if ( selColor.isValid() ) {
1155 setBackgroundColor( selColor );
1161 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1163 myCurveType = curveType;
1164 if ( curveType == 0 )
1165 myActions[ CurvePointsId ]->setOn( true );
1166 else if ( curveType == 1 )
1167 myActions[ CurveLinesId ]->setOn( true );
1168 else if ( curveType == 2 )
1169 myActions[ CurveSplinesId ]->setOn( true );
1171 QArray<long> keys = myPlot->curveKeys();
1172 for ( int i = 0; i < keys.count(); i++ ) {
1173 if ( myCurveType == 0 )
1174 myPlot->setCurveStyle( keys[i], QwtCurve::NoCurve );
1175 else if ( myCurveType == 1 )
1176 myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1177 else if ( myCurveType == 2 )
1178 myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1186 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1188 myShowLegend = show;
1189 myActions[ LegendId ]->setOn( myShowLegend );
1191 myPlot->setAutoLegend( myShowLegend );
1192 myPlot->enableLegend( myShowLegend );
1198 Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1200 void Plot2d_ViewFrame::setLegendPos( int pos )
1205 myPlot->setLegendPos( Qwt::Left );
1208 myPlot->setLegendPos( Qwt::Right );
1211 myPlot->setLegendPos( Qwt::Top );
1214 myPlot->setLegendPos( Qwt::Bottom );
1219 Sets new marker size
1221 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1223 if ( myMarkerSize != size ) {
1224 myMarkerSize = size;
1225 QArray<long> keys = myPlot->curveKeys();
1226 for ( int i = 0; i < keys.count(); i++ ) {
1227 QwtPlotCurve* crv = myPlot->curve( keys[i] );
1229 QwtSymbol aSymbol = crv->symbol();
1230 aSymbol.setSize( myMarkerSize, myMarkerSize );
1231 crv->setSymbol( aSymbol );
1232 int legendIndex = myPlot->getLegend()->findFirstKey( keys[i] );
1233 if ( legendIndex != myPlot->getLegend()->itemCnt() )
1234 myPlot->getLegend()->setSymbol( legendIndex, aSymbol );
1242 Sets background color
1244 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1246 myBackground = color;
1247 //myPlot->setCanvasBackground( myBackground );
1248 myPlot->canvas()->setPalette( myBackground );
1249 myPlot->setPalette( myBackground );
1250 QPalette aPal = myPlot->getLegend()->palette();
1251 for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1252 QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1253 aPal.setColor( cg, QColorGroup::Base, myBackground );
1254 aPal.setColor( cg, QColorGroup::Background, myBackground );
1256 myPlot->getLegend()->setPalette( aPal );
1259 Gets background color
1261 QColor Plot2d_ViewFrame::backgroundColor() const
1263 return myBackground;
1266 Sets hor.axis grid parameters
1268 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
1269 bool xMinorEnabled, const int xMinorMax,
1272 myXGridMajorEnabled = xMajorEnabled;
1273 myXGridMinorEnabled = xMinorEnabled;
1274 myXGridMaxMajor = xMajorMax;
1275 myXGridMaxMinor = xMinorMax;
1276 myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1277 myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1278 myPlot->enableGridX( myXGridMajorEnabled );
1279 myPlot->enableGridXMin( myXGridMinorEnabled );
1284 Sets ver.axis grid parameters
1286 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
1287 bool yMinorEnabled, const int yMinorMax,
1290 myYGridMajorEnabled = yMajorEnabled;
1291 myYGridMinorEnabled = yMinorEnabled;
1292 myYGridMaxMajor = yMajorMax;
1293 myYGridMaxMinor = yMinorMax;
1294 myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1295 myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1296 myPlot->enableGridY( myYGridMajorEnabled );
1297 myPlot->enableGridYMin( myYGridMinorEnabled );
1304 void Plot2d_ViewFrame::setMainTitle( bool enabled, const QString& title, bool update )
1306 myTitleEnabled = enabled;
1308 myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1315 void Plot2d_ViewFrame::setXTitle( bool enabled, const QString& title, bool update )
1317 myXTitleEnabled = enabled;
1319 myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1326 void Plot2d_ViewFrame::setYTitle( bool enabled, const QString& title, bool update )
1328 myYTitleEnabled = enabled;
1330 myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1335 Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1337 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1340 if ( myXMode == 0 ) { // linear
1341 myActions[ ModeXLogarithmicId ]->setOn( false );
1342 myActions[ ModeXLinearId ]->setOn( true );
1343 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1345 else { // logarithmic
1346 myActions[ ModeXLinearId ]->setOn( false );
1347 myActions[ ModeXLogarithmicId ]->setOn( true );
1348 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
1351 // myPlot->replot();
1355 Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1357 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1360 if ( myYMode == 0 ) { // linear
1361 myActions[ ModeYLogarithmicId ]->setOn( false );
1362 myActions[ ModeYLinearId ]->setOn( true );
1363 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1365 else { // logarithmic
1366 myActions[ ModeYLinearId ]->setOn( false );
1367 myActions[ ModeYLogarithmicId ]->setOn( true );
1368 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
1371 // myPlot->replot();
1375 Slot, called when Legend item is clicked
1377 void Plot2d_ViewFrame::onLegendClicked( long key )
1379 Plot2d_Curve* curve = myCurves[ key ];
1380 if ( curve && curve->hasIO() ) {
1381 SALOME_Selection* Sel = SALOME_Selection::Selection( QAD_Application::getDesktop()->getActiveStudy()->getSelection() );
1382 Sel->ClearIObjects();
1383 Sel->AddIObject( curve->getIO(), true );
1388 Slot, called when user presses mouse button
1390 void Plot2d_ViewFrame::plotMousePressed( const QMouseEvent& me )
1392 if ( myOperation == NoOpId )
1393 myOperation = testOperation( me );
1394 if ( myOperation != NoOpId ) {
1396 if ( myOperation == ZoomId ) {
1397 myPlot->canvas()->setCursor( QCursor( QPixmap( imageZoomCursor ) ) );
1399 else if ( myOperation == PanId ) {
1400 myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
1402 else if ( myOperation == FitAreaId ) {
1403 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1404 myPlot->setOutlineStyle( Qwt::Rect );
1408 int btn = me.button() | me.state();
1409 if ( btn == RightButton ) {
1412 QAD_Tools::checkPopup( myPopup );
1413 if ( myPopup->count()>0 ) {
1414 myPopup->exec( QCursor::pos() );
1420 myPlot->setOutlineStyle( Qwt::Cross );
1421 QAD_Application::getDesktop()->putInfo( getInfo( me.pos() ) );
1426 Slot, called when user moves mouse
1428 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1430 int dx = me.pos().x() - myPnt.x();
1431 int dy = me.pos().y() - myPnt.y();
1433 if ( myOperation != NoOpId) {
1434 if ( myOperation == ZoomId ) {
1435 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1436 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1438 myPlot->setAxisScale( QwtPlot::yLeft,
1439 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1440 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1441 myPlot->setAxisScale( QwtPlot::xBottom,
1442 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1443 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1447 else if ( myOperation == PanId ) {
1448 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1449 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1451 myPlot->setAxisScale( QwtPlot::yLeft,
1452 myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ),
1453 myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1454 myPlot->setAxisScale( QwtPlot::xBottom,
1455 myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1456 myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) );
1462 QAD_Application::getDesktop()->putInfo( getInfo( me.pos() ) );
1466 Slot, called when user releases mouse
1468 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1470 if ( myOperation == FitAreaId ) {
1471 QRect rect( myPnt, me.pos() );
1474 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1475 myPlot->setOutlineStyle( Qwt::Triangle );
1476 QAD_Application::getDesktop()->putInfo( tr( "INF_READY" ) );
1477 myOperation = NoOpId;
1480 View operations : Pan view
1482 void Plot2d_ViewFrame::onViewPan()
1484 myOperation = PanId;
1485 qApp->installEventFilter( this );
1488 View operations : Zoom view
1490 void Plot2d_ViewFrame::onViewZoom()
1492 myOperation = ZoomId;
1493 qApp->installEventFilter( this );
1496 View operations : Fot All
1498 void Plot2d_ViewFrame::onViewFitAll()
1503 View operations : Fit Area
1505 void Plot2d_ViewFrame::onViewFitArea()
1507 myOperation = FitAreaId;
1508 qApp->installEventFilter( this );
1511 View operations : Global panning
1513 void Plot2d_ViewFrame::onViewGlobalPan()
1514 { MESSAGE( "Plot2d_ViewFrame::onViewGlobalPan : NOT SUPPORTED" ); }
1516 View operations : Rotate view
1518 void Plot2d_ViewFrame::onViewRotate()
1519 { MESSAGE( "Plot2d_ViewFrame::onViewRotate : NOT SUPPORTED" ); }
1521 View operations : Reset view
1523 void Plot2d_ViewFrame::onViewReset()
1524 { MESSAGE( "Plot2d_ViewFrame::onViewReset : NOT SUPPORTED" ); }
1526 View operations : View front
1528 void Plot2d_ViewFrame::onViewFront()
1529 { MESSAGE( "Plot2d_ViewFrame::onViewFront : NOT SUPPORTED" ); }
1531 View operations : View back
1533 void Plot2d_ViewFrame::onViewBack()
1534 { MESSAGE( "Plot2d_ViewFrame::onViewBack : NOT SUPPORTED" ); }
1536 View operations : View right
1538 void Plot2d_ViewFrame::onViewRight()
1539 { MESSAGE( "Plot2d_ViewFrame::onViewRight : NOT SUPPORTED" ); }
1541 View operations : View left
1543 void Plot2d_ViewFrame::onViewLeft()
1544 { MESSAGE( "Plot2d_ViewFrame::onViewLeft : NOT SUPPORTED" ); }
1546 View operations : View bottom
1548 void Plot2d_ViewFrame::onViewBottom()
1549 { MESSAGE( "Plot2d_ViewFrame::onViewBottom : NOT SUPPORTED" ); }
1551 View operations : View top
1553 void Plot2d_ViewFrame::onViewTop()
1554 { MESSAGE( "Plot2d_ViewFrame::onViewTop : NOT SUPPORTED" ); }
1556 View operations : Show/hide trihedron
1558 void Plot2d_ViewFrame::onViewTrihedron()
1559 { MESSAGE( "Plot2d_ViewFrame::onViewTrihedron : NOT SUPPORTED" ); }
1562 //=================================================================================
1563 // Plot2d_Plot2d implementation
1564 //=================================================================================
1569 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1573 enableOutline( true );
1574 setOutlineStyle( Qwt::Triangle );
1575 setOutlinePen( green );
1577 setAutoLegend( false );
1578 setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1579 enableLegend( false );
1581 enableGridX( false );
1582 enableGridXMin( false );
1583 enableGridY( false );
1584 enableGridYMin( false );
1585 // auto scaling by default
1586 setAxisAutoScale( QwtPlot::yLeft );
1587 setAxisAutoScale( QwtPlot::xBottom );
1590 Recalculates and redraws Plot 2d view
1592 void Plot2d_Plot2d::replot()
1594 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
1598 Checks if two colors are close to each other [ static ]
1599 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1601 const long COLOR_DISTANCE = 100;
1602 const int MAX_ATTEMPTS = 10;
1603 static bool closeColors( const QColor& color1, const QColor& color2 )
1605 long tol = abs( color2.red() - color1.red() ) +
1606 abs( color2.green() - color1.green() ) +
1607 abs( color2.blue() - color1.blue() );
1609 return ( tol <= COLOR_DISTANCE );
1612 Gets new unique marker for item if possible
1614 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine )
1619 int aRed = (int)( 256.0 * random() / RAND_MAX); // generate random color
1620 int aGreen = (int)( 256.0 * random() / RAND_MAX); // ...
1621 int aBlue = (int)( 256.0 * random() / RAND_MAX); // ...
1622 int aMarker = (int)( 9.0 * random() / RAND_MAX) + 1; // 9 markers types ( not including empty )
1623 int aLine = (int)( 5.0 * random() / RAND_MAX) + 1; // 5 line types ( not including empty )
1625 typeMarker = ( QwtSymbol::Style )aMarker;
1626 color = QColor( aRed, aGreen, aBlue );
1627 typeLine = ( Qt::PenStyle )aLine;
1630 if ( cnt == MAX_ATTEMPTS )
1633 bOk = !existMarker( typeMarker, color, typeLine );
1636 static int aMarker = -1;
1637 static int aColor = -1;
1638 static int aLine = -1;
1640 if ( myColors.isEmpty() ) {
1641 // creating colors list
1642 myColors.append( Qt::white );
1643 myColors.append( Qt::blue );
1644 myColors.append( Qt::gray );
1645 myColors.append( Qt::darkGreen );
1646 myColors.append( Qt::magenta );
1647 myColors.append( Qt::darkGray );
1648 myColors.append( Qt::red );
1649 myColors.append( Qt::darkBlue );
1650 myColors.append( Qt::darkYellow );
1651 myColors.append( Qt::cyan );
1652 myColors.append( Qt::darkRed );
1653 myColors.append( Qt::darkCyan );
1654 myColors.append( Qt::yellow );
1655 myColors.append( Qt::darkMagenta );
1656 myColors.append( Qt::green );
1657 myColors.append( Qt::black );
1660 int nbMarkers = 11; // QwtSymbol supports 11 marker types
1661 int nbLines = 6; // Qt supports 6 line types
1662 int nbColors = myColors.count(); // number of default colors supported
1664 aMarker = ( aMarker + 1 ) % nbMarkers;
1665 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1666 aColor = ( aColor + 1 ) % nbColors;
1667 aLine = ( aLine + 1 ) % nbLines;
1668 if ( aLine == Qt::NoPen ) aLine++;
1670 typeMarker = ( QwtSymbol::Style )aMarker;
1671 color = myColors[ aColor ];
1672 typeLine = ( Qt::PenStyle )aLine;
1673 if ( !existMarker( typeMarker, color, typeLine ) )
1677 for ( i = 0; i < nbMarkers; i++ ) {
1678 aMarker = ( aMarker + 1 ) % nbMarkers;
1679 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1680 for ( j = 0; j < nbColors; j++ ) {
1681 aColor = ( aColor + 1 ) % nbColors;
1682 for ( k = 0; k < nbLines; k++ ) {
1683 aLine = ( aLine + 1 ) % nbLines;
1684 if ( aLine == Qt::NoPen ) aLine++;
1685 if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1686 typeMarker = ( QwtSymbol::Style )aMarker;
1687 color = myColors[ aColor ];
1688 typeLine = ( Qt::PenStyle )aLine;
1697 Checks if marker belongs to any enitity
1699 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine )
1701 // getting all curves
1702 QArray<long> keys = curveKeys();
1705 if ( closeColors( color, backgroundColor() ) )
1707 for ( int i = 0; i < keys.count(); i++ ) {
1708 QwtPlotCurve* crv = curve( keys[i] );
1710 QwtSymbol::Style aStyle = crv->symbol().style();
1711 QColor aColor = crv->pen().color();
1712 Qt::PenStyle aLine = crv->pen().style();
1713 // if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1714 if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1721 //==========================================================
1723 * Plot2d_ViewFrame::Display
1724 * Display presentation
1726 //==========================================================
1727 void Plot2d_ViewFrame::Display( const SALOME_Prs2d* prs )
1729 // try do downcast object
1730 const Plot2d_Prs* aPlot2dPrs = dynamic_cast<const Plot2d_Prs*>( prs );
1731 if ( !aPlot2dPrs || aPlot2dPrs->IsNull() )
1734 // display all curves from presentation
1735 Plot2d_CurveContainer aCurves = aPlot2dPrs->GetObjects();
1736 displayCurves( aCurves );
1739 //==========================================================
1741 * Plot2d_ViewFrame::Erase
1742 * Erase presentation
1744 //==========================================================
1745 void Plot2d_ViewFrame::Erase( const SALOME_Prs2d* prs, const bool )
1747 // try do downcast object
1748 const Plot2d_Prs* aPlot2dPrs = dynamic_cast<const Plot2d_Prs*>( prs );
1749 if ( !aPlot2dPrs || aPlot2dPrs->IsNull() )
1752 // erase all curves from presentation
1753 Plot2d_CurveContainer aCurves = aPlot2dPrs->GetObjects();
1754 eraseCurves( aCurves );
1757 //==========================================================
1759 * Plot2d_ViewFrame::CreatePrs
1760 * Create presentation by entry
1762 //==========================================================
1763 SALOME_Prs* Plot2d_ViewFrame::CreatePrs( const char* entry )
1765 Plot2d_Prs* prs = new Plot2d_Prs();
1767 QIntDictIterator<Plot2d_Curve> it( myCurves );
1768 for ( ; it.current(); ++it ) {
1769 if ( it.current()->hasIO() && !strcmp( it.current()->getIO()->getEntry(), entry ) ) {
1770 prs->AddObject( it.current() );
1777 //==========================================================
1779 * Plot2d_ViewFrame::BeforeDisplay
1780 * Axiluary method called before displaying of objects
1782 //==========================================================
1783 void Plot2d_ViewFrame::BeforeDisplay( SALOME_Displayer* d )
1785 d->BeforeDisplay( this, SALOME_Plot2dViewType() );
1788 //==========================================================
1790 * Plot2d_ViewFrame::AfterDisplay
1791 * Axiluary method called after displaying of objects
1793 //==========================================================
1794 void Plot2d_ViewFrame::AfterDisplay( SALOME_Displayer* d )
1796 d->AfterDisplay( this, SALOME_Plot2dViewType() );