1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 #include "Plot2d_ViewFrame.h"
21 #include "Plot2d_Prs.h"
22 #include "Plot2d_Curve.h"
23 #include "Plot2d_FitDataDlg.h"
24 #include "Plot2d_ViewWindow.h"
25 #include "Plot2d_SetupViewDlg.h"
27 #include "SUIT_Tools.h"
28 #include "SUIT_Session.h"
29 #include "SUIT_MessageBox.h"
30 #include "SUIT_ResourceMgr.h"
31 #include "SUIT_Application.h"
33 #include "qapplication.h"
35 #include <qtoolbutton.h>
37 #include <qcolordialog.h>
42 #include <qpaintdevicemetrics.h>
45 #include <qwt_plot_canvas.h>
50 #include <qwt_legend.h>
52 #define DEFAULT_LINE_WIDTH 0 // (default) line width
53 #define DEFAULT_MARKER_SIZE 9 // default marker size
54 #define MIN_RECT_SIZE 11 // min sensibility area size
56 const char* imageZoomCursor[] = {
61 "................................",
62 "................................",
63 ".#######........................",
64 "..aaaaaaa.......................",
65 "................................",
66 ".............#####..............",
67 "...........##.aaaa##............",
68 "..........#.aa.....a#...........",
69 ".........#.a.........#..........",
70 ".........#a..........#a.........",
71 "........#.a...........#.........",
72 "........#a............#a........",
73 "........#a............#a........",
74 "........#a............#a........",
75 "........#a............#a........",
76 ".........#...........#.a........",
77 ".........#a..........#a.........",
78 ".........##.........#.a.........",
79 "........#####.....##.a..........",
80 ".......###aaa#####.aa...........",
81 "......###aa...aaaaa.......#.....",
82 ".....###aa................#a....",
83 "....###aa.................#a....",
84 "...###aa...............#######..",
85 "....#aa.................aa#aaaa.",
86 ".....a....................#a....",
87 "..........................#a....",
88 "...........................a....",
89 "................................",
90 "................................",
91 "................................",
92 "................................"};
94 const char* imageCrossCursor[] = {
99 "................................",
100 "................................",
101 "................................",
102 "................................",
103 "................................",
104 "................................",
105 "................................",
106 "...............#................",
107 "...............#a...............",
108 "...............#a...............",
109 "...............#a...............",
110 "...............#a...............",
111 "...............#a...............",
112 "...............#a...............",
113 "...............#a...............",
114 ".......#################........",
115 "........aaaaaaa#aaaaaaaaa.......",
116 "...............#a...............",
117 "...............#a...............",
118 "...............#a...............",
119 "...............#a...............",
120 "...............#a...............",
121 "...............#a...............",
122 "...............#a...............",
123 "................a...............",
124 "................................",
125 "................................",
126 "................................",
127 "................................",
128 "................................",
129 "................................",
130 "................................"};
133 QPixmap zoomPixmap(imageZoomCursor);
134 QPixmap globalPanPixmap(imageCrossCursor);
136 QCursor panCursor(Qt::SizeAllCursor);
137 QCursor zoomCursor(zoomPixmap);
138 QCursor glPanCursor(globalPanPixmap);
140 //=================================================================================
141 // Plot2d_ViewFrame implementation
142 //=================================================================================
147 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
148 : QWidget (parent, title, 0),
149 myOperation( NoOpId ),
151 myShowLegend( true ), myLegendPos( 1 ),
152 myMarkerSize( DEFAULT_MARKER_SIZE ),
153 myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
154 myBackground( white ),
155 myTitleEnabled( true ), myXTitleEnabled( true ),
156 myYTitleEnabled( true ), myY2TitleEnabled (true),
157 myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ),
158 myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
159 myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
160 myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
161 myXMode( 0 ), myYMode( 0 ), mySecondY( false )
164 QVBoxLayout* aLayout = new QVBoxLayout( this );
165 myPlot = new Plot2d_Plot2d( this );
166 aLayout->addWidget( myPlot );
170 connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
171 this, SLOT( plotMouseMoved( const QMouseEvent& ) ) );
172 connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
173 this, SLOT( plotMousePressed( const QMouseEvent& ) ) );
174 connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
175 this, SLOT( plotMouseReleased( const QMouseEvent& ) ) );
176 //connect( myPlot, SIGNAL( legendClicked( long ) ),
177 // this, SLOT( onLegendClicked( long ) ) );
179 /* Initial Setup - get from the preferences */
182 myPlot->setMargin( 5 );
183 setCurveType( myCurveType, false );
184 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
185 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
186 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
188 setTitle( myTitleEnabled, myTitle, MainTitle, false );
189 setTitle( myXTitleEnabled, myXTitle, XTitle, false );
190 setTitle( myYTitleEnabled, myYTitle, YTitle, false );
193 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
194 setHorScaleMode( myXMode, false );
195 setVerScaleMode( myYMode, false );
196 setBackgroundColor( myBackground );
197 setLegendPos( myLegendPos );
198 showLegend( myShowLegend, false );
202 resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
204 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
205 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
206 myXDistance = xMap.d2() - xMap.d1();
207 myYDistance = yMap.d2() - yMap.d1();
210 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
211 myYDistance2 = yMap2.d2() - yMap2.d1();
217 Plot2d_ViewFrame::~Plot2d_ViewFrame()
221 Gets window's central widget
223 QWidget* Plot2d_ViewFrame::getViewWidget()
225 return (QWidget*)myPlot;
228 Actually this method just re-displays all curves which are presented in the viewer
230 void Plot2d_ViewFrame::DisplayAll()
232 QList<Plot2d_Curve> clist;
234 for ( int i = 0; i < (int)clist.count(); i++ ) {
235 updateCurve( clist.at( i ), false );
240 Removes all curves from the view
242 void Plot2d_ViewFrame::EraseAll()
249 Redraws viewframe contents
251 void Plot2d_ViewFrame::Repaint()
258 void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
260 if ( !prs || prs->IsNull() )
263 if (prs->isSecondY()) {
264 myPlot->enableAxis(QwtPlot::yRight, true);
268 myPlot->enableAxis(QwtPlot::yRight, false);
272 // display all curves from presentation
273 curveList aCurves = prs->getCurves();
274 displayCurves( aCurves );
275 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
276 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
277 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
283 void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
285 if ( !prs || prs->IsNull() )
288 // erase all curves from presentation
289 curveList aCurves = prs->getCurves();
290 eraseCurves( aCurves );
296 void Plot2d_ViewFrame::setTitle( const QString& title )
298 setTitle( myTitleEnabled, title, MainTitle, true );
302 Reads Plot2d view settings from the preferences
304 void Plot2d_ViewFrame::readPreferences()
306 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
308 myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
309 if ( myCurveType < 1 || myCurveType > 2 )
311 myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
312 myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
313 myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
314 myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
316 myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
317 myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
318 myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
319 myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
321 myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
322 myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
323 myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
325 myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
326 myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
327 myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
329 myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
330 myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
332 myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
334 myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
335 myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
337 myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
339 myXMode = resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode );
340 myXMode = QMAX( 0, QMIN( 1, myXMode ) );
342 myYMode = resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode );
343 myYMode = QMAX( 0, QMIN( 1, myYMode ) );
347 Writes Plot2d view settings to the preferences
349 void Plot2d_ViewFrame::writePreferences()
351 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
353 resMgr->setValue( "Plot2d", "CurveType", myCurveType );
354 resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
355 resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
356 resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
357 resMgr->setValue( "Plot2d", "Background", myBackground );
358 resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
359 resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
360 resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
362 resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
364 resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
365 resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
366 resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
367 resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
369 resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
370 resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
372 resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
373 resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
375 resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
379 resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
380 resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
381 resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
382 resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
385 resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
389 Prints mouse cursor coordinates into string
391 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt )
394 bool xFound = false, yFound = false;
395 double xCoord, yCoord;
396 const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
397 for ( i = 0; i < aXscale->majCnt(); i++ ) {
398 double majXmark = aXscale->majMark( i );
399 int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
400 if ( xmark-2 == pnt.x() ) {
407 for ( i = 0; i < aXscale->minCnt(); i++ ) {
408 double minXmark = aXscale->minMark( i );
409 int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
410 if ( xmark-2 == pnt.x() ) {
417 const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
418 for ( i = 0; i < aYscale->majCnt(); i++ ) {
419 double majYmark = aYscale->majMark( i );
420 int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
421 if ( ymark-2 == pnt.y() ) {
428 for ( i = 0; i < aYscale->minCnt(); i++ ) {
429 double minYmark = aYscale->minMark( i );
430 int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
431 if ( ymark-2 == pnt.y() ) {
439 QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
442 QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
448 bool yFound2 = false;
451 const QwtScaleDiv* aYscale2 = myPlot->axisScale( QwtPlot::yRight );
452 for ( i = 0; i < aYscale2->majCnt(); i++ ) {
453 double majYmark = aYscale2->majMark( i );
454 int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
455 if ( ymark-2 == pnt.y() ) {
462 for ( i = 0; i < aYscale2->minCnt(); i++ ) {
463 double minYmark = aYscale2->minMark( i );
464 int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
465 if ( ymark-2 == pnt.y() ) {
472 QString strY2 = QString::number( yFound2 ? yCoord2 :
473 myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).stripWhiteSpace();
476 info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
479 info = tr("INF_COORDINATES").arg( strX ).arg( strY );
485 Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
487 static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
489 QwtSymbol::Style ms = QwtSymbol::None;
491 case Plot2d_Curve::Circle:
492 ms = QwtSymbol::Ellipse; break;
493 case Plot2d_Curve::Rectangle:
494 ms = QwtSymbol::Rect; break;
495 case Plot2d_Curve::Diamond:
496 ms = QwtSymbol::Diamond; break;
497 case Plot2d_Curve::DTriangle:
498 ms = QwtSymbol::DTriangle; break;
499 case Plot2d_Curve::UTriangle:
500 ms = QwtSymbol::UTriangle; break;
501 case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
502 ms = QwtSymbol::RTriangle; break;
503 case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
504 ms = QwtSymbol::LTriangle; break;
505 case Plot2d_Curve::Cross:
506 ms = QwtSymbol::Cross; break;
507 case Plot2d_Curve::XCross:
508 ms = QwtSymbol::XCross; break;
509 case Plot2d_Curve::None:
511 ms = QwtSymbol::None; break;
517 Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
519 static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
521 Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;
523 case QwtSymbol::Ellipse:
524 ms = Plot2d_Curve::Circle; break;
525 case QwtSymbol::Rect:
526 ms = Plot2d_Curve::Rectangle; break;
527 case QwtSymbol::Diamond:
528 ms = Plot2d_Curve::Diamond; break;
529 case QwtSymbol::DTriangle:
530 ms = Plot2d_Curve::DTriangle; break;
531 case QwtSymbol::UTriangle:
532 ms = Plot2d_Curve::UTriangle; break;
533 case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
534 ms = Plot2d_Curve::LTriangle; break;
535 case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
536 ms = Plot2d_Curve::RTriangle; break;
537 case QwtSymbol::Cross:
538 ms = Plot2d_Curve::Cross; break;
539 case QwtSymbol::XCross:
540 ms = Plot2d_Curve::XCross; break;
541 case QwtSymbol::None:
543 ms = Plot2d_Curve::None; break;
549 Converts Plot2d_Curve's line style to Qwt line style [ static ]
551 static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
553 Qt::PenStyle ps = Qt::NoPen;
555 case Plot2d_Curve::Solid:
556 ps = Qt::SolidLine; break;
557 case Plot2d_Curve::Dash:
558 ps = Qt::DashLine; break;
559 case Plot2d_Curve::Dot:
560 ps = Qt::DotLine; break;
561 case Plot2d_Curve::DashDot:
562 ps = Qt::DashDotLine; break;
563 case Plot2d_Curve::DashDotDot:
564 ps = Qt::DashDotDotLine; break;
565 case Plot2d_Curve::NoPen:
567 ps = Qt::NoPen; break;
573 Converts Qwt line style to Plot2d_Curve's line style [ static ]
575 static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
577 Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
580 ps = Plot2d_Curve::Solid; break;
582 ps = Plot2d_Curve::Dash; break;
584 ps = Plot2d_Curve::Dot; break;
585 case Qt::DashDotLine:
586 ps = Plot2d_Curve::DashDot; break;
587 case Qt::DashDotDotLine:
588 ps = Plot2d_Curve::DashDotDot; break;
591 ps = Plot2d_Curve::NoPen; break;
599 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
603 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
604 // it crashes if switched to X/Y logarithmic mode, when one or more points have
605 // non-positive X/Y coordinate
606 if ( myXMode && curve->getMinX() <= 0. )
607 setHorScaleMode( 0, false );
608 if ( myYMode && curve->getMinY() <= 0. )
609 setVerScaleMode( 0, false );
612 if ( hasCurve( curve ) ) {
613 updateCurve( curve, update );
616 long curveKey = myPlot->insertCurve( curve->getVerTitle() );
617 myPlot->setCurveYAxis(curveKey, curve->getYAxis());
619 myCurves.insert( curveKey, curve );
620 if ( curve->isAutoAssign() ) {
621 QwtSymbol::Style typeMarker;
623 Qt::PenStyle typeLine;
624 myPlot->getNextMarker( typeMarker, color, typeLine );
625 myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
626 myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker,
629 QSize( myMarkerSize, myMarkerSize ) ) );
630 curve->setColor( color );
631 curve->setLine( qwt2plotLine( typeLine ) );
632 curve->setMarker( qwt2plotMarker( typeMarker ) );
635 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
636 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
637 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
638 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
639 QBrush( curve->getColor() ),
640 QPen( curve->getColor() ),
641 QSize( myMarkerSize, myMarkerSize ) ) );
643 if ( myCurveType == 0 )
644 myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
645 else if ( myCurveType == 1 )
646 myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
647 else if ( myCurveType == 2 )
648 myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
649 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
657 Adds curves into view
659 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
661 myPlot->setUpdatesEnabled( false );
662 QPtrListIterator<Plot2d_Curve> it(curves);
663 Plot2d_Curve* aCurve;
664 while( (aCurve = it.current()) ) {
665 displayCurve( aCurve, false );
670 myPlot->setUpdatesEnabled( true );
678 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
682 int curveKey = hasCurve( curve );
684 myPlot->removeCurve( curveKey );
685 myCurves.remove( curveKey );
694 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
696 QPtrListIterator<Plot2d_Curve> it(curves);
697 Plot2d_Curve* aCurve;
698 while( (aCurve = it.current()) ) {
699 eraseCurve( aCurve, false );
708 Updates curves attributes
710 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
714 int curveKey = hasCurve( curve );
716 if ( !curve->isAutoAssign() ) {
717 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
718 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
719 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
720 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
721 QBrush( curve->getColor() ),
722 QPen( curve->getColor() ),
723 QSize( myMarkerSize, myMarkerSize ) ) );
724 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
726 myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
727 myPlot->curve( curveKey )->setEnabled( true );
734 Returns curve key if is is displayed in the viewer and 0 otherwise
736 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
738 QIntDictIterator<Plot2d_Curve> it( myCurves );
739 for ( ; it.current(); ++it ) {
740 if ( it.current() == curve )
741 return it.currentKey();
747 Gets lsit of displayed curves
749 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
752 clist.setAutoDelete( false );
753 QIntDictIterator<Plot2d_Curve> it( myCurves );
754 for ( ; it.current(); ++it ) {
755 clist.append( it.current() );
757 return clist.count();
761 Returns true if the curve is visible
763 bool Plot2d_ViewFrame::isVisible( Plot2d_Curve* curve )
766 int key = hasCurve( curve );
768 return myPlot->curve( key )->enabled();
776 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
778 if ( !prs || prs->IsNull() )
780 curveList aCurves = prs->getCurves();
782 QPtrListIterator<Plot2d_Curve> it(aCurves);
783 Plot2d_Curve* aCurve;
784 while( (aCurve = it.current()) ) {
785 int curveKey = hasCurve( aCurve );
787 myPlot->setCurveTitle( curveKey, aCurve->getVerTitle() );
793 Fits the view to see all data
795 void Plot2d_ViewFrame::fitAll()
797 QwtDiMap xMap1 = myPlot->canvasMap( QwtPlot::xBottom );
799 myPlot->setAxisAutoScale( QwtPlot::yLeft );
800 myPlot->setAxisAutoScale( QwtPlot::xBottom );
804 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
805 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
807 myPlot->setAxisScale( QwtPlot::xBottom,
808 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
809 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() ) );
810 myPlot->setAxisScale( QwtPlot::yLeft,
811 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
812 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() ) );
815 myPlot->setAxisAutoScale( QwtPlot::yRight );
817 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
818 myPlot->setAxisScale( QwtPlot::yRight,
819 myPlot->invTransform( QwtPlot::yRight, yMap2.i1() ),
820 myPlot->invTransform( QwtPlot::yRight, yMap2.i2() ) );
826 Fits the view to rectangle area (pixels)
828 void Plot2d_ViewFrame::fitArea( const QRect& area )
830 QRect rect = area.normalize();
831 if ( rect.width() < MIN_RECT_SIZE ) {
832 rect.setWidth( MIN_RECT_SIZE );
833 rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
835 if ( rect.height() < MIN_RECT_SIZE ) {
836 rect.setHeight( MIN_RECT_SIZE );
837 rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
839 myPlot->setAxisScale( QwtPlot::yLeft,
840 myPlot->invTransform( QwtPlot::yLeft, rect.top() ),
841 myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
843 myPlot->setAxisScale( QwtPlot::yRight,
844 myPlot->invTransform( QwtPlot::yRight, rect.top() ),
845 myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
846 myPlot->setAxisScale( QwtPlot::xBottom,
847 myPlot->invTransform( QwtPlot::xBottom, rect.left() ),
848 myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
853 "Fit Data" command for TUI interface
855 void Plot2d_ViewFrame::fitData(const int mode,
856 const double xMin, const double xMax,
857 const double yMin, const double yMax,
858 double y2Min, double y2Max)
860 if ( mode == 0 || mode == 2 ) {
861 myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
863 myPlot->setAxisScale( QwtPlot::yRight, y2Max, y2Min );
865 if ( mode == 0 || mode == 1 )
866 myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax );
871 Gets current fit ranges for view frame
873 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
874 double& yMin, double& yMax,
875 double& y2Min, double& y2Max)
877 int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
878 int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
879 int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
880 int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
881 xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
882 xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
883 yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
884 yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
888 int iyMin = myPlot->canvasMap( QwtPlot::yRight ).i1();
889 int iyMax = myPlot->canvasMap( QwtPlot::yRight ).i2();
890 y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
891 y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
896 Tests if it is necessary to start operation on mouse action
898 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
900 int btn = me.button() | me.state();
901 const int zoomBtn = ControlButton | LeftButton;
902 const int panBtn = ControlButton | MidButton;
903 const int fitBtn = ControlButton | RightButton;
908 myPlot->canvas()->setCursor( zoomCursor );
911 myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
914 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
922 "Settings" toolbar action slot
924 void Plot2d_ViewFrame::onSettings()
926 #ifdef TEST_AUTOASSIGN
927 typedef QMap<int,int> IList;
928 typedef QMap<QString,int> SList;
931 cols[ "red-min" ] = 1000;
932 cols[ "red-max" ] = -1;
933 cols[ "green-min" ] = 1000;
934 cols[ "green-max" ] = -1;
935 cols[ "blue-min" ] = 1000;
936 cols[ "blue-max" ] = -1;
937 for ( unsigned i = 0; i < 10000; i++ ) {
938 QwtSymbol::Style typeMarker;
940 Qt::PenStyle typeLine;
941 myPlot->getNextMarker( typeMarker, color, typeLine );
942 if ( mars.contains(typeMarker) )
943 mars[ typeMarker ] = mars[ typeMarker ]+1;
945 mars[ typeMarker ] = 0;
946 if ( lins.contains(typeLine) )
947 lins[ typeLine ] = lins[ typeLine ]+1;
949 lins[ typeLine ] = 0;
950 if ( cols[ "red-max" ] < color.red() )
951 cols[ "red-max" ] = color.red();
952 if ( cols[ "red-min" ] > color.red() )
953 cols[ "red-min" ] = color.red();
954 if ( cols[ "green-max" ] < color.green() )
955 cols[ "green-max" ] = color.green();
956 if ( cols[ "green-min" ] > color.green() )
957 cols[ "green-min" ] = color.green();
958 if ( cols[ "blue-max" ] < color.blue() )
959 cols[ "blue-max" ] = color.blue();
960 if ( cols[ "blue-min" ] > color.blue() )
961 cols[ "blue-min" ] = color.blue();
965 Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
966 dlg->setMainTitle( myTitleEnabled, myTitle );
967 dlg->setXTitle( myXTitleEnabled, myXTitle );
968 dlg->setYTitle( myYTitleEnabled, myYTitle );
970 dlg->setY2Title( myY2TitleEnabled, myY2Title );
971 dlg->setCurveType( myCurveType );
972 dlg->setLegend( myShowLegend, myLegendPos );
973 dlg->setMarkerSize( myMarkerSize );
974 dlg->setBackgroundColor( myBackground );
975 dlg->setScaleMode(myXMode, myYMode);
977 dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
978 myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
979 myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
980 dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
981 myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
982 myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
983 if ( dlg->exec() == QDialog::Accepted ) {
984 // horizontal axis title
985 setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
986 // vertical left axis title
987 setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
988 if (mySecondY) // vertical right axis title
989 setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
992 setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
994 if ( myCurveType != dlg->getCurveType() ) {
995 setCurveType( dlg->getCurveType(), false );
998 if ( myShowLegend != dlg->isLegendEnabled() ) {
999 showLegend( dlg->isLegendEnabled(), false );
1001 if ( myLegendPos != dlg->getLegendPos() ) {
1002 setLegendPos( dlg->getLegendPos() );
1005 if ( myMarkerSize != dlg->getMarkerSize() ) {
1006 setMarkerSize( dlg->getMarkerSize(), false );
1009 if ( myBackground != dlg->getBackgroundColor() ) {
1010 setBackgroundColor( dlg->getBackgroundColor() );
1013 bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
1014 aY2GridMajorEnabled, aY2GridMinorEnabled;
1015 int aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
1016 aY2GridMaxMajor, aY2GridMaxMinor;
1017 dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
1018 aY2GridMajorEnabled, aY2GridMaxMajor);
1019 dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
1020 aY2GridMinorEnabled, aY2GridMaxMinor);
1021 setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1022 setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
1023 aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
1024 if ( myXMode != dlg->getXScaleMode() ) {
1025 setHorScaleMode( dlg->getXScaleMode() );
1027 if ( myYMode != dlg->getYScaleMode() ) {
1028 setVerScaleMode( dlg->getYScaleMode() );
1032 // update preferences
1033 if ( dlg->isSetAsDefault() )
1040 "Fit Data" command slot
1042 void Plot2d_ViewFrame::onFitData()
1044 Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
1045 double xMin,xMax,yMin,yMax,y2Min,y2Max;
1046 getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
1048 dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1049 if ( dlg->exec() == QDialog::Accepted ) {
1050 int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1051 fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
1057 Change background color
1059 void Plot2d_ViewFrame::onChangeBackground()
1061 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
1062 if ( selColor.isValid() ) {
1063 setBackgroundColor( selColor );
1070 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1072 myCurveType = curveType;
1073 QArray<long> keys = myPlot->curveKeys();
1074 for ( int i = 0; i < (int)keys.count(); i++ ) {
1075 if ( myCurveType == 0 )
1076 myPlot->setCurveStyle( keys[i], QwtCurve::Dots );//QwtCurve::NoCurve
1077 else if ( myCurveType == 1 )
1078 myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1079 else if ( myCurveType == 2 )
1080 myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1084 emit vpCurveChanged();
1087 void Plot2d_ViewFrame::setCurveTitle( int curveKey, const QString& title )
1089 if(myPlot) myPlot->setCurveTitle(curveKey, title);
1095 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1097 myShowLegend = show;
1098 myPlot->setAutoLegend( myShowLegend );
1099 myPlot->enableLegend( myShowLegend );
1105 Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1107 void Plot2d_ViewFrame::setLegendPos( int pos )
1112 myPlot->setLegendPos( Qwt::Left );
1115 myPlot->setLegendPos( Qwt::Right );
1118 myPlot->setLegendPos( Qwt::Top );
1121 myPlot->setLegendPos( Qwt::Bottom );
1127 Sets new marker size
1129 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1131 if ( myMarkerSize != size )
1133 myMarkerSize = size;
1134 QArray<long> keys = myPlot->curveKeys();
1135 for ( int i = 0; i < (int)keys.count(); i++ )
1137 QwtPlotCurve* crv = myPlot->curve( keys[i] );
1140 QwtSymbol aSymbol = crv->symbol();
1141 aSymbol.setSize( myMarkerSize, myMarkerSize );
1142 myPlot->setCurveSymbol( keys[i], aSymbol );
1151 Sets background color
1153 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1155 myBackground = color;
1156 //myPlot->setCanvasBackground( myBackground );
1157 myPlot->canvas()->setPalette( myBackground );
1158 myPlot->setPalette( myBackground );
1159 QPalette aPal = myPlot->getLegend()->palette();
1160 for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1161 QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1162 aPal.setColor( cg, QColorGroup::Base, myBackground );
1163 aPal.setColor( cg, QColorGroup::Background, myBackground );
1165 myPlot->getLegend()->setPalette( aPal );
1169 Gets background color
1171 QColor Plot2d_ViewFrame::backgroundColor() const
1173 return myBackground;
1176 Sets hor.axis grid parameters
1178 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
1179 bool xMinorEnabled, const int xMinorMax,
1182 myXGridMajorEnabled = xMajorEnabled;
1183 myXGridMinorEnabled = xMinorEnabled;
1184 myXGridMaxMajor = xMajorMax;
1185 myXGridMaxMinor = xMinorMax;
1186 myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1187 myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1188 myPlot->setGridXAxis(QwtPlot::xBottom);
1189 myPlot->enableGridX( myXGridMajorEnabled );
1190 myPlot->enableGridXMin( myXGridMinorEnabled );
1195 Sets ver.axis grid parameters
1197 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
1198 bool yMinorEnabled, const int yMinorMax,
1199 bool y2MajorEnabled, const int y2MajorMax,
1200 bool y2MinorEnabled, const int y2MinorMax,
1203 myYGridMajorEnabled = yMajorEnabled;
1204 myYGridMinorEnabled = yMinorEnabled;
1205 myYGridMaxMajor = yMajorMax;
1206 myYGridMaxMinor = yMinorMax;
1209 myY2GridMajorEnabled = y2MajorEnabled;
1210 myY2GridMinorEnabled = y2MinorEnabled;
1211 myY2GridMaxMajor = y2MajorMax;
1212 myY2GridMaxMinor = y2MinorMax;
1214 myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1215 myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1218 myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
1219 myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
1222 myPlot->setGridYAxis(QwtPlot::yLeft);
1225 if (myYGridMajorEnabled) {
1226 myPlot->enableGridYMin(myYGridMinorEnabled);
1227 myPlot->enableGridY( myYGridMajorEnabled);
1229 else if (myY2GridMajorEnabled) {
1230 myPlot->setGridYAxis(QwtPlot::yRight);
1231 myPlot->enableGridYMin(myY2GridMinorEnabled);
1232 myPlot->enableGridY(myY2GridMajorEnabled);
1235 myPlot->enableGridYMin(false);
1236 myPlot->enableGridY(false);
1240 myPlot->enableGridY( myYGridMajorEnabled );
1241 myPlot->enableGridYMin( myYGridMinorEnabled );
1248 Sets title for some axis
1250 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
1251 ObjectType type, bool update )
1255 myTitleEnabled = enabled;
1257 myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1260 myXTitleEnabled = enabled;
1262 myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1265 myYTitleEnabled = enabled;
1267 myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1270 myY2TitleEnabled = enabled;
1272 myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString::null );
1279 Sets title for some axis
1281 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
1286 title = myTitle; break;
1288 title = myXTitle; break;
1290 title = myYTitle; break;
1292 title = myY2Title; break;
1297 Sets font for Plot2d object : title or axis
1299 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
1303 myPlot->setTitleFont(font);
1306 myPlot->setAxisTitleFont(QwtPlot::xBottom, font); break;
1308 myPlot->setAxisTitleFont(QwtPlot::yLeft, font); break;
1310 myPlot->setAxisTitleFont(QwtPlot::yRight, font); break;
1312 myPlot->setAxisFont(QwtPlot::xBottom, font); break;
1314 myPlot->setAxisFont(QwtPlot::yLeft, font); break;
1316 myPlot->setAxisFont(QwtPlot::yRight, font); break;
1322 Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1324 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1326 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1327 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1328 // non-positive X/Y coordinate
1329 if ( mode && !isXLogEnabled() ){
1330 SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"), tr("BUT_OK"));
1335 if ( myXMode == 0 ) // linear
1336 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1338 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
1342 emit vpModeHorChanged();
1345 Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1347 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1349 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1350 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1351 // non-positive X/Y coordinate
1352 if ( mode && !isYLogEnabled() ){
1353 SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"), tr("BUT_OK"));
1358 if ( myYMode == 0 ) { // linear
1359 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1361 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1363 else { // logarithmic
1364 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
1366 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, true );
1370 emit vpModeVerChanged();
1374 Return, scale mode for horizontal axis
1376 bool Plot2d_ViewFrame::isModeHorLinear()
1378 return (myXMode == 0 ? true : false);
1382 Return, scale mode for vertical axis
1384 bool Plot2d_ViewFrame::isModeVerLinear()
1386 return (myYMode == 0 ? true : false);
1389 Slot, called when user presses mouse button
1391 void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
1393 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1395 aParent->putInfo(getInfo(me.pos()));
1396 if ( myOperation == NoOpId )
1397 myOperation = testOperation( me );
1398 if ( myOperation != NoOpId ) {
1400 if ( myOperation == FitAreaId ) {
1401 myPlot->setOutlineStyle( Qwt::Rect );
1403 else if ( myOperation == GlPanId ) {
1404 myPlot->setAxisScale( QwtPlot::yLeft,
1405 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2,
1406 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1407 myPlot->setAxisScale( QwtPlot::xBottom,
1408 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
1409 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1411 myPlot->setAxisScale( QwtPlot::yRight,
1412 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2,
1413 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1418 int btn = me.button() | me.state();
1419 if (btn == RightButton) {
1420 QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1421 me.pos(), btn, me.state());
1422 // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1423 parent()->eventFilter(this, aEvent);
1428 Slot, called when user moves mouse
1430 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1432 int dx = me.pos().x() - myPnt.x();
1433 int dy = me.pos().y() - myPnt.y();
1435 if ( myOperation != NoOpId) {
1436 if ( myOperation == ZoomId ) {
1437 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1438 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1440 myPlot->setAxisScale( QwtPlot::yLeft,
1441 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1442 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1443 myPlot->setAxisScale( QwtPlot::xBottom,
1444 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1445 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1447 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1448 myPlot->setAxisScale( QwtPlot::yRight,
1449 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1450 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1455 else if ( myOperation == PanId ) {
1456 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1457 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1459 myPlot->setAxisScale( QwtPlot::yLeft,
1460 myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ),
1461 myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1462 myPlot->setAxisScale( QwtPlot::xBottom,
1463 myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1464 myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) );
1466 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1467 myPlot->setAxisScale( QwtPlot::yRight,
1468 myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ),
1469 myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1476 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1478 aParent->putInfo(getInfo(me.pos()));
1482 Slot, called when user releases mouse
1484 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1486 if ( myOperation == NoOpId && me.button() == RightButton )
1488 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1489 me.pos(), me.globalPos(),
1491 emit contextMenuRequested( &aEvent );
1493 if ( myOperation == FitAreaId ) {
1494 QRect rect( myPnt, me.pos() );
1497 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1498 myPlot->setOutlineStyle( Qwt::Triangle );
1500 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1502 aParent->putInfo(tr("INF_READY"));
1503 myOperation = NoOpId;
1506 Slot, called when user wheeling mouse
1508 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1510 double aDelta = event->delta();
1511 double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
1513 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1514 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1516 myPlot->setAxisScale( QwtPlot::yLeft,
1517 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1518 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1519 myPlot->setAxisScale( QwtPlot::xBottom,
1520 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1521 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1523 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1524 myPlot->setAxisScale( QwtPlot::yRight,
1525 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1526 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1529 myPnt = event->pos();
1532 View operations : Pan view
1534 void Plot2d_ViewFrame::onViewPan()
1536 myPlot->canvas()->setCursor( panCursor );
1537 myOperation = PanId;
1538 qApp->installEventFilter( this );
1541 View operations : Zoom view
1543 void Plot2d_ViewFrame::onViewZoom()
1545 myPlot->canvas()->setCursor( zoomCursor );
1546 myOperation = ZoomId;
1547 qApp->installEventFilter( this );
1550 View operations : Fot All
1552 void Plot2d_ViewFrame::onViewFitAll()
1557 View operations : Fit Area
1559 void Plot2d_ViewFrame::onViewFitArea()
1561 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1562 myOperation = FitAreaId;
1563 qApp->installEventFilter( this );
1566 View operations : Global panning
1568 void Plot2d_ViewFrame::onViewGlobalPan()
1570 myPlot->canvas()->setCursor( glPanCursor );
1571 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1572 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1574 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1576 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1577 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1579 myXDistance = xMap.d2() - xMap.d1();
1580 myYDistance = yMap.d2() - yMap.d1();
1583 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1584 myYDistance2 = yMap2.d2() - yMap2.d1();
1587 myOperation = GlPanId;
1588 qApp->installEventFilter( this );
1592 Precaution for logarithmic X scale
1594 bool Plot2d_ViewFrame::isXLogEnabled() const
1596 bool allPositive = true;
1597 QIntDictIterator<Plot2d_Curve> it( myCurves );
1598 for ( ; allPositive && it.current(); ++it ) {
1599 allPositive = ( it.current()->getMinX() > 0. );
1605 Precaution for logarithmic Y scale
1607 bool Plot2d_ViewFrame::isYLogEnabled() const
1609 bool allPositive = true;
1610 QIntDictIterator<Plot2d_Curve> it( myCurves );
1611 for ( ; allPositive && it.current(); ++it ) {
1612 allPositive = ( it.current()->getMinY() > 0. );
1617 //=================================================================================
1618 // Plot2d_Plot2d implementation
1619 //=================================================================================
1623 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1627 enableOutline( true );
1628 setOutlineStyle( Qwt::Triangle );
1629 setOutlinePen( green );
1631 setAutoLegend( false );
1632 setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1633 enableLegend( false );
1635 enableGridX( false );
1636 enableGridXMin( false );
1637 enableGridY( false );
1638 enableGridYMin( false );
1639 // auto scaling by default
1640 setAxisAutoScale( QwtPlot::yLeft );
1641 setAxisAutoScale( QwtPlot::yRight );
1642 setAxisAutoScale( QwtPlot::xBottom );
1645 Recalculates and redraws Plot 2d view
1647 void Plot2d_Plot2d::replot()
1649 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
1654 Checks if two colors are close to each other [ static ]
1655 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1657 const long COLOR_DISTANCE = 100;
1658 const int MAX_ATTEMPTS = 10;
1659 static bool closeColors( const QColor& color1, const QColor& color2 )
1661 long tol = abs( color2.red() - color1.red() ) +
1662 abs( color2.green() - color1.green() ) +
1663 abs( color2.blue() - color1.blue() );
1665 return ( tol <= COLOR_DISTANCE );
1668 Gets new unique marker for item if possible
1670 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine )
1675 int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color
1676 int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ...
1677 int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ...
1678 int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1; // 9 markers types ( not including empty )
1679 int aLine = (int)( 5.0 * rand() / RAND_MAX) + 1; // 5 line types ( not including empty )
1681 typeMarker = ( QwtSymbol::Style )aMarker;
1682 color = QColor( aRed, aGreen, aBlue );
1683 typeLine = ( Qt::PenStyle )aLine;
1686 if ( cnt == MAX_ATTEMPTS )
1689 bOk = !existMarker( typeMarker, color, typeLine );
1692 static int aMarker = -1;
1693 static int aColor = -1;
1694 static int aLine = -1;
1696 if ( myColors.isEmpty() ) {
1697 // creating colors list
1698 myColors.append( Qt::white );
1699 myColors.append( Qt::blue );
1700 myColors.append( Qt::gray );
1701 myColors.append( Qt::darkGreen );
1702 myColors.append( Qt::magenta );
1703 myColors.append( Qt::darkGray );
1704 myColors.append( Qt::red );
1705 myColors.append( Qt::darkBlue );
1706 myColors.append( Qt::darkYellow );
1707 myColors.append( Qt::cyan );
1708 myColors.append( Qt::darkRed );
1709 myColors.append( Qt::darkCyan );
1710 myColors.append( Qt::yellow );
1711 myColors.append( Qt::darkMagenta );
1712 myColors.append( Qt::green );
1713 myColors.append( Qt::black );
1716 int nbMarkers = 11; // QwtSymbol supports 11 marker types
1717 int nbLines = 6; // Qt supports 6 line types
1718 int nbColors = myColors.count(); // number of default colors supported
1720 aMarker = ( aMarker + 1 ) % nbMarkers;
1721 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1722 aColor = ( aColor + 1 ) % nbColors;
1723 aLine = ( aLine + 1 ) % nbLines;
1724 if ( aLine == Qt::NoPen ) aLine++;
1726 typeMarker = ( QwtSymbol::Style )aMarker;
1727 color = myColors[ aColor ];
1728 typeLine = ( Qt::PenStyle )aLine;
1729 if ( !existMarker( typeMarker, color, typeLine ) )
1733 for ( i = 0; i < nbMarkers; i++ ) {
1734 aMarker = ( aMarker + 1 ) % nbMarkers;
1735 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1736 for ( j = 0; j < nbColors; j++ ) {
1737 aColor = ( aColor + 1 ) % nbColors;
1738 for ( k = 0; k < nbLines; k++ ) {
1739 aLine = ( aLine + 1 ) % nbLines;
1740 if ( aLine == Qt::NoPen ) aLine++;
1741 if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1742 typeMarker = ( QwtSymbol::Style )aMarker;
1743 color = myColors[ aColor ];
1744 typeLine = ( Qt::PenStyle )aLine;
1753 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1755 return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1758 QSize Plot2d_Plot2d::sizeHint() const
1760 return QwtPlot::minimumSizeHint();
1764 return minimum size for qwt plot
1766 QSize Plot2d_Plot2d::minimumSizeHint() const
1768 return QSize( 0, 0 );
1769 // QSize aSize = QwtPlot::minimumSizeHint();
1770 // return QSize(aSize.width()*3/4, aSize.height());
1773 Checks if marker belongs to any enitity
1775 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine )
1777 // getting all curves
1778 QArray<long> keys = curveKeys();
1781 if ( closeColors( color, backgroundColor() ) )
1783 for ( int i = 0; i < (int)keys.count(); i++ )
1785 QwtPlotCurve* crv = curve( keys[i] );
1787 QwtSymbol::Style aStyle = crv->symbol().style();
1788 QColor aColor = crv->pen().color();
1789 Qt::PenStyle aLine = crv->pen().style();
1790 // if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1791 if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1798 // TEMPORARY SOLUTION!!! TO BE IMPLEMENTED!!!
1799 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1804 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1809 myCurveType = vf->myCurveType;
1810 myShowLegend = vf->myShowLegend;
1811 myLegendPos = vf->myLegendPos;
1812 myMarkerSize = vf->myMarkerSize;
1813 myBackground = vf->myBackground;
1814 myTitle = vf->myTitle;
1815 myXTitle = vf->myXTitle;
1816 myYTitle = vf->myYTitle;
1817 myY2Title = vf->myY2Title;
1818 myTitleEnabled = vf->myTitleEnabled;
1819 myXTitleEnabled = vf->myXTitleEnabled;
1820 myYTitleEnabled = vf->myYTitleEnabled;
1821 myY2TitleEnabled = vf->myY2TitleEnabled;
1822 myXGridMajorEnabled = vf->myXGridMajorEnabled;
1823 myYGridMajorEnabled = vf->myYGridMajorEnabled;
1824 myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1825 myXGridMinorEnabled = vf->myXGridMinorEnabled;
1826 myYGridMinorEnabled = vf->myYGridMinorEnabled;
1827 myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1828 myXGridMaxMajor = vf->myXGridMaxMajor;
1829 myYGridMaxMajor = vf->myYGridMaxMajor;
1830 myY2GridMaxMajor = vf->myY2GridMaxMajor;
1831 myXGridMaxMinor = vf->myXGridMaxMinor;
1832 myYGridMaxMinor = vf->myYGridMaxMinor;
1833 myY2GridMaxMinor = vf->myY2GridMaxMinor;
1834 myXMode = vf->myXMode;
1835 myYMode = vf->myYMode;
1836 mySecondY = vf->mySecondY;
1840 Updates titles according to curves
1842 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1843 void Plot2d_ViewFrame::updateTitles()
1845 QIntDictIterator<Plot2d_Curve> it( myCurves );
1846 QStringList aXTitles;
1847 QStringList aYTitles;
1848 QStringList aXUnits;
1849 QStringList aYUnits;
1850 QStringList aTables;
1852 while ( it.current() ) {
1853 // collect titles and units from all curves...
1854 QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1855 QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1856 QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1857 QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1859 aYTitles.append( yTitle );
1860 if ( aXTitles.find( xTitle ) == aXTitles.end() )
1861 aXTitles.append( xTitle );
1862 if ( aXUnits.find( xUnits ) == aXUnits.end() )
1863 aXUnits.append( xUnits );
1864 if ( aYUnits.find( yUnits ) == aYUnits.end() )
1865 aYUnits.append( yUnits );
1867 QString aName = it.current()->getTableTitle();
1868 if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1869 aTables.append( aName );
1874 // ... and update plot 2d view
1875 QString xUnits, yUnits;
1876 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1877 xUnits = BRACKETIZE( aXUnits[0] );
1878 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1879 yUnits = BRACKETIZE( aYUnits[0] );
1880 QString xTitle, yTitle;
1881 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1882 xTitle = aXTitles[0];
1883 if ( aYTitles.count() == 1 )
1884 yTitle = aYTitles[0];
1886 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1888 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1891 setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1892 setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1893 setTitle( true, aTables.join("; "), MainTitle, true );
1896 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
1905 QPaintDevice* pd = 0;
1908 QPrinter* pr = new QPrinter( QPrinter::HighResolution );
1909 pr->setPageSize( QPrinter::A4 );
1910 pr->setOutputToFile( true );
1911 pr->setOutputFileName( file );
1912 pr->setPrintProgram( "" );
1918 myPlot->print( *pd );