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)
40 #define DEFAULT_LINE_WIDTH 0 // (default) line width
41 #define DEFAULT_MARKER_SIZE 9 // default marker size
42 #define MIN_RECT_SIZE 11 // min sensibility area size
45 const char* imageZoomCursor[] = {
50 "................................",
51 "................................",
52 ".#######........................",
53 "..aaaaaaa.......................",
54 "................................",
55 ".............#####..............",
56 "...........##.aaaa##............",
57 "..........#.aa.....a#...........",
58 ".........#.a.........#..........",
59 ".........#a..........#a.........",
60 "........#.a...........#.........",
61 "........#a............#a........",
62 "........#a............#a........",
63 "........#a............#a........",
64 "........#a............#a........",
65 ".........#...........#.a........",
66 ".........#a..........#a.........",
67 ".........##.........#.a.........",
68 "........#####.....##.a..........",
69 ".......###aaa#####.aa...........",
70 "......###aa...aaaaa.......#.....",
71 ".....###aa................#a....",
72 "....###aa.................#a....",
73 "...###aa...............#######..",
74 "....#aa.................aa#aaaa.",
75 ".....a....................#a....",
76 "..........................#a....",
77 "...........................a....",
78 "................................",
79 "................................",
80 "................................",
81 "................................"};
84 //=================================================================================
85 // Plot2d_ViewFrame implementation
86 //=================================================================================
91 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
92 : QAD_ViewFrame( parent, title ),
93 myOperation( NoOpId ),
95 myShowLegend( true ), myLegendPos( 1 ),
96 myMarkerSize( DEFAULT_MARKER_SIZE ),
97 myTitle( "" ), myXTitle( "" ), myYTitle( "" ),
98 myBackground( white ),
99 myTitleEnabled( true ), myXTitleEnabled( true ), myYTitleEnabled( true ),
100 myXGridMajorEnabled( true ), myYGridMajorEnabled( true ),
101 myXGridMinorEnabled( false ), myYGridMinorEnabled( false ),
102 myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ),
103 myXMode( 0 ), myYMode( 0 )
106 myCurves.setAutoDelete( true );
108 myPlot = new Plot2d_Plot2d( this );
109 setCentralWidget( myPlot );
113 connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
114 this, SLOT( plotMouseMoved( const QMouseEvent& ) ) );
115 connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
116 this, SLOT( plotMousePressed( const QMouseEvent& ) ) );
117 connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
118 this, SLOT( plotMouseReleased( const QMouseEvent& ) ) );
119 connect( myPlot, SIGNAL( legendClicked( long ) ),
120 this, SLOT( onLegendClicked( long ) ) );
122 /* Initial Setup - get from the preferences */
125 myPlot->setMargin( 5 );
126 setCurveType( myCurveType, false );
127 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
128 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor, false );
129 setMainTitle( myTitleEnabled, myTitle, false );
130 setXTitle( myXTitleEnabled, myXTitle, false );
131 setYTitle( myYTitleEnabled, myYTitle, false );
132 setHorScaleMode( myXMode, false );
133 setVerScaleMode( myYMode, false );
134 setBackgroundColor( myBackground );
135 setLegendPos( myLegendPos );
136 showLegend( myShowLegend, false );
140 resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
146 Plot2d_ViewFrame::~Plot2d_ViewFrame()
149 qApp->removeEventFilter( this );
152 Creates popup menu actions
154 void Plot2d_ViewFrame::createActions()
156 QAD_ResourceMgr* rmgr = QAD_Desktop::getResourceManager();
157 /* Linear/logarithmic mode */
159 QActionPGroup* modeHorGrp = new QActionPGroup( this );
160 modeHorGrp->setExclusive( TRUE );
161 QActionP* linearXAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LINEAR_HOR"),
162 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LINEAR_HOR") ) ,
163 tr( "MEN_PLOT2D_MODE_LINEAR_HOR" ), 0, modeHorGrp );
164 linearXAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LINEAR_HOR" ) );
165 linearXAction->setToggleAction( true );
166 myActions.insert( ModeXLinearId, linearXAction );
167 QActionP* logXAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LOGARITHMIC_HOR"),
168 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LOGARITHMIC_HOR") ) ,
169 tr( "MEN_PLOT2D_MODE_LOGARITHMIC_HOR" ), 0, modeHorGrp );
170 logXAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LOGARITHMIC_HOR" ) );
171 logXAction->setToggleAction( true );
172 myActions.insert( ModeXLogarithmicId, logXAction );
173 connect( modeHorGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onHorMode() ) );
176 QActionPGroup* modeVerGrp = new QActionPGroup( this );
177 modeVerGrp->setExclusive( TRUE );
178 QActionP* linearYAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LINEAR_VER"),
179 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LINEAR_VER") ) ,
180 tr( "MEN_PLOT2D_MODE_LINEAR_VER" ), 0, modeVerGrp );
181 linearYAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LINEAR_VER" ) );
182 linearYAction->setToggleAction( true );
183 myActions.insert( ModeYLinearId, linearYAction );
184 QActionP* logYAction = new QActionP ( tr( "TOT_PLOT2D_MODE_LOGARITHMIC_VER"),
185 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_MODE_LOGARITHMIC_VER") ) ,
186 tr( "MEN_PLOT2D_MODE_LOGARITHMIC_VER" ), 0, modeVerGrp );
187 logYAction->setStatusTip ( tr( "PRP_PLOT2D_MODE_LOGARITHMIC_VER" ) );
188 logYAction->setToggleAction( true );
189 myActions.insert( ModeYLogarithmicId, logYAction );
190 connect( modeVerGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onVerMode() ) );
193 QActionP* legendAction = new QActionP ( tr( "TOT_PLOT2D_SHOW_LEGEND"),
194 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_SHOW_LEGEND") ) ,
195 tr( "MEN_PLOT2D_SHOW_LEGEND" ), 0, this );
196 legendAction->setStatusTip ( tr( "PRP_PLOT2D_SHOW_LEGEND" ) );
197 legendAction->setToggleAction( true );
198 myActions.insert( LegendId, legendAction );
199 connect( legendAction, SIGNAL( activated() ), this, SLOT( onLegend() ) );
202 QActionPGroup* curveGrp = new QActionPGroup( this );
203 curveGrp->setExclusive( TRUE );
204 QActionP* pointsAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_POINTS"),
205 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_POINTS") ) ,
206 tr( "MEN_PLOT2D_CURVES_POINTS" ), 0, curveGrp );
207 pointsAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_POINTS" ) );
208 pointsAction->setToggleAction( true );
209 myActions.insert( CurvePointsId, pointsAction );
210 QActionP* linesAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_LINES"),
211 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_LINES") ) ,
212 tr( "MEN_PLOT2D_CURVES_LINES" ), 0, curveGrp );
213 linesAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_LINES" ) );
214 linesAction->setToggleAction( true );
215 myActions.insert( CurveLinesId, linesAction );
216 QActionP* splinesAction = new QActionP ( tr( "TOT_PLOT2D_CURVES_SPLINES"),
217 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_CURVES_SPLINES") ) ,
218 tr( "MEN_PLOT2D_CURVES_SPLINES" ), 0, curveGrp );
219 splinesAction->setStatusTip ( tr( "PRP_PLOT2D_CURVES_SPLINES" ) );
220 splinesAction->setToggleAction( true );
221 myActions.insert( CurveSplinesId, splinesAction );
222 connect( curveGrp, SIGNAL( selected( QActionP* ) ), this, SLOT( onCurves() ) );
225 QActionP* settingsAction = new QActionP ( tr( "TOT_PLOT2D_SETTINGS"),
226 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_SETTINGS") ) ,
227 tr( "MEN_PLOT2D_SETTINGS" ), 0, this );
228 settingsAction->setStatusTip ( tr( "PRP_PLOT2D_SETTINGS" ) );
229 myActions.insert( SettingsId, settingsAction );
230 connect( settingsAction, SIGNAL( activated() ), this, SLOT( onSettings() ) );
233 QActionP* fitDataAction = new QActionP ( tr( "TOT_PLOT2D_FITDATA"),
234 rmgr->loadPixmap( "SALOMEGUI", tr("ICON_PLOT2D_FITDATA") ) ,
235 tr( "MEN_PLOT2D_FITDATA" ), 0, this );
236 fitDataAction->setStatusTip ( tr( "PRP_PLOT2D_FITDATA" ) );
237 myActions.insert( FitDataId, fitDataAction );
238 connect( fitDataAction, SIGNAL( activated() ), this, SLOT( onFitData() ) );
241 QActionP* changeBGAction = new QActionP ( tr( "TOT_PLOT2D_CHANGE_BACKGROUND"),
242 tr( "MEN_PLOT2D_CHANGE_BACKGROUND" ), 0, this );
243 fitDataAction->setStatusTip ( tr( "PRP_PLOT2D_CHANGE_BACKGROUND" ) );
244 myActions.insert( ChangeBackgroundId, changeBGAction );
245 connect( changeBGAction, SIGNAL( activated() ), this, SLOT( onChangeBackground() ) );
248 Gets window's central widget
250 QWidget* Plot2d_ViewFrame::getViewWidget()
252 return (QWidget*)myPlot;
254 /* Popup management : sets Popup server */
255 void Plot2d_ViewFrame::setPopupServer( QAD_Application* App )
257 // QAD_PopupClientServer::setPopupServer( (QAD_PopupServer*)App );
262 void Plot2d_ViewFrame::onCreatePopup()
267 QPopupMenu* scalingPopup = new QPopupMenu( myPopup );
268 myActions[ ModeXLinearId ]->addTo( scalingPopup );
269 myActions[ ModeXLogarithmicId ]->addTo( scalingPopup );
270 scalingPopup->insertSeparator();
271 myActions[ ModeYLinearId ]->addTo( scalingPopup );
272 myActions[ ModeYLogarithmicId ]->addTo( scalingPopup );
273 myActions[ FitDataId ]->addTo( myPopup );
274 myPopup->insertItem( tr( "SCALING_POPUP" ), scalingPopup );
276 QPopupMenu* curTypePopup = new QPopupMenu( myPopup );
277 myActions[ CurvePointsId ]->addTo( curTypePopup );
278 myActions[ CurveLinesId ]->addTo( curTypePopup );
279 myActions[ CurveSplinesId ]->addTo( curTypePopup );
280 myPopup->insertItem( tr( "CURVE_TYPE_POPUP" ), curTypePopup );
282 myPopup->insertSeparator();
283 myActions[ LegendId ]->addTo( myPopup );
285 myPopup->insertSeparator();
286 myActions[ SettingsId ]->addTo( myPopup );
288 myPopup->insertSeparator();
289 myActions[ ChangeBackgroundId ]->addTo( myPopup );
293 Renames curve if it is found
295 void Plot2d_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
297 Plot2d_Curve* curve = getCurveByIO( IObject );
299 curve->setVerTitle( newName );
300 int key = hasCurve( curve );
302 myPlot->setCurveTitle( key, newName );
303 // int legendIndex = myPlot->getLegend()->findFirstKey( key );
304 // if ( legendIndex != myPlot->getLegend()->itemCnt() )
305 // myPlot->getLegend()->setText( legendIndex, aSymbol );
311 Returns true if interactive object is presented in the viewer
313 bool Plot2d_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject )
315 if( getCurveByIO( IObject ) != NULL )
318 if(!IObject.IsNull()){
319 QIntDictIterator<Plot2d_Curve> it(myCurves);
320 for(; it.current();++it){
321 if(it.current()->hasIO() && it.current()->getTableIO()->isSame(IObject))
328 Returns true if interactive object is presented in the viewer and displayed
330 bool Plot2d_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject )
332 Plot2d_Curve* curve = getCurveByIO( IObject );
334 int key = hasCurve( curve );
336 return myPlot->curve( key )->enabled();
341 Return interactive obeject if is presented in the viewer
343 Handle(SALOME_InteractiveObject) Plot2d_ViewFrame::FindIObject( const char* Entry )
345 Handle(SALOME_InteractiveObject) o;
346 QIntDictIterator<Plot2d_Curve> it( myCurves );
347 for ( ; it.current(); ++it ) {
348 if ( it.current()->hasIO() && !strcmp( it.current()->getIO()->getEntry(), Entry ) ) {
349 o = it.current()->getIO();
356 Actually this method just re-displays curves which refers to the <IObject>
358 void Plot2d_ViewFrame::Display( const Handle(SALOME_InteractiveObject)& IObject, bool update )
360 Plot2d_Curve* curve = getCurveByIO( IObject );
362 updateCurve( curve, update );
365 Actually this method just erases all curves which don't refer to <IOBject>
366 and re-displays curve which is of <IObject>
368 void Plot2d_ViewFrame::DisplayOnly( const Handle(SALOME_InteractiveObject)& IObject )
370 Plot2d_Curve* curve = getCurveByIO( IObject );
371 QList<Plot2d_Curve> clist;
373 for ( int i = 0; i < clist.count(); i++ ) {
374 if ( clist.at( i ) != curve )
377 updateCurve( curve, false );
382 Removes from the viewer the curves which refer to <IObject>
384 void Plot2d_ViewFrame::Erase( const Handle(SALOME_InteractiveObject)& IObject, bool update )
386 Plot2d_Curve* curve = getCurveByIO( IObject );
388 eraseCurve( curve, update );
391 Actually this method just re-displays all curves which are presented in the viewer
393 void Plot2d_ViewFrame::DisplayAll()
395 QList<Plot2d_Curve> clist;
397 for ( int i = 0; i < clist.count(); i++ ) {
398 updateCurve( clist.at( i ), false );
403 Removes all curves from the view
405 void Plot2d_ViewFrame::EraseAll()
412 Redraws viewframe contents
414 void Plot2d_ViewFrame::Repaint()
421 bool Plot2d_ViewFrame::eventFilter( QObject* o, QEvent* e )
423 if ( ( e->type() == QEvent::MouseButtonPress || e->type() == QEvent::KeyPress ) && o != myPlot->canvas() ) {
424 myOperation = NoOpId;
425 qApp->removeEventFilter( this );
427 return QMainWindow::eventFilter( o, e );
432 void Plot2d_ViewFrame::setTitle( const QString& title )
434 setMainTitle( myTitleEnabled, title, true );
437 Reads Plot2d view settings from the preferences
439 void Plot2d_ViewFrame::readPreferences()
441 if ( QAD_CONFIG->hasSetting( "Plot2d:CurveType" ) ) { // curve type
442 myCurveType = QAD_CONFIG->getSetting( "Plot2d:CurveType" ).toInt();
443 if ( myCurveType < 0 || myCurveType > 2 ) myCurveType = 1;
445 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowLegend" ) ) {
446 myShowLegend = QAD_CONFIG->getSetting( "Plot2d:ShowLegend" ) == QString( "true" ); // show legend
448 if ( QAD_CONFIG->hasSetting( "Plot2d:LegendPos" ) ) { // legend position
449 myLegendPos = QAD_CONFIG->getSetting( "Plot2d:LegendPos" ).toInt();
450 if ( myLegendPos < 0 || myLegendPos > 3 ) myLegendPos = 1;
452 if ( QAD_CONFIG->hasSetting( "Plot2d:MarkerSize" ) ) { // marker size
453 myMarkerSize = QAD_CONFIG->getSetting( "Plot2d:MarkerSize" ).toInt();
455 if ( QAD_CONFIG->hasSetting( "Plot2d:Background" ) ) { // background color
456 QString bgString = QAD_CONFIG->getSetting( "Plot2d:Background" );
457 QStringList bgData = QStringList::split( ":", bgString, true );
458 int bgRed = 0, bgGreen = 0, bgBlue = 0;
459 if ( bgData.count() > 0 ) bgRed = bgData[ 0 ].toInt();
460 if ( bgData.count() > 1 ) bgGreen = bgData[ 1 ].toInt();
461 if ( bgData.count() > 2 ) bgBlue = bgData[ 2 ].toInt();
462 myBackground = QColor( bgRed, bgGreen, bgBlue );
464 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowTitle" ) ) { // main title
465 myTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowTitle" ) == QString( "true" );
467 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowHorTitle" ) ) { // hor.axis title
468 myXTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowHorTitle" ) == QString( "true" );
470 if ( QAD_CONFIG->hasSetting( "Plot2d:ShowVerTitle" ) ) { // ver.axisn title
471 myYTitleEnabled = QAD_CONFIG->getSetting( "Plot2d:ShowVerTitle" ) == QString( "true" );
473 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableHorMajorGrid" ) ) { // grid
474 myXGridMajorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableHorMajorGrid" ) == QString( "true" );
476 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableVerMajorGrid" ) ) {
477 myYGridMajorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableVerMajorGrid" ) == QString( "true" );
479 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableHorMinorGrid" ) ) {
480 myXGridMinorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableHorMinorGrid" ) == QString( "true" );
482 if ( QAD_CONFIG->hasSetting( "Plot2d:EnableVerMinorGrid" ) ) {
483 myYGridMinorEnabled = QAD_CONFIG->getSetting( "Plot2d:EnableVerMinorGrid" ) == QString( "true" );
485 if ( QAD_CONFIG->hasSetting( "Plot2d:HorMajorGridMax" ) ) {
486 myXGridMaxMajor = QAD_CONFIG->getSetting( "Plot2d:HorMajorGridMax" ).toInt();
488 if ( QAD_CONFIG->hasSetting( "Plot2d:VerMajorGridMax" ) ) {
489 myYGridMaxMajor = QAD_CONFIG->getSetting( "Plot2d:VerMajorGridMax" ).toInt();
491 if ( QAD_CONFIG->hasSetting( "Plot2d:HorMinorGridMax" ) ) {
492 myXGridMaxMinor = QAD_CONFIG->getSetting( "Plot2d:HorMinorGridMax" ).toInt();
494 if ( QAD_CONFIG->hasSetting( "Plot2d:VerMinorGridMax" ) ) {
495 myYGridMaxMinor = QAD_CONFIG->getSetting( "Plot2d:VerMinorGridMax" ).toInt();
497 if ( QAD_CONFIG->hasSetting( "Plot2d:HorScaleMode" ) ) { // scale mode
498 myXMode = QAD_CONFIG->getSetting( "Plot2d:HorScaleMode" ).toInt();
499 if ( myXMode < 0 || myXMode > 1 ) myXMode = 0;
501 if ( QAD_CONFIG->hasSetting( "Plot2d:VerScaleMode" ) ) {
502 myYMode = QAD_CONFIG->getSetting( "Plot2d:VerScaleMode" ).toInt();
503 if ( myYMode < 0 || myYMode > 1 ) myYMode = 0;
507 Writes Plot2d view settings to the preferences
509 void Plot2d_ViewFrame::writePreferences()
511 QAD_CONFIG->addSetting( "Plot2d:CurveType", myCurveType ); // curve type
512 QAD_CONFIG->addSetting( "Plot2d:ShowLegend", myShowLegend ? "true" : "false" ); // show legend
513 QAD_CONFIG->addSetting( "Plot2d:LegendPos", myLegendPos ); // legend position
514 QAD_CONFIG->addSetting( "Plot2d:MarkerSize", myMarkerSize ); // marker size
516 bgData.append( QString::number( myBackground.red() ) );
517 bgData.append( QString::number( myBackground.green() ) );
518 bgData.append( QString::number( myBackground.blue() ) );
519 QAD_CONFIG->addSetting( "Plot2d:Background", bgData.join( ":" ) ); // background color
520 QAD_CONFIG->addSetting( "Plot2d:ShowTitle", myTitleEnabled ? "true" : "false" ); // titles
521 QAD_CONFIG->addSetting( "Plot2d:ShowHorTitle", myXTitleEnabled ? "true" : "false" );
522 QAD_CONFIG->addSetting( "Plot2d:ShowVerTitle", myYTitleEnabled ? "true" : "false" );
523 QAD_CONFIG->addSetting( "Plot2d:EnableHorMajorGrid", myXGridMajorEnabled ? "true" : "false" ); // grid
524 QAD_CONFIG->addSetting( "Plot2d:EnableVerMajorGrid", myYGridMajorEnabled ? "true" : "false" );
525 QAD_CONFIG->addSetting( "Plot2d:EnableHorMinorGrid", myXGridMinorEnabled ? "true" : "false" );
526 QAD_CONFIG->addSetting( "Plot2d:EnableVerMinorGrid", myYGridMinorEnabled ? "true" : "false" );
527 QAD_CONFIG->addSetting( "Plot2d:HorMajorGridMax", myXGridMaxMajor );
528 QAD_CONFIG->addSetting( "Plot2d:VerMajorGridMax", myYGridMaxMajor );
529 QAD_CONFIG->addSetting( "Plot2d:HorMinorGridMax", myXGridMaxMinor );
530 QAD_CONFIG->addSetting( "Plot2d:VerMinorGridMax", myYGridMaxMinor );
531 QAD_CONFIG->addSetting( "Plot2d:HorScaleMode", myXMode ); // scale mode
532 QAD_CONFIG->addSetting( "Plot2d:VerScaleMode", myYMode );
535 Prints mouse cursor coordinates into string
537 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt )
539 bool xFound = false, yFound = false;
540 double xCoord, yCoord;
541 const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
542 for ( int i = 0; i < aXscale->majCnt(); i++ ) {
543 double majXmark = aXscale->majMark( i );
544 int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
545 if ( xmark-2 == pnt.x() ) {
548 MESSAGE("Plot2d_ViewFrame::getInfo : close maj X mark("<<i<<") = "<<majXmark<<" "<<xmark<<" "<<pnt.x());
553 for ( int i = 0; i < aXscale->minCnt(); i++ ) {
554 double minXmark = aXscale->minMark( i );
555 int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
556 if ( xmark-2 == pnt.x() ) {
559 MESSAGE("Plot2d_ViewFrame::getInfo : close min X mark("<<i<<") = "<<minXmark<<" "<<xmark<<" "<<pnt.x());
564 const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
565 for ( int i = 0; i < aYscale->majCnt(); i++ ) {
566 double majYmark = aYscale->majMark( i );
567 int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
568 if ( ymark-2 == pnt.y() ) {
575 for ( int i = 0; i < aYscale->minCnt(); i++ ) {
576 double minYmark = aYscale->minMark( i );
577 int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
578 if ( ymark-2 == pnt.y() ) {
585 QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
588 QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
591 QString info = tr("INF_COORDINATES").arg( strX ).arg( strY );
595 Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
597 static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
599 QwtSymbol::Style ms = QwtSymbol::None;
601 case Plot2d_Curve::Circle:
602 ms = QwtSymbol::Ellipse; break;
603 case Plot2d_Curve::Rectangle:
604 ms = QwtSymbol::Rect; break;
605 case Plot2d_Curve::Diamond:
606 ms = QwtSymbol::Diamond; break;
607 case Plot2d_Curve::DTriangle:
608 ms = QwtSymbol::DTriangle; break;
609 case Plot2d_Curve::UTriangle:
610 ms = QwtSymbol::UTriangle; break;
611 case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
612 ms = QwtSymbol::RTriangle; break;
613 case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
614 ms = QwtSymbol::LTriangle; break;
615 case Plot2d_Curve::Cross:
616 ms = QwtSymbol::Cross; break;
617 case Plot2d_Curve::XCross:
618 ms = QwtSymbol::XCross; break;
619 case Plot2d_Curve::None:
621 ms = QwtSymbol::None; break;
626 Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
628 static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
630 Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;
632 case QwtSymbol::Ellipse:
633 ms = Plot2d_Curve::Circle; break;
634 case QwtSymbol::Rect:
635 ms = Plot2d_Curve::Rectangle; break;
636 case QwtSymbol::Diamond:
637 ms = Plot2d_Curve::Diamond; break;
638 case QwtSymbol::DTriangle:
639 ms = Plot2d_Curve::DTriangle; break;
640 case QwtSymbol::UTriangle:
641 ms = Plot2d_Curve::UTriangle; break;
642 case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
643 ms = Plot2d_Curve::LTriangle; break;
644 case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
645 ms = Plot2d_Curve::RTriangle; break;
646 case QwtSymbol::Cross:
647 ms = Plot2d_Curve::Cross; break;
648 case QwtSymbol::XCross:
649 ms = Plot2d_Curve::XCross; break;
650 case QwtSymbol::None:
652 ms = Plot2d_Curve::None; break;
657 Converts Plot2d_Curve's line style to Qwt line style [ static ]
659 static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
661 Qt::PenStyle ps = Qt::NoPen;
663 case Plot2d_Curve::Solid:
664 ps = Qt::SolidLine; break;
665 case Plot2d_Curve::Dash:
666 ps = Qt::DashLine; break;
667 case Plot2d_Curve::Dot:
668 ps = Qt::DotLine; break;
669 case Plot2d_Curve::DashDot:
670 ps = Qt::DashDotLine; break;
671 case Plot2d_Curve::DashDotDot:
672 ps = Qt::DashDotDotLine; break;
673 case Plot2d_Curve::NoPen:
675 ps = Qt::NoPen; break;
680 Converts Qwt line style to Plot2d_Curve's line style [ static ]
682 static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
684 Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
687 ps = Plot2d_Curve::Solid; break;
689 ps = Plot2d_Curve::Dash; break;
691 ps = Plot2d_Curve::Dot; break;
692 case Qt::DashDotLine:
693 ps = Plot2d_Curve::DashDot; break;
694 case Qt::DashDotDotLine:
695 ps = Plot2d_Curve::DashDotDot; break;
698 ps = Plot2d_Curve::NoPen; break;
705 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
709 if ( hasCurve( curve ) ) {
710 updateCurve( curve, update );
713 long curveKey = myPlot->insertCurve( curve->getVerTitle() );
714 myCurves.insert( curveKey, curve );
715 if ( curve->isAutoAssign() ) {
716 QwtSymbol::Style typeMarker;
718 Qt::PenStyle typeLine;
719 myPlot->getNextMarker( typeMarker, color, typeLine );
720 myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
721 myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker,
724 QSize( myMarkerSize, myMarkerSize ) ) );
725 curve->setColor( color );
726 curve->setLine( qwt2plotLine( typeLine ) );
727 curve->setMarker( qwt2plotMarker( typeMarker ) );
730 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
731 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
732 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
733 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
734 QBrush( curve->getColor() ),
735 QPen( curve->getColor() ),
736 QSize( myMarkerSize, myMarkerSize ) ) );
738 if ( myCurveType == 0 )
739 myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
740 else if ( myCurveType == 1 )
741 myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
742 else if ( myCurveType == 2 )
743 myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
744 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
751 Adds curves into view
753 void Plot2d_ViewFrame::displayCurves( Plot2d_CurveContainer& curves, bool update )
755 myPlot->setUpdatesEnabled( false );
756 for ( int i = 0; i < curves.count(); i++ ) {
757 displayCurve( curves.curve( i ), false );
760 myPlot->setUpdatesEnabled( true );
767 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
771 int curveKey = hasCurve( curve );
773 myPlot->removeCurve( curveKey );
774 myCurves.remove( curveKey );
783 void Plot2d_ViewFrame::eraseCurves( Plot2d_CurveContainer& curves, bool update )
785 for ( int i = 0; i < curves.count(); i++ ) {
786 eraseCurve( curves.curve( i ), false );
793 Updates curves attributes
795 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
799 int curveKey = hasCurve( curve );
801 if ( !curve->isAutoAssign() ) {
802 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
803 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
804 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
805 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
806 QBrush( curve->getColor() ),
807 QPen( curve->getColor() ),
808 QSize( myMarkerSize, myMarkerSize ) ) );
810 myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
811 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
812 myPlot->curve( curveKey )->setEnabled( true );
819 Returns curve key if is is displayed in the viewer and 0 otherwise
821 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
823 QIntDictIterator<Plot2d_Curve> it( myCurves );
824 for ( ; it.current(); ++it ) {
825 if ( it.current() == curve )
826 return it.currentKey();
830 Plot2d_Curve* Plot2d_ViewFrame::getCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject )
832 if ( !theIObject.IsNull() ) {
833 QIntDictIterator<Plot2d_Curve> it( myCurves );
834 for ( ; it.current(); ++it ) {
835 if ( it.current()->hasIO() && it.current()->getIO()->isSame( theIObject ) )
842 Gets lsit of displayed curves
844 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
847 clist.setAutoDelete( false );
848 QIntDictIterator<Plot2d_Curve> it( myCurves );
849 for ( ; it.current(); ++it ) {
850 clist.append( it.current() );
852 return clist.count();
856 Updates titles according to curves
858 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
859 void Plot2d_ViewFrame::updateTitles()
861 QAD_Study* activeStudy = QAD_Application::getDesktop()->getActiveStudy();
862 QIntDictIterator<Plot2d_Curve> it( myCurves );
863 QStringList aXTitles;
864 QStringList aYTitles;
869 while ( it.current() ) {
870 // collect titles and units from all curves...
871 QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
872 QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
873 QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
874 QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
876 aYTitles.append( yTitle );
877 if ( aXTitles.find( xTitle ) == aXTitles.end() )
878 aXTitles.append( xTitle );
879 if ( aXUnits.find( xUnits ) == aXUnits.end() )
880 aXUnits.append( xUnits );
881 if ( aYUnits.find( yUnits ) == aYUnits.end() )
882 aYUnits.append( yUnits );
884 if ( activeStudy && it.current()->hasTableIO() ) {
885 SALOMEDS::SObject_var SO = activeStudy->getStudyDocument()->FindObjectID( it.current()->getTableIO()->getEntry() );
886 if ( !SO->_is_nil() ) {
887 SALOMEDS::GenericAttribute_var anAttr;
888 if ( SO->FindAttribute( anAttr, "AttributeName" ) ) {
889 SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow( anAttr );
890 QString aName = aNameAttr->Value();
891 if ( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
892 aTables.append( aName );
900 // ... and update plot 2d view
901 QString xUnits, yUnits;
902 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
903 xUnits = BRACKETIZE( aXUnits[0] );
904 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
905 yUnits = BRACKETIZE( aYUnits[0] );
906 QString xTitle, yTitle;
907 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
908 xTitle = aXTitles[0];
909 if ( aYTitles.count() == 1 )
910 yTitle = aYTitles[0];
912 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
914 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
917 setXTitle( myXTitleEnabled, xTitle + xUnits );
918 setYTitle( myYTitleEnabled, yTitle + yUnits );
919 setTitle( aTables.join("; ") );
922 Fits the view to see all data
924 void Plot2d_ViewFrame::fitAll()
926 myPlot->setAxisAutoScale( QwtPlot::yLeft );
927 myPlot->setAxisAutoScale( QwtPlot::xBottom );
931 Fits the view to rectangle area (pixels)
933 void Plot2d_ViewFrame::fitArea( const QRect& area )
935 QRect rect = area.normalize();
936 if ( rect.width() < MIN_RECT_SIZE ) {
937 rect.setWidth( MIN_RECT_SIZE );
938 rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
940 if ( rect.height() < MIN_RECT_SIZE ) {
941 rect.setHeight( MIN_RECT_SIZE );
942 rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
944 myPlot->setAxisScale( QwtPlot::yLeft,
945 myPlot->invTransform( QwtPlot::yLeft, rect.top() ),
946 myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
947 myPlot->setAxisScale( QwtPlot::xBottom,
948 myPlot->invTransform( QwtPlot::xBottom, rect.left() ),
949 myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
953 Tests if it is necessary to start operation on mouse action
955 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
957 int btn = me.button() | me.state();
958 int zoomBtn = ControlButton | LeftButton;
959 int panBtn = ControlButton | MidButton;
960 int fitBtn = ControlButton | RightButton;
962 if ( btn == zoomBtn )
971 Mode toolbar buttons slot - horizontal axis (<Linear>/<Logarithmic>)
973 void Plot2d_ViewFrame::onHorMode()
975 if ( myActions[ ModeXLinearId ]->isOn() )
976 setHorScaleMode( 0 );
977 else if ( myActions[ ModeXLogarithmicId ]->isOn() )
978 setHorScaleMode( 1 );
981 Mode toolbar buttons slot - vertical axis (<Linear>/<Logarithmic>)
983 void Plot2d_ViewFrame::onVerMode()
985 if ( myActions[ ModeYLinearId ]->isOn() )
986 setVerScaleMode( 0 );
987 else if ( myActions[ ModeYLogarithmicId ]->isOn() )
988 setVerScaleMode( 1 );
991 "Show/hide legend" toolbar action slot
993 void Plot2d_ViewFrame::onLegend()
995 showLegend( myActions[ LegendId ]->isOn() );
998 "Curve type" toolbar action slot
1000 void Plot2d_ViewFrame::onCurves()
1002 if ( myActions[ CurvePointsId ]->isOn() )
1004 else if ( myActions[ CurveLinesId ]->isOn() )
1006 else if ( myActions[ CurveSplinesId ]->isOn() )
1010 "Settings" toolbar action slot
1012 void Plot2d_ViewFrame::onSettings()
1014 #ifdef TEST_AUTOASSIGN
1015 typedef QMap<int,int> IList;
1016 typedef QMap<QString,int> SList;
1019 cols[ "red-min" ] = 1000;
1020 cols[ "red-max" ] = -1;
1021 cols[ "green-min" ] = 1000;
1022 cols[ "green-max" ] = -1;
1023 cols[ "blue-min" ] = 1000;
1024 cols[ "blue-max" ] = -1;
1025 for ( unsigned i = 0; i < 10000; i++ ) {
1026 QwtSymbol::Style typeMarker;
1028 Qt::PenStyle typeLine;
1029 myPlot->getNextMarker( typeMarker, color, typeLine );
1030 if ( mars.contains(typeMarker) )
1031 mars[ typeMarker ] = mars[ typeMarker ]+1;
1033 mars[ typeMarker ] = 0;
1034 if ( lins.contains(typeLine) )
1035 lins[ typeLine ] = lins[ typeLine ]+1;
1037 lins[ typeLine ] = 0;
1038 if ( cols[ "red-max" ] < color.red() )
1039 cols[ "red-max" ] = color.red();
1040 if ( cols[ "red-min" ] > color.red() )
1041 cols[ "red-min" ] = color.red();
1042 if ( cols[ "green-max" ] < color.green() )
1043 cols[ "green-max" ] = color.green();
1044 if ( cols[ "green-min" ] > color.green() )
1045 cols[ "green-min" ] = color.green();
1046 if ( cols[ "blue-max" ] < color.blue() )
1047 cols[ "blue-max" ] = color.blue();
1048 if ( cols[ "blue-min" ] > color.blue() )
1049 cols[ "blue-min" ] = color.blue();
1051 for (IList::Iterator it = mars.begin(); it != mars.end(); ++it)
1052 MESSAGE("markers( " << it.key() << ") = " << it.data() );
1053 for (IList::Iterator it = lins.begin(); it != lins.end(); ++it)
1054 MESSAGE("lines( " << it.key() << ") = " << it.data() );
1055 for (SList::Iterator it = cols.begin(); it != cols.end(); ++it)
1056 MESSAGE("colors( " << it.key() << ") = " << it.data() );
1059 Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true );
1060 dlg->setMainTitle( myTitleEnabled, myTitle );
1061 dlg->setXTitle( myXTitleEnabled, myXTitle );
1062 dlg->setYTitle( myYTitleEnabled, myYTitle );
1063 dlg->setCurveType( myCurveType );
1064 dlg->setLegend( myShowLegend, myLegendPos );
1065 dlg->setMarkerSize( myMarkerSize );
1066 dlg->setBackgroundColor( myBackground );
1067 dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
1068 myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ) );
1069 dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
1070 myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ) );
1071 dlg->setScaleMode( myXMode, myYMode );
1073 if ( dlg->exec() == QDialog::Accepted ) {
1074 // horizontal axis title
1075 setXTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), false );
1076 // vertical axis title
1077 setYTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), false );
1079 setMainTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), true );
1081 if ( myCurveType != dlg->getCurveType() ) {
1082 setCurveType( dlg->getCurveType(), false );
1085 if ( myShowLegend != dlg->isLegendEnabled() ) {
1086 showLegend( dlg->isLegendEnabled(), false );
1088 if ( myLegendPos != dlg->getLegendPos() ) {
1089 setLegendPos( dlg->getLegendPos() );
1092 if ( myMarkerSize != dlg->getMarkerSize() ) {
1093 setMarkerSize( dlg->getMarkerSize(), false );
1096 if ( myBackground != dlg->getBackgroundColor() ) {
1097 setBackgroundColor( dlg->getBackgroundColor() );
1100 bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled;
1101 int aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor;
1102 dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor );
1103 dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor );
1104 setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1105 setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor, false );
1107 if ( myXMode != dlg->getXScaleMode() ) {
1108 setHorScaleMode( dlg->getXScaleMode() );
1110 if ( myYMode != dlg->getYScaleMode() ) {
1111 setVerScaleMode( dlg->getYScaleMode() );
1115 // update preferences
1116 if ( dlg->isSetAsDefault() )
1122 "Fit Data" command slot
1124 void Plot2d_ViewFrame::onFitData()
1126 Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this );
1127 int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
1128 int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
1129 int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
1130 int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
1131 double xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
1132 double xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
1133 double yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
1134 double yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
1136 dlg->setRange( xMin, xMax, yMin, yMax );
1137 if ( dlg->exec() == QDialog::Accepted ) {
1138 int mode = dlg->getRange( xMin, xMax, yMin, yMax );
1139 if ( mode == 0 || mode == 2 )
1140 myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
1141 if ( mode == 0 || mode == 1 )
1142 myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax );
1148 Change background color
1150 void Plot2d_ViewFrame::onChangeBackground()
1152 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
1153 if ( selColor.isValid() ) {
1154 setBackgroundColor( selColor );
1160 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1162 myCurveType = curveType;
1163 if ( curveType == 0 )
1164 myActions[ CurvePointsId ]->setOn( true );
1165 else if ( curveType == 1 )
1166 myActions[ CurveLinesId ]->setOn( true );
1167 else if ( curveType == 2 )
1168 myActions[ CurveSplinesId ]->setOn( true );
1170 QArray<long> keys = myPlot->curveKeys();
1171 for ( int i = 0; i < keys.count(); i++ ) {
1172 if ( myCurveType == 0 )
1173 myPlot->setCurveStyle( keys[i], QwtCurve::NoCurve );
1174 else if ( myCurveType == 1 )
1175 myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1176 else if ( myCurveType == 2 )
1177 myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1185 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1187 myShowLegend = show;
1188 myActions[ LegendId ]->setOn( myShowLegend );
1190 myPlot->setAutoLegend( myShowLegend );
1191 myPlot->enableLegend( myShowLegend );
1197 Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1199 void Plot2d_ViewFrame::setLegendPos( int pos )
1204 myPlot->setLegendPos( Qwt::Left );
1207 myPlot->setLegendPos( Qwt::Right );
1210 myPlot->setLegendPos( Qwt::Top );
1213 myPlot->setLegendPos( Qwt::Bottom );
1218 Sets new marker size
1220 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1222 if ( myMarkerSize != size ) {
1223 myMarkerSize = size;
1224 QArray<long> keys = myPlot->curveKeys();
1225 for ( int i = 0; i < keys.count(); i++ ) {
1226 QwtPlotCurve* crv = myPlot->curve( keys[i] );
1228 QwtSymbol aSymbol = crv->symbol();
1229 aSymbol.setSize( myMarkerSize, myMarkerSize );
1230 crv->setSymbol( aSymbol );
1231 int legendIndex = myPlot->getLegend()->findFirstKey( keys[i] );
1232 if ( legendIndex != myPlot->getLegend()->itemCnt() )
1233 myPlot->getLegend()->setSymbol( legendIndex, aSymbol );
1241 Sets background color
1243 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1245 myBackground = color;
1246 //myPlot->setCanvasBackground( myBackground );
1247 myPlot->canvas()->setPalette( myBackground );
1248 myPlot->setPalette( myBackground );
1249 QPalette aPal = myPlot->getLegend()->palette();
1250 for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1251 QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1252 aPal.setColor( cg, QColorGroup::Base, myBackground );
1253 aPal.setColor( cg, QColorGroup::Background, myBackground );
1255 myPlot->getLegend()->setPalette( aPal );
1258 Gets background color
1260 QColor Plot2d_ViewFrame::backgroundColor() const
1262 return myBackground;
1265 Sets hor.axis grid parameters
1267 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
1268 bool xMinorEnabled, const int xMinorMax,
1271 myXGridMajorEnabled = xMajorEnabled;
1272 myXGridMinorEnabled = xMinorEnabled;
1273 myXGridMaxMajor = xMajorMax;
1274 myXGridMaxMinor = xMinorMax;
1275 myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1276 myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1277 myPlot->enableGridX( myXGridMajorEnabled );
1278 myPlot->enableGridXMin( myXGridMinorEnabled );
1283 Sets ver.axis grid parameters
1285 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
1286 bool yMinorEnabled, const int yMinorMax,
1289 myYGridMajorEnabled = yMajorEnabled;
1290 myYGridMinorEnabled = yMinorEnabled;
1291 myYGridMaxMajor = yMajorMax;
1292 myYGridMaxMinor = yMinorMax;
1293 myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1294 myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1295 myPlot->enableGridY( myYGridMajorEnabled );
1296 myPlot->enableGridYMin( myYGridMinorEnabled );
1303 void Plot2d_ViewFrame::setMainTitle( bool enabled, const QString& title, bool update )
1305 myTitleEnabled = enabled;
1307 myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1314 void Plot2d_ViewFrame::setXTitle( bool enabled, const QString& title, bool update )
1316 myXTitleEnabled = enabled;
1318 myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1325 void Plot2d_ViewFrame::setYTitle( bool enabled, const QString& title, bool update )
1327 myYTitleEnabled = enabled;
1329 myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1334 Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1336 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1339 if ( myXMode == 0 ) { // linear
1340 myActions[ ModeXLogarithmicId ]->setOn( false );
1341 myActions[ ModeXLinearId ]->setOn( true );
1342 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1344 else { // logarithmic
1345 myActions[ ModeXLinearId ]->setOn( false );
1346 myActions[ ModeXLogarithmicId ]->setOn( true );
1347 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
1350 // myPlot->replot();
1354 Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1356 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1359 if ( myYMode == 0 ) { // linear
1360 myActions[ ModeYLogarithmicId ]->setOn( false );
1361 myActions[ ModeYLinearId ]->setOn( true );
1362 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1364 else { // logarithmic
1365 myActions[ ModeYLinearId ]->setOn( false );
1366 myActions[ ModeYLogarithmicId ]->setOn( true );
1367 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
1370 // myPlot->replot();
1374 Slot, called when Legend item is clicked
1376 void Plot2d_ViewFrame::onLegendClicked( long key )
1378 Plot2d_Curve* curve = myCurves[ key ];
1379 if ( curve && curve->hasIO() ) {
1380 SALOME_Selection* Sel = SALOME_Selection::Selection( QAD_Application::getDesktop()->getActiveStudy()->getSelection() );
1381 Sel->ClearIObjects();
1382 Sel->AddIObject( curve->getIO(), true );
1387 Slot, called when user presses mouse button
1389 void Plot2d_ViewFrame::plotMousePressed( const QMouseEvent& me )
1391 if ( myOperation == NoOpId )
1392 myOperation = testOperation( me );
1393 if ( myOperation != NoOpId ) {
1395 if ( myOperation == ZoomId ) {
1396 myPlot->canvas()->setCursor( QCursor( QPixmap( imageZoomCursor ) ) );
1398 else if ( myOperation == PanId ) {
1399 myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
1401 else if ( myOperation == FitAreaId ) {
1402 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1403 myPlot->setOutlineStyle( Qwt::Rect );
1407 int btn = me.button() | me.state();
1408 if ( btn == RightButton ) {
1411 QAD_Tools::checkPopup( myPopup );
1412 if ( myPopup->count()>0 ) {
1413 myPopup->exec( QCursor::pos() );
1419 myPlot->setOutlineStyle( Qwt::Cross );
1420 QAD_Application::getDesktop()->putInfo( getInfo( me.pos() ) );
1425 Slot, called when user moves mouse
1427 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1429 int dx = me.pos().x() - myPnt.x();
1430 int dy = me.pos().y() - myPnt.y();
1432 if ( myOperation != NoOpId) {
1433 if ( myOperation == ZoomId ) {
1434 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1435 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1437 myPlot->setAxisScale( QwtPlot::yLeft,
1438 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1439 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1440 myPlot->setAxisScale( QwtPlot::xBottom,
1441 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1442 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1446 else if ( myOperation == PanId ) {
1447 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1448 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1450 myPlot->setAxisScale( QwtPlot::yLeft,
1451 myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ),
1452 myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1453 myPlot->setAxisScale( QwtPlot::xBottom,
1454 myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1455 myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) );
1461 QAD_Application::getDesktop()->putInfo( getInfo( me.pos() ) );
1465 Slot, called when user releases mouse
1467 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1469 if ( myOperation == FitAreaId ) {
1470 QRect rect( myPnt, me.pos() );
1473 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1474 myPlot->setOutlineStyle( Qwt::Triangle );
1475 QAD_Application::getDesktop()->putInfo( tr( "INF_READY" ) );
1476 myOperation = NoOpId;
1479 View operations : Pan view
1481 void Plot2d_ViewFrame::onViewPan()
1483 myOperation = PanId;
1484 qApp->installEventFilter( this );
1487 View operations : Zoom view
1489 void Plot2d_ViewFrame::onViewZoom()
1491 myOperation = ZoomId;
1492 qApp->installEventFilter( this );
1495 View operations : Fot All
1497 void Plot2d_ViewFrame::onViewFitAll()
1502 View operations : Fit Area
1504 void Plot2d_ViewFrame::onViewFitArea()
1506 myOperation = FitAreaId;
1507 qApp->installEventFilter( this );
1510 View operations : Global panning
1512 void Plot2d_ViewFrame::onViewGlobalPan()
1513 { MESSAGE( "Plot2d_ViewFrame::onViewGlobalPan : NOT SUPPORTED" ); }
1515 View operations : Rotate view
1517 void Plot2d_ViewFrame::onViewRotate()
1518 { MESSAGE( "Plot2d_ViewFrame::onViewRotate : NOT SUPPORTED" ); }
1520 View operations : Reset view
1522 void Plot2d_ViewFrame::onViewReset()
1523 { MESSAGE( "Plot2d_ViewFrame::onViewReset : NOT SUPPORTED" ); }
1525 View operations : View front
1527 void Plot2d_ViewFrame::onViewFront()
1528 { MESSAGE( "Plot2d_ViewFrame::onViewFront : NOT SUPPORTED" ); }
1530 View operations : View back
1532 void Plot2d_ViewFrame::onViewBack()
1533 { MESSAGE( "Plot2d_ViewFrame::onViewBack : NOT SUPPORTED" ); }
1535 View operations : View right
1537 void Plot2d_ViewFrame::onViewRight()
1538 { MESSAGE( "Plot2d_ViewFrame::onViewRight : NOT SUPPORTED" ); }
1540 View operations : View left
1542 void Plot2d_ViewFrame::onViewLeft()
1543 { MESSAGE( "Plot2d_ViewFrame::onViewLeft : NOT SUPPORTED" ); }
1545 View operations : View bottom
1547 void Plot2d_ViewFrame::onViewBottom()
1548 { MESSAGE( "Plot2d_ViewFrame::onViewBottom : NOT SUPPORTED" ); }
1550 View operations : View top
1552 void Plot2d_ViewFrame::onViewTop()
1553 { MESSAGE( "Plot2d_ViewFrame::onViewTop : NOT SUPPORTED" ); }
1555 View operations : Show/hide trihedron
1557 void Plot2d_ViewFrame::onViewTrihedron()
1558 { MESSAGE( "Plot2d_ViewFrame::onViewTrihedron : NOT SUPPORTED" ); }
1561 //=================================================================================
1562 // Plot2d_Plot2d implementation
1563 //=================================================================================
1568 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1572 enableOutline( true );
1573 setOutlineStyle( Qwt::Triangle );
1574 setOutlinePen( green );
1576 setAutoLegend( false );
1577 setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1578 enableLegend( false );
1580 enableGridX( false );
1581 enableGridXMin( false );
1582 enableGridY( false );
1583 enableGridYMin( false );
1584 // auto scaling by default
1585 setAxisAutoScale( QwtPlot::yLeft );
1586 setAxisAutoScale( QwtPlot::xBottom );
1589 Recalculates and redraws Plot 2d view
1591 void Plot2d_Plot2d::replot()
1593 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
1597 Checks if two colors are close to each other [ static ]
1598 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1600 const long COLOR_DISTANCE = 100;
1601 const int MAX_ATTEMPTS = 10;
1602 static bool closeColors( const QColor& color1, const QColor& color2 )
1604 long tol = abs( color2.red() - color1.red() ) +
1605 abs( color2.green() - color1.green() ) +
1606 abs( color2.blue() - color1.blue() );
1608 return ( tol <= COLOR_DISTANCE );
1611 Gets new unique marker for item if possible
1613 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine )
1618 int aRed = (int)( 256.0 * random() / RAND_MAX); // generate random color
1619 int aGreen = (int)( 256.0 * random() / RAND_MAX); // ...
1620 int aBlue = (int)( 256.0 * random() / RAND_MAX); // ...
1621 int aMarker = (int)( 9.0 * random() / RAND_MAX) + 1; // 9 markers types ( not including empty )
1622 int aLine = (int)( 5.0 * random() / RAND_MAX) + 1; // 5 line types ( not including empty )
1624 typeMarker = ( QwtSymbol::Style )aMarker;
1625 color = QColor( aRed, aGreen, aBlue );
1626 typeLine = ( Qt::PenStyle )aLine;
1629 if ( cnt == MAX_ATTEMPTS )
1632 bOk = !existMarker( typeMarker, color, typeLine );
1635 static int aMarker = -1;
1636 static int aColor = -1;
1637 static int aLine = -1;
1639 if ( myColors.isEmpty() ) {
1640 // creating colors list
1641 myColors.append( Qt::white );
1642 myColors.append( Qt::blue );
1643 myColors.append( Qt::gray );
1644 myColors.append( Qt::darkGreen );
1645 myColors.append( Qt::magenta );
1646 myColors.append( Qt::darkGray );
1647 myColors.append( Qt::red );
1648 myColors.append( Qt::darkBlue );
1649 myColors.append( Qt::darkYellow );
1650 myColors.append( Qt::cyan );
1651 myColors.append( Qt::darkRed );
1652 myColors.append( Qt::darkCyan );
1653 myColors.append( Qt::yellow );
1654 myColors.append( Qt::darkMagenta );
1655 myColors.append( Qt::green );
1656 myColors.append( Qt::black );
1659 int nbMarkers = 11; // QwtSymbol supports 11 marker types
1660 int nbLines = 6; // Qt supports 6 line types
1661 int nbColors = myColors.count(); // number of default colors supported
1663 aMarker = ( aMarker + 1 ) % nbMarkers;
1664 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1665 aColor = ( aColor + 1 ) % nbColors;
1666 aLine = ( aLine + 1 ) % nbLines;
1667 if ( aLine == Qt::NoPen ) aLine++;
1669 typeMarker = ( QwtSymbol::Style )aMarker;
1670 color = myColors[ aColor ];
1671 typeLine = ( Qt::PenStyle )aLine;
1672 if ( !existMarker( typeMarker, color, typeLine ) )
1676 for ( i = 0; i < nbMarkers; i++ ) {
1677 aMarker = ( aMarker + 1 ) % nbMarkers;
1678 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1679 for ( j = 0; j < nbColors; j++ ) {
1680 aColor = ( aColor + 1 ) % nbColors;
1681 for ( k = 0; k < nbLines; k++ ) {
1682 aLine = ( aLine + 1 ) % nbLines;
1683 if ( aLine == Qt::NoPen ) aLine++;
1684 if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1685 typeMarker = ( QwtSymbol::Style )aMarker;
1686 color = myColors[ aColor ];
1687 typeLine = ( Qt::PenStyle )aLine;
1696 Checks if marker belongs to any enitity
1698 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine )
1700 // getting all curves
1701 QArray<long> keys = curveKeys();
1704 if ( closeColors( color, backgroundColor() ) )
1706 for ( int i = 0; i < keys.count(); i++ ) {
1707 QwtPlotCurve* crv = curve( keys[i] );
1709 QwtSymbol::Style aStyle = crv->symbol().style();
1710 QColor aColor = crv->pen().color();
1711 Qt::PenStyle aLine = crv->pen().style();
1712 // if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1713 if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1720 //==========================================================
1722 * Plot2d_ViewFrame::Display
1723 * Display presentation
1725 //==========================================================
1726 void Plot2d_ViewFrame::Display( const SALOME_Prs2d* prs )
1728 // try do downcast object
1729 const Plot2d_Prs* aPlot2dPrs = dynamic_cast<const Plot2d_Prs*>( prs );
1730 if ( !aPlot2dPrs || aPlot2dPrs->IsNull() )
1733 // display all curves from presentation
1734 Plot2d_CurveContainer aCurves = aPlot2dPrs->GetObjects();
1735 displayCurves( aCurves );
1738 //==========================================================
1740 * Plot2d_ViewFrame::Erase
1741 * Erase presentation
1743 //==========================================================
1744 void Plot2d_ViewFrame::Erase( const SALOME_Prs2d* prs, const bool )
1746 // try do downcast object
1747 const Plot2d_Prs* aPlot2dPrs = dynamic_cast<const Plot2d_Prs*>( prs );
1748 if ( !aPlot2dPrs || aPlot2dPrs->IsNull() )
1751 // erase all curves from presentation
1752 Plot2d_CurveContainer aCurves = aPlot2dPrs->GetObjects();
1753 eraseCurves( aCurves );
1756 //==========================================================
1758 * Plot2d_ViewFrame::CreatePrs
1759 * Create presentation by entry
1761 //==========================================================
1762 SALOME_Prs* Plot2d_ViewFrame::CreatePrs( const char* entry )
1764 Plot2d_Prs* prs = new Plot2d_Prs();
1766 QIntDictIterator<Plot2d_Curve> it( myCurves );
1767 for ( ; it.current(); ++it ) {
1768 if ( it.current()->hasIO() && !strcmp( it.current()->getIO()->getEntry(), entry ) ) {
1769 prs->AddObject( it.current() );
1776 //==========================================================
1778 * Plot2d_ViewFrame::BeforeDisplay
1779 * Axiluary method called before displaying of objects
1781 //==========================================================
1782 void Plot2d_ViewFrame::BeforeDisplay( SALOME_Displayer* d )
1784 d->BeforeDisplay( this, SALOME_Plot2dViewType() );
1787 //==========================================================
1789 * Plot2d_ViewFrame::AfterDisplay
1790 * Axiluary method called after displaying of objects
1792 //==========================================================
1793 void Plot2d_ViewFrame::AfterDisplay( SALOME_Displayer* d )
1795 d->AfterDisplay( this, SALOME_Plot2dViewType() );