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*)parent())->putInfo(getInfo(me.pos()));
1394 if ( myOperation == NoOpId )
1395 myOperation = testOperation( me );
1396 if ( myOperation != NoOpId ) {
1398 if ( myOperation == FitAreaId ) {
1399 myPlot->setOutlineStyle( Qwt::Rect );
1401 else if ( myOperation == GlPanId ) {
1402 myPlot->setAxisScale( QwtPlot::yLeft,
1403 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2,
1404 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1405 myPlot->setAxisScale( QwtPlot::xBottom,
1406 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
1407 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1409 myPlot->setAxisScale( QwtPlot::yRight,
1410 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2,
1411 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1416 int btn = me.button() | me.state();
1417 if (btn == RightButton) {
1418 QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1419 me.pos(), btn, me.state());
1420 // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1421 parent()->eventFilter(this, aEvent);
1426 Slot, called when user moves mouse
1428 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1430 int dx = me.pos().x() - myPnt.x();
1431 int dy = me.pos().y() - myPnt.y();
1433 if ( myOperation != NoOpId) {
1434 if ( myOperation == ZoomId ) {
1435 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1436 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1438 myPlot->setAxisScale( QwtPlot::yLeft,
1439 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1440 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1441 myPlot->setAxisScale( QwtPlot::xBottom,
1442 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1443 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1445 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1446 myPlot->setAxisScale( QwtPlot::yRight,
1447 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1448 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1453 else if ( myOperation == PanId ) {
1454 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1455 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1457 myPlot->setAxisScale( QwtPlot::yLeft,
1458 myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ),
1459 myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1460 myPlot->setAxisScale( QwtPlot::xBottom,
1461 myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1462 myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) );
1464 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1465 myPlot->setAxisScale( QwtPlot::yRight,
1466 myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ),
1467 myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1474 ((Plot2d_ViewWindow*)parent())->putInfo(getInfo(me.pos()));
1478 Slot, called when user releases mouse
1480 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1482 if ( myOperation == NoOpId && me.button() == RightButton )
1484 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1485 me.pos(), me.globalPos(),
1487 emit contextMenuRequested( &aEvent );
1489 if ( myOperation == FitAreaId ) {
1490 QRect rect( myPnt, me.pos() );
1493 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1494 myPlot->setOutlineStyle( Qwt::Triangle );
1496 ((Plot2d_ViewWindow*)parent())->putInfo(tr("INF_READY"));
1497 myOperation = NoOpId;
1500 Slot, called when user wheeling mouse
1502 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1504 double aDelta = event->delta();
1505 double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
1507 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1508 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1510 myPlot->setAxisScale( QwtPlot::yLeft,
1511 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1512 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1513 myPlot->setAxisScale( QwtPlot::xBottom,
1514 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1515 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1517 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1518 myPlot->setAxisScale( QwtPlot::yRight,
1519 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1520 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1523 myPnt = event->pos();
1526 View operations : Pan view
1528 void Plot2d_ViewFrame::onViewPan()
1530 myPlot->canvas()->setCursor( panCursor );
1531 myOperation = PanId;
1532 qApp->installEventFilter( this );
1535 View operations : Zoom view
1537 void Plot2d_ViewFrame::onViewZoom()
1539 myPlot->canvas()->setCursor( zoomCursor );
1540 myOperation = ZoomId;
1541 qApp->installEventFilter( this );
1544 View operations : Fot All
1546 void Plot2d_ViewFrame::onViewFitAll()
1551 View operations : Fit Area
1553 void Plot2d_ViewFrame::onViewFitArea()
1555 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1556 myOperation = FitAreaId;
1557 qApp->installEventFilter( this );
1560 View operations : Global panning
1562 void Plot2d_ViewFrame::onViewGlobalPan()
1564 myPlot->canvas()->setCursor( glPanCursor );
1565 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1566 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1568 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1570 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1571 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1573 myXDistance = xMap.d2() - xMap.d1();
1574 myYDistance = yMap.d2() - yMap.d1();
1577 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1578 myYDistance2 = yMap2.d2() - yMap2.d1();
1581 myOperation = GlPanId;
1582 qApp->installEventFilter( this );
1586 Precaution for logarithmic X scale
1588 bool Plot2d_ViewFrame::isXLogEnabled() const
1590 bool allPositive = true;
1591 QIntDictIterator<Plot2d_Curve> it( myCurves );
1592 for ( ; allPositive && it.current(); ++it ) {
1593 allPositive = ( it.current()->getMinX() > 0. );
1599 Precaution for logarithmic Y scale
1601 bool Plot2d_ViewFrame::isYLogEnabled() const
1603 bool allPositive = true;
1604 QIntDictIterator<Plot2d_Curve> it( myCurves );
1605 for ( ; allPositive && it.current(); ++it ) {
1606 allPositive = ( it.current()->getMinY() > 0. );
1611 //=================================================================================
1612 // Plot2d_Plot2d implementation
1613 //=================================================================================
1617 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1621 enableOutline( true );
1622 setOutlineStyle( Qwt::Triangle );
1623 setOutlinePen( green );
1625 setAutoLegend( false );
1626 setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1627 enableLegend( false );
1629 enableGridX( false );
1630 enableGridXMin( false );
1631 enableGridY( false );
1632 enableGridYMin( false );
1633 // auto scaling by default
1634 setAxisAutoScale( QwtPlot::yLeft );
1635 setAxisAutoScale( QwtPlot::yRight );
1636 setAxisAutoScale( QwtPlot::xBottom );
1639 Recalculates and redraws Plot 2d view
1641 void Plot2d_Plot2d::replot()
1643 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
1648 Checks if two colors are close to each other [ static ]
1649 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1651 const long COLOR_DISTANCE = 100;
1652 const int MAX_ATTEMPTS = 10;
1653 static bool closeColors( const QColor& color1, const QColor& color2 )
1655 long tol = abs( color2.red() - color1.red() ) +
1656 abs( color2.green() - color1.green() ) +
1657 abs( color2.blue() - color1.blue() );
1659 return ( tol <= COLOR_DISTANCE );
1662 Gets new unique marker for item if possible
1664 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine )
1669 int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color
1670 int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ...
1671 int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ...
1672 int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1; // 9 markers types ( not including empty )
1673 int aLine = (int)( 5.0 * rand() / RAND_MAX) + 1; // 5 line types ( not including empty )
1675 typeMarker = ( QwtSymbol::Style )aMarker;
1676 color = QColor( aRed, aGreen, aBlue );
1677 typeLine = ( Qt::PenStyle )aLine;
1680 if ( cnt == MAX_ATTEMPTS )
1683 bOk = !existMarker( typeMarker, color, typeLine );
1686 static int aMarker = -1;
1687 static int aColor = -1;
1688 static int aLine = -1;
1690 if ( myColors.isEmpty() ) {
1691 // creating colors list
1692 myColors.append( Qt::white );
1693 myColors.append( Qt::blue );
1694 myColors.append( Qt::gray );
1695 myColors.append( Qt::darkGreen );
1696 myColors.append( Qt::magenta );
1697 myColors.append( Qt::darkGray );
1698 myColors.append( Qt::red );
1699 myColors.append( Qt::darkBlue );
1700 myColors.append( Qt::darkYellow );
1701 myColors.append( Qt::cyan );
1702 myColors.append( Qt::darkRed );
1703 myColors.append( Qt::darkCyan );
1704 myColors.append( Qt::yellow );
1705 myColors.append( Qt::darkMagenta );
1706 myColors.append( Qt::green );
1707 myColors.append( Qt::black );
1710 int nbMarkers = 11; // QwtSymbol supports 11 marker types
1711 int nbLines = 6; // Qt supports 6 line types
1712 int nbColors = myColors.count(); // number of default colors supported
1714 aMarker = ( aMarker + 1 ) % nbMarkers;
1715 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1716 aColor = ( aColor + 1 ) % nbColors;
1717 aLine = ( aLine + 1 ) % nbLines;
1718 if ( aLine == Qt::NoPen ) aLine++;
1720 typeMarker = ( QwtSymbol::Style )aMarker;
1721 color = myColors[ aColor ];
1722 typeLine = ( Qt::PenStyle )aLine;
1723 if ( !existMarker( typeMarker, color, typeLine ) )
1727 for ( i = 0; i < nbMarkers; i++ ) {
1728 aMarker = ( aMarker + 1 ) % nbMarkers;
1729 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1730 for ( j = 0; j < nbColors; j++ ) {
1731 aColor = ( aColor + 1 ) % nbColors;
1732 for ( k = 0; k < nbLines; k++ ) {
1733 aLine = ( aLine + 1 ) % nbLines;
1734 if ( aLine == Qt::NoPen ) aLine++;
1735 if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1736 typeMarker = ( QwtSymbol::Style )aMarker;
1737 color = myColors[ aColor ];
1738 typeLine = ( Qt::PenStyle )aLine;
1747 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1749 return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1752 QSize Plot2d_Plot2d::sizeHint() const
1754 return QwtPlot::minimumSizeHint();
1758 return minimum size for qwt plot
1760 QSize Plot2d_Plot2d::minimumSizeHint() const
1762 return QSize( 0, 0 );
1763 // QSize aSize = QwtPlot::minimumSizeHint();
1764 // return QSize(aSize.width()*3/4, aSize.height());
1767 Checks if marker belongs to any enitity
1769 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine )
1771 // getting all curves
1772 QArray<long> keys = curveKeys();
1775 if ( closeColors( color, backgroundColor() ) )
1777 for ( int i = 0; i < (int)keys.count(); i++ )
1779 QwtPlotCurve* crv = curve( keys[i] );
1781 QwtSymbol::Style aStyle = crv->symbol().style();
1782 QColor aColor = crv->pen().color();
1783 Qt::PenStyle aLine = crv->pen().style();
1784 // if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1785 if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1792 // TEMPORARY SOLUTION!!! TO BE IMPLEMENTED!!!
1793 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1798 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1803 myCurveType = vf->myCurveType;
1804 myShowLegend = vf->myShowLegend;
1805 myLegendPos = vf->myLegendPos;
1806 myMarkerSize = vf->myMarkerSize;
1807 myBackground = vf->myBackground;
1808 myTitle = vf->myTitle;
1809 myXTitle = vf->myXTitle;
1810 myYTitle = vf->myYTitle;
1811 myY2Title = vf->myY2Title;
1812 myTitleEnabled = vf->myTitleEnabled;
1813 myXTitleEnabled = vf->myXTitleEnabled;
1814 myYTitleEnabled = vf->myYTitleEnabled;
1815 myY2TitleEnabled = vf->myY2TitleEnabled;
1816 myXGridMajorEnabled = vf->myXGridMajorEnabled;
1817 myYGridMajorEnabled = vf->myYGridMajorEnabled;
1818 myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1819 myXGridMinorEnabled = vf->myXGridMinorEnabled;
1820 myYGridMinorEnabled = vf->myYGridMinorEnabled;
1821 myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1822 myXGridMaxMajor = vf->myXGridMaxMajor;
1823 myYGridMaxMajor = vf->myYGridMaxMajor;
1824 myY2GridMaxMajor = vf->myY2GridMaxMajor;
1825 myXGridMaxMinor = vf->myXGridMaxMinor;
1826 myYGridMaxMinor = vf->myYGridMaxMinor;
1827 myY2GridMaxMinor = vf->myY2GridMaxMinor;
1828 myXMode = vf->myXMode;
1829 myYMode = vf->myYMode;
1830 mySecondY = vf->mySecondY;
1834 Updates titles according to curves
1836 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1837 void Plot2d_ViewFrame::updateTitles()
1839 QIntDictIterator<Plot2d_Curve> it( myCurves );
1840 QStringList aXTitles;
1841 QStringList aYTitles;
1842 QStringList aXUnits;
1843 QStringList aYUnits;
1844 QStringList aTables;
1846 while ( it.current() ) {
1847 // collect titles and units from all curves...
1848 QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1849 QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1850 QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1851 QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1853 aYTitles.append( yTitle );
1854 if ( aXTitles.find( xTitle ) == aXTitles.end() )
1855 aXTitles.append( xTitle );
1856 if ( aXUnits.find( xUnits ) == aXUnits.end() )
1857 aXUnits.append( xUnits );
1858 if ( aYUnits.find( yUnits ) == aYUnits.end() )
1859 aYUnits.append( yUnits );
1861 QString aName = it.current()->getTableTitle();
1862 if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1863 aTables.append( aName );
1868 // ... and update plot 2d view
1869 QString xUnits, yUnits;
1870 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1871 xUnits = BRACKETIZE( aXUnits[0] );
1872 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1873 yUnits = BRACKETIZE( aYUnits[0] );
1874 QString xTitle, yTitle;
1875 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1876 xTitle = aXTitles[0];
1877 if ( aYTitles.count() == 1 )
1878 yTitle = aYTitles[0];
1880 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1882 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1885 setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1886 setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1887 setTitle( true, aTables.join("; "), MainTitle, true );
1890 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
1899 QPaintDevice* pd = 0;
1902 QPrinter* pr = new QPrinter( QPrinter::HighResolution );
1903 pr->setPageSize( QPrinter::A4 );
1904 pr->setOutputToFile( true );
1905 pr->setOutputFileName( file );
1906 pr->setPrintProgram( "" );
1912 myPlot->print( *pd );