From 559e36577f76a589bac96fcc050f2845c08e77fb Mon Sep 17 00:00:00 2001 From: vsr Date: Sun, 16 Jan 2011 19:33:55 +0000 Subject: [PATCH] Add histogram items to the Plot2d viewer --- src/Plot2d/Makefile.am | 7 + src/Plot2d/Plot2d_Curve.cxx | 422 ++++--------- src/Plot2d/Plot2d_Curve.h | 111 +--- src/Plot2d/Plot2d_Histogram.cxx | 256 ++++++++ src/Plot2d/Plot2d_Histogram.h | 68 ++ src/Plot2d/Plot2d_Object.cxx | 486 ++++++++++++++ src/Plot2d/Plot2d_Object.h | 128 ++++ src/Plot2d/Plot2d_PlotItems.cxx | 628 ++++++++++++++++++ src/Plot2d/Plot2d_PlotItems.h | 146 +++++ src/Plot2d/Plot2d_Prs.cxx | 23 +- src/Plot2d/Plot2d_Prs.h | 22 +- src/Plot2d/Plot2d_ToolTip.cxx | 14 +- src/Plot2d/Plot2d_ToolTip.h | 11 +- src/Plot2d/Plot2d_ViewFrame.cxx | 874 ++++++++++++-------------- src/Plot2d/Plot2d_ViewFrame.h | 329 +++++----- src/Plot2d/Plot2d_ViewManager.cxx | 78 +++ src/Plot2d/Plot2d_ViewManager.h | 3 + src/Plot2d/Plot2d_ViewModel.cxx | 7 +- src/Plot2d/Plot2d_ViewModel.h | 2 +- src/Plot2d/Plot2d_ViewWindow.cxx | 184 +++++- src/Plot2d/Plot2d_ViewWindow.h | 10 +- src/Plot2d/resources/Plot2d_images.ts | 4 + src/Plot2d/resources/Plot2d_msg_en.ts | 76 +++ src/Plot2d/resources/plot2d_print.png | Bin 0 -> 233 bytes 24 files changed, 2812 insertions(+), 1077 deletions(-) create mode 100644 src/Plot2d/Plot2d_Histogram.cxx create mode 100644 src/Plot2d/Plot2d_Histogram.h create mode 100755 src/Plot2d/Plot2d_Object.cxx create mode 100755 src/Plot2d/Plot2d_Object.h create mode 100644 src/Plot2d/Plot2d_PlotItems.cxx create mode 100644 src/Plot2d/Plot2d_PlotItems.h create mode 100755 src/Plot2d/resources/plot2d_print.png diff --git a/src/Plot2d/Makefile.am b/src/Plot2d/Makefile.am index 8cb2b6e21..fd15389e1 100755 --- a/src/Plot2d/Makefile.am +++ b/src/Plot2d/Makefile.am @@ -32,7 +32,10 @@ lib_LTLIBRARIES = libPlot2d.la # header files salomeinclude_HEADERS = \ Plot2d.h \ + Plot2d_PlotItems.h \ + Plot2d_Object.h \ Plot2d_Curve.h \ + Plot2d_Histogram.h \ Plot2d_FitDataDlg.h \ Plot2d_Prs.h \ Plot2d_SetupViewDlg.h \ @@ -45,7 +48,10 @@ salomeinclude_HEADERS = \ dist_libPlot2d_la_SOURCES = \ Plot2d.cxx \ + Plot2d_PlotItems.cxx \ + Plot2d_Object.cxx \ Plot2d_Curve.cxx \ + Plot2d_Histogram.cxx \ Plot2d_FitDataDlg.cxx \ Plot2d_Prs.cxx \ Plot2d_SetupViewDlg.cxx \ @@ -81,6 +87,7 @@ dist_salomeres_DATA = \ resources/plot2d_log_y.png \ resources/plot2d_pan.png \ resources/plot2d_points.png \ + resources/plot2d_print.png \ resources/plot2d_settings.png \ resources/plot2d_splines.png \ resources/plot2d_zoom.png diff --git a/src/Plot2d/Plot2d_Curve.cxx b/src/Plot2d/Plot2d_Curve.cxx index aed76a81e..5b48d5eec 100755 --- a/src/Plot2d/Plot2d_Curve.cxx +++ b/src/Plot2d/Plot2d_Curve.cxx @@ -19,25 +19,27 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : Plot2d_Curve.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// File : Plot2d_Curve.cxx -// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// #include "Plot2d_Curve.h" -#include +#include +#include + +const int DEFAULT_LINE_WIDTH = 0; // (default) line width +const int DEFAULT_MARKER_SIZE = 9; // default marker size +const int MAX_ATTEMPTS = 10; // max attempts /*! Constructor */ Plot2d_Curve::Plot2d_Curve() -: myHorTitle( "" ), myVerTitle( "" ), - myHorUnits( "" ), myVerUnits( "" ), - myAutoAssign( true ), - myColor( 0,0,0 ), +: Plot2d_Object(), + myColor( 0, 0, 0 ), myMarker( Plot2d::Circle ), + myMarkerSize( 0 ), myLine( Plot2d::Solid ), - myLineWidth( 0 ), - myYAxis( QwtPlot::yLeft ) + myLineWidth( 0 ) { } @@ -49,276 +51,154 @@ Plot2d_Curve::~Plot2d_Curve() } /*! - Copy constructor. Makes deep copy of data. + Copy constructor. Makes deep copy of data */ Plot2d_Curve::Plot2d_Curve( const Plot2d_Curve& curve ) +: Plot2d_Object( curve ) { - myAutoAssign = curve.isAutoAssign(); - myHorTitle = curve.getHorTitle(); - myVerTitle = curve.getVerTitle(); - myHorUnits = curve.getHorUnits(); - myVerUnits = curve.getVerUnits(); myColor = curve.getColor(); myMarker = curve.getMarker(); + myMarkerSize = curve.getMarkerSize(); myLine = curve.getLine(); myLineWidth = curve.getLineWidth(); - myPoints = curve.getPointList(); } /*! - operator=. Makes deep copy of data. + operator=. Makes deep copy of data */ Plot2d_Curve& Plot2d_Curve::operator=( const Plot2d_Curve& curve ) { - myAutoAssign = curve.isAutoAssign(); - myHorTitle = curve.getHorTitle(); - myVerTitle = curve.getVerTitle(); - myHorUnits = curve.getHorUnits(); - myVerUnits = curve.getVerUnits(); + Plot2d_Object::operator=(curve); myColor = curve.getColor(); myMarker = curve.getMarker(); + myMarkerSize = curve.getMarkerSize(); myLine = curve.getLine(); myLineWidth = curve.getLineWidth(); - myPoints = curve.getPointList(); return *this; } /*! - \return title of table -*/ -QString Plot2d_Curve::getTableTitle() const -{ - return QString(); -} - -/*! - Sets curve's horizontal title -*/ -void Plot2d_Curve::setHorTitle( const QString& title ) -{ - myHorTitle = title; -} - -/*! - Gets curve's horizontal title -*/ -QString Plot2d_Curve::getHorTitle() const -{ - return myHorTitle; -} - -/*! - Sets curve's vertical title -*/ -void Plot2d_Curve::setVerTitle( const QString& title ) -{ - myVerTitle = title; -} - -/*! - Gets curve's vertical title -*/ -QString Plot2d_Curve::getVerTitle() const -{ - return myVerTitle; -} - -/*! - Sets curve's horizontal units -*/ -void Plot2d_Curve::setHorUnits( const QString& units ) -{ - myHorUnits = units; -} - -/*! - Gets curve's horizontal units + Get typeid for the plot2d curve class */ -QString Plot2d_Curve::getHorUnits() const +int Plot2d_Curve::rtti() { - return myHorUnits; + return QwtPlotItem::Rtti_PlotCurve; } /*! - Sets curve's vertical units + Create plot object for the curve */ -void Plot2d_Curve::setVerUnits( const QString& units ) +QwtPlotItem* Plot2d_Curve::createPlotItem() { - myVerUnits = units; + QwtPlotCurve* aCurve = new Plot2d_QwtPlotCurve( getVerTitle(), getYAxis() ); + updatePlotItem( aCurve ); + return aCurve; } /*! - Gets curve's vertical units + Auto fill parameters of object by plot view */ -QString Plot2d_Curve::getVerUnits() const +void Plot2d_Curve::autoFill( const QwtPlot* thePlot ) { - return myVerUnits; -} - -/*! - Adds one point for curve. -*/ -void Plot2d_Curve::addPoint(double theX, double theY, const QString& txt ) -{ - Plot2d_Point aPoint; - aPoint.x = theX; - aPoint.y = theY; - aPoint.text = txt; - myPoints.append(aPoint); -} - -/*! - Insert one point for curve on some position. -*/ -void Plot2d_Curve::insertPoint(int thePos, double theX, double theY, const QString& txt) -{ - Plot2d_Point aPoint; - aPoint.x = theX; - aPoint.y = theY; - aPoint.text = txt; - - pointList::iterator aIt; - int aCurrent = 0; - for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) { - if (thePos == aCurrent) { - myPoints.insert(aIt, aPoint); - return; - } - aCurrent++; - } - myPoints.append(aPoint); -} - -/*! - Delete one point for curve on some position. -*/ -void Plot2d_Curve::deletePoint(int thePos) -{ - if ( thePos >= 0 && thePos < myPoints.count() ) - myPoints.removeAt( thePos ); -} + QwtSymbol::Style typeMarker; + QColor color; + Qt::PenStyle typeLine; + getNextMarker( thePlot, typeMarker, color, typeLine ); -/*! - Remove all points for curve. -*/ -void Plot2d_Curve::clearAllPoints() -{ - myPoints.clear(); + setColor( color ); + setLine( Plot2d::qwt2plotLine( typeLine ), DEFAULT_LINE_WIDTH ); + setMarker( Plot2d::qwt2plotMarker( typeMarker ) ); } /*! - Gets curve's data : abscissas of points + Updates curve fields */ -pointList Plot2d_Curve::getPointList() const +void Plot2d_Curve::updatePlotItem( QwtPlotItem* theItem ) { - return myPoints; -} + if ( theItem->rtti() != rtti() ) + return; -/*! - Sets curve's data. -*/ -void Plot2d_Curve::setData( const double* hData, const double* vData, long size, const QStringList& lst ) -{ - clearAllPoints(); - QStringList::const_iterator anIt = lst.begin(), aLast = lst.end(); - for( long i = 0; i < size; i++, anIt++ ) - addPoint( hData[i], vData[i], anIt==aLast ? QString() : *anIt ); -} + QwtPlotCurve* aCurve = dynamic_cast( theItem ); + if ( !aCurve ) + return; -/*! - Gets curve's data : abscissas of points -*/ -double* Plot2d_Curve::horData() const -{ - int aNPoints = nbPoints(); - double* aX = new double[aNPoints]; - for (int i = 0; i < aNPoints; i++) { - aX[i] = myPoints[i].x; - } - return aX; -} + Plot2d_Object::updatePlotItem( theItem ); -/*! - Gets curve's data : ordinates of points -*/ -double* Plot2d_Curve::verData() const -{ - int aNPoints = nbPoints(); - double* aY = new double[aNPoints]; - for (int i = 0; i < aNPoints; i++) { - aY[i] = myPoints[i].y; - } - return aY; -} + Qt::PenStyle ps = Plot2d::plot2qwtLine( getLine() ); + QwtSymbol::Style ms = Plot2d::plot2qwtMarker( getMarker() ); -/*! - Gets curve's data : number of points -*/ -int Plot2d_Curve::nbPoints() const -{ - return myPoints.count(); + aCurve->setPen( QPen( getColor(), getLineWidth(), ps ) ); + aCurve->setSymbol( QwtSymbol( ms, QBrush( getColor() ), + QPen( getColor() ), + QSize( getMarkerSize(), getMarkerSize() ) ) ); + double *x, *y; + long nb = getData( &x, &y ); + aCurve->setData( x, y, nb ); } /*! - Returns true if curve has no data + Sets curve's color ( and resets AutoAssign flag ) */ -bool Plot2d_Curve::isEmpty() const +void Plot2d_Curve::setColor( const QColor& color ) { - return myPoints.isEmpty(); + myColor = color; + setAutoAssign( false ); } /*! - Sets curve's AutoAssign flag - in this case attributes will be set automatically + Gets curve's color */ -void Plot2d_Curve::setAutoAssign( bool on ) +QColor Plot2d_Curve::getColor() const { - myAutoAssign = on; + return myColor; } /*! - Gets curve's AutoAssign flag state + Sets marker type and size ( and resets AutoAssign flag ) */ -bool Plot2d_Curve::isAutoAssign() const +void Plot2d_Curve::setMarker( Plot2d::MarkerType marker, const int markerSize ) { - return myAutoAssign; + setMarker( marker ); + setMarkerSize( markerSize ); + setAutoAssign( false ); } /*! - Sets curve's color ( and resets AutoAssign flag ) + Sets marker type ( and resets AutoAssign flag ) */ -void Plot2d_Curve::setColor( const QColor& color ) +void Plot2d_Curve::setMarker( Plot2d::MarkerType marker ) { - myColor = color; - myAutoAssign = false; + myMarker = marker; + setAutoAssign( false ); } /*! - Gets curve's color + Gets marker type */ -QColor Plot2d_Curve::getColor() const +Plot2d::MarkerType Plot2d_Curve::getMarker() const { - return myColor; + return myMarker; } /*! - Sets curve's marker ( and resets AutoAssign flag ) + Sets new marker size ( and resets AutoAssign flag ) */ -void Plot2d_Curve::setMarker( Plot2d::MarkerType marker ) +void Plot2d_Curve::setMarkerSize( const int theSize ) { - myMarker = marker; - myAutoAssign = false; + myMarkerSize = theSize < 0 ? 0 : theSize; + setAutoAssign( false ); } /*! - Gets curve's marker + Gets marker size */ -Plot2d::MarkerType Plot2d_Curve::getMarker() const +int Plot2d_Curve::getMarkerSize() const { - return myMarker; + return myMarkerSize; } /*! - Sets curve's line type and width ( and resets AutoAssign flag ) + Sets line type and width ( and resets AutoAssign flag ) NOTE : A line width of 0 will produce a 1 pixel wide line using a fast algorithm for diagonals. A line width of 1 will also produce a 1 pixel wide line, but uses a slower more accurate algorithm for diagonals. @@ -326,124 +206,96 @@ Plot2d::MarkerType Plot2d_Curve::getMarker() const */ void Plot2d_Curve::setLine( Plot2d::LineType line, const int lineWidth ) { - myLine = line; - myLineWidth = lineWidth; - if ( myLineWidth < 0 ) myLineWidth = 0; - myAutoAssign = false; -} - -/*! - Gets curve's line type -*/ -Plot2d::LineType Plot2d_Curve::getLine() const -{ - return myLine; + setLine( line ); + setLineWidth( lineWidth ); + setAutoAssign( false ); } /*! - Gets curve's line width + Sets line type ( and resets AutoAssign flag ) */ -int Plot2d_Curve::getLineWidth() const +void Plot2d_Curve::setLine( Plot2d::LineType line ) { - return myLineWidth; + myLine = line; + setAutoAssign( false ); } /*! - Sets curve's y axis + Gets line type */ -void Plot2d_Curve::setYAxis(QwtPlot::Axis theYAxis) +Plot2d::LineType Plot2d_Curve::getLine() const { - if(theYAxis == QwtPlot::yLeft || theYAxis == QwtPlot::yRight) - myYAxis = theYAxis; + return myLine; } /*! - Gets curve's y axis + Sets line width ( and resets AutoAssign flag ) */ -QwtPlot::Axis Plot2d_Curve::getYAxis() const +void Plot2d_Curve::setLineWidth( const int lineWidth ) { - return myYAxis; + myLineWidth = lineWidth < 0 ? 0 : lineWidth; + setAutoAssign( false ); } /*! - Gets curve's minimal abscissa + Gets line width */ -double Plot2d_Curve::getMinX() const +int Plot2d_Curve::getLineWidth() const { - pointList::const_iterator aIt; - double aMinX = 1e150; - //int aCurrent = 0; - for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) { - if ( (*aIt).x < aMinX ) - aMinX = (*aIt).x; - } - return aMinX; + return myLineWidth; } /*! - Gets curve's maximal abscissa + Gets new unique marker for item if possible */ -double Plot2d_Curve::getMaxX() const +void Plot2d_Curve::getNextMarker( const QwtPlot* thePlot, QwtSymbol::Style& typeMarker, + QColor& color, Qt::PenStyle& typeLine ) { - pointList::const_iterator aIt; - double aMaxX = -1e150; - for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) { - if ( (*aIt).x > aMaxX ) - aMaxX = (*aIt).x; - } - return aMaxX; -} + bool bOk = false; + int cnt = 0; + while ( !bOk ) { + int aRed = (int)( 256.0 * rand() / RAND_MAX ); // generate random color + int aGreen = (int)( 256.0 * rand() / RAND_MAX ); // ... + int aBlue = (int)( 256.0 * rand() / RAND_MAX ); // ... + int aMarker = (int)( 9.0 * rand() / RAND_MAX ) + 1;// 9 markers types( not including empty ) + int aLine = (int)( 5.0 * rand() / RAND_MAX ) + 1;// 5 line types ( not including empty ) -/*! - Gets curve's minimal ordinate -*/ -double Plot2d_Curve::getMinY() const -{ - pointList::const_iterator aIt; - double aMinY = 1e150; - //int aCurrent = 0; - for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) { - if ( (*aIt).y < aMinY ) - aMinY = (*aIt).y; - } - return aMinY; -} + typeMarker = ( QwtSymbol::Style )aMarker; + color = QColor( aRed, aGreen, aBlue ); + typeLine = ( Qt::PenStyle )aLine; -/*! - Gets curve's maximal ordinate -*/ -double Plot2d_Curve::getMaxY() const -{ - pointList::const_iterator aIt; - double aMaxY = -1e150; - for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) { - if ( (*aIt).y > aMaxY ) - aMaxY = (*aIt).y; + bOk = ( ++cnt == MAX_ATTEMPTS ) || !existMarker( thePlot, typeMarker, color, typeLine ); } - return aMaxY; } /*! - Changes text assigned to point of curve - \param ind -- index of point - \param txt -- new text + Checks if marker belongs to any enitity */ -void Plot2d_Curve::setText( const int ind, const QString& txt ) +bool Plot2d_Curve::existMarker( const QwtPlot* thePlot, const QwtSymbol::Style typeMarker, + const QColor& color, const Qt::PenStyle typeLine ) { - if( ind<0 || ind>=myPoints.count() ) - return; + bool ok = false; - myPoints[ind].text = txt; -} - -/*! - \return text assigned to point - \param ind -- index of point -*/ -QString Plot2d_Curve::text( const int ind ) const -{ - if( ind<0 || ind>=myPoints.count() ) - return QString(); - else - return myPoints[ind].text; + QColor bgColor = thePlot->palette().color( QPalette::Background ); + if ( closeColors( color, bgColor ) ) { + ok = true; + } + else { + QwtPlotItemList anItems = thePlot->itemList(); + QwtPlotItemIterator anIt = anItems.begin(), aLast = anItems.end(); + QwtPlotItem* anItem; + for ( ; anIt != aLast && !ok; anIt++ ) { + anItem = *anIt; + if ( anItem && anItem->rtti() == rtti() ) { + QwtPlotCurve* crv = dynamic_cast( anItem ); + if ( crv ) { + QwtSymbol::Style aStyle = crv->symbol().style(); + QColor aColor = crv->pen().color(); + Qt::PenStyle aLine = crv->pen().style(); + ok = closeColors( aColor, color ) && aStyle == typeMarker && aLine == typeLine; + } + } + } + } + return ok; } diff --git a/src/Plot2d/Plot2d_Curve.h b/src/Plot2d/Plot2d_Curve.h index eccea214a..693a6ff02 100755 --- a/src/Plot2d/Plot2d_Curve.h +++ b/src/Plot2d/Plot2d_Curve.h @@ -19,103 +19,58 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : Plot2d_Curve.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// File : Plot2d_Curve.h -// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// #ifndef PLOT2D_CURVE_H #define PLOT2D_CURVE_H #include "Plot2d.h" +#include "Plot2d_Object.h" -#include -#include - -class QColor; - -typedef struct -{ - double x; - double y; - QString text; -} Plot2d_Point; - -typedef QList pointList; +//#include -class PLOT2D_EXPORT Plot2d_Curve +class PLOT2D_EXPORT Plot2d_Curve : public Plot2d_Object { public: Plot2d_Curve(); - virtual ~Plot2d_Curve(); Plot2d_Curve( const Plot2d_Curve& ); - Plot2d_Curve& operator= ( const Plot2d_Curve& ); - - virtual QString getTableTitle() const; - - void setHorTitle( const QString& ); - QString getHorTitle() const; - void setVerTitle( const QString& ); - QString getVerTitle() const; - - void setHorUnits( const QString& ); - QString getHorUnits() const; - void setVerUnits( const QString& ); - QString getVerUnits() const; - void addPoint( double, double, const QString& = QString() ); - void insertPoint( int, double, double, const QString& = QString() ); - void deletePoint( int ); - void clearAllPoints(); - pointList getPointList() const; - - void setData( const double*, const double*, - long, const QStringList& = QStringList() ); - double* horData() const; - double* verData() const; - - void setText( const int, const QString& ); - QString text( const int ) const; - - int nbPoints() const; - bool isEmpty() const; - - void setAutoAssign( bool ); - bool isAutoAssign() const; - - void setColor( const QColor& ); - QColor getColor() const; + virtual ~Plot2d_Curve(); + Plot2d_Curve& operator= ( const Plot2d_Curve& ); - void setMarker( Plot2d::MarkerType ); - Plot2d::MarkerType getMarker() const; + virtual int rtti(); + virtual QwtPlotItem* createPlotItem(); + virtual void autoFill( const QwtPlot* ); + virtual void updatePlotItem( QwtPlotItem* ); - void setLine( Plot2d::LineType, const int = 0 ); - Plot2d::LineType getLine() const; - int getLineWidth() const; + void setColor( const QColor& ); + QColor getColor() const; - void setYAxis( QwtPlot::Axis ); - QwtPlot::Axis getYAxis() const; + void setMarker( Plot2d::MarkerType, const int ); + void setMarker( Plot2d::MarkerType ); + Plot2d::MarkerType getMarker() const; + void setMarkerSize( const int ); + int getMarkerSize() const; - // Protection against QwtCurve::drawLines() bug in Qwt 0.4.x: - // it crashes if switched to X/Y logarithmic mode, when one or more points have - // non-positive X/Y coordinate - double getMinX() const; - double getMinY() const; - double getMaxX() const; - double getMaxY() const; + void setLine( Plot2d::LineType, const int ); + void setLine( Plot2d::LineType ); + Plot2d::LineType getLine() const; + void setLineWidth( const int ); + int getLineWidth() const; protected: - bool myAutoAssign; - QString myHorTitle; - QString myVerTitle; - QString myHorUnits; - QString myVerUnits; - QColor myColor; - Plot2d::MarkerType myMarker; - Plot2d::LineType myLine; - int myLineWidth; - QwtPlot::Axis myYAxis; + void getNextMarker( const QwtPlot*, QwtSymbol::Style&, + QColor&, Qt::PenStyle& ); + bool existMarker( const QwtPlot*, const QwtSymbol::Style, + const QColor&, const Qt::PenStyle ); - pointList myPoints; +protected: + QColor myColor; + Plot2d::MarkerType myMarker; + int myMarkerSize; + Plot2d::LineType myLine; + int myLineWidth; }; typedef QList curveList; diff --git a/src/Plot2d/Plot2d_Histogram.cxx b/src/Plot2d/Plot2d_Histogram.cxx new file mode 100644 index 000000000..e5b7cfa3f --- /dev/null +++ b/src/Plot2d/Plot2d_Histogram.cxx @@ -0,0 +1,256 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : Plot2d_Histogram.cxx +// Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com) + +#include "Plot2d_Histogram.h" +#include "Plot2d_PlotItems.h" + +#include + +const int MAX_ATTEMPTS = 10; // max attempts + +/*! + Constructor. +*/ +Plot2d_Histogram::Plot2d_Histogram() +: Plot2d_Object(), + myColor( 0, 0, 0 ), + myWidth( 0 ), + myDefWidth( 0 ) +{ +} + +/*! + Destructor. +*/ +Plot2d_Histogram::~Plot2d_Histogram() +{ +} + +/*! + Copy constructor. Makes deep copy of data. +*/ +Plot2d_Histogram::Plot2d_Histogram( const Plot2d_Histogram& hist ) +: Plot2d_Object( hist ) +{ + myColor = hist.myColor; + myWidth = hist.myWidth; + myDefWidth = hist.myDefWidth; +} + +/*! + operator=. Makes deep copy of data. +*/ +Plot2d_Histogram& Plot2d_Histogram::operator=( const Plot2d_Histogram& hist ) +{ + Plot2d_Object::operator=(hist); + myColor = hist.myColor; + myWidth = hist.myWidth; + myDefWidth = hist.myDefWidth; + return *this; +} + +/*! + Get typeid for the plot2d histogram class +*/ +int Plot2d_Histogram::rtti() +{ + return QwtPlotItem::Rtti_PlotHistogram; +} + +/*! + Create plot object for the histogram +*/ +QwtPlotItem* Plot2d_Histogram::createPlotItem() +{ + Plot2d_HistogramItem* anItem = new Plot2d_HistogramItem(); + updatePlotItem( anItem ); + return anItem; +} + +/*! + Auto fill parameters of object by plot view +*/ +void Plot2d_Histogram::autoFill( const QwtPlot* thePlot ) +{ + setColor( getNextColor( thePlot ) ); +} + +/*! + Updates histogram fields +*/ +void Plot2d_Histogram::updatePlotItem( QwtPlotItem* theItem ) +{ + if ( theItem->rtti() != rtti() ) + return; + + Plot2d_HistogramItem* anItem = dynamic_cast( theItem ); + if ( !anItem ) + return; + + Plot2d_Object::updatePlotItem( theItem ); + + anItem->setData( getData() ); + anItem->setColor( getColor() ); +} + +/*! + Sets data to object +*/ +void Plot2d_Histogram::setData( const QList& theXVals, + const QList& theYVals ) +{ + pointList aPoints; + int aSize = theXVals.size(); + for ( int i = 0; i < aSize; i++ ) + aPoints.append( Plot2d_Point( theXVals[i], theYVals[i] ) ); + setPointList( aPoints ); + + myDefWidth = getMinInterval( theXVals )*(2./3.); + myWidth = myDefWidth; +} + +/*! + Gets data +*/ +QwtIntervalData Plot2d_Histogram::getData() const +{ + pointList aPoints = getPointList(); + int aSize = aPoints.size(); + + QwtArray anIntervals( aSize ); + QwtArray aValues( aSize ); + double aX; + double aWidth = isAutoAssign() ? myDefWidth : myWidth; + for ( int i = 0; i < aSize; i++ ) { + aX = aPoints[i].x; + anIntervals[i] = QwtDoubleInterval( aX - aWidth/2, aX + aWidth/2 ); + aValues[i] = aPoints[i].y; + } + + return QwtIntervalData( anIntervals, aValues ); +} + +/*! + Sets color of histogram +*/ +void Plot2d_Histogram::setColor( const QColor& theColor ) +{ + myColor = theColor; + setAutoAssign( false ); +} + +/*! + Returns color of histogram +*/ +QColor Plot2d_Histogram::getColor() const +{ + return myColor; +} + +/*! + Sets width of a histogram bar +*/ +void Plot2d_Histogram::setWidth( const double theWidth ) +{ + myWidth = theWidth; + setAutoAssign( false ); +} + +/*! + Returns width for a histogram bar +*/ +double Plot2d_Histogram::getWidth( const bool isDef ) const +{ + return isDef ? myDefWidth : myWidth; +} + +/*! + Gets new unique marker for item if possible +*/ +QColor Plot2d_Histogram::getNextColor( const QwtPlot* thePlot ) +{ + bool bOk = false; + int cnt = 0; + QColor aColor; + while ( !bOk ) { + int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color + int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ... + int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ... + aColor = QColor( aRed, aGreen, aBlue ); + bOk = ( ++cnt == MAX_ATTEMPTS ) || !existColor( thePlot, aColor ); + } + return aColor; +} + +/*! + Checks if color is already user by other histogram entity +*/ +bool Plot2d_Histogram::existColor( const QwtPlot* thePlot, const QColor& theColor ) +{ + bool ok = false; + + QColor bgColor = thePlot->palette().color( QPalette::Background ); + if ( closeColors( theColor, bgColor ) ) { + ok = true; + } + else { + QwtPlotItemList anItems = thePlot->itemList(); + QwtPlotItemIterator anIt = anItems.begin(), aLast = anItems.end(); + QwtPlotItem* anItem; + for( ; anIt != aLast && !ok; anIt++ ) { + anItem = *anIt; + if ( !anItem ) + continue; + if ( anItem->rtti() == rtti() ) { + Plot2d_HistogramItem* aHItem = dynamic_cast( anItem ); + ok = aHItem && closeColors( theColor, aHItem->color() ); + } + else if ( anItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) { + QwtPlotCurve* aCurve = dynamic_cast( anItem ); + ok = aCurve && closeColors( theColor, aCurve->pen().color() ); + } + } + } + return ok; +} + +/*! + Return min interval from values +*/ +double Plot2d_Histogram::getMinInterval( const QList& theVals ) +{ + double aValue = -1; + int aSize = theVals.size(); + if ( aSize > 1 ) { + aValue = qAbs( theVals[1] - theVals[0] ); + double aDelta; + for ( int i = 2; i < aSize; i++ ) { + aDelta = qAbs( theVals[i] - theVals[i-1] ); + aValue = qMin( aValue, qMax( aDelta, 0. ) ); + } + aValue = aValue/2; + } + return aValue; +} + diff --git a/src/Plot2d/Plot2d_Histogram.h b/src/Plot2d/Plot2d_Histogram.h new file mode 100644 index 000000000..e204e7f1d --- /dev/null +++ b/src/Plot2d/Plot2d_Histogram.h @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : Plot2d_Histogram.h +// Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com) + +#ifndef PLOT2D_HISTOGRAM_H +#define PLOT2D_HISTOGRAM_H + +#include "Plot2d.h" +#include "Plot2d_Object.h" + +#include + +class PLOT2D_EXPORT Plot2d_Histogram : public Plot2d_Object +{ +public: + Plot2d_Histogram(); + Plot2d_Histogram( const Plot2d_Histogram& ); + + virtual ~Plot2d_Histogram(); + Plot2d_Histogram& operator= ( const Plot2d_Histogram& ); + + virtual int rtti(); + virtual QwtPlotItem* createPlotItem(); + virtual void autoFill( const QwtPlot* ); + virtual void updatePlotItem( QwtPlotItem* ); + + void setData( const QList&, const QList& ); + QwtIntervalData getData() const; + + void setColor( const QColor& ); + QColor getColor() const; + + void setWidth( const double ); + double getWidth( const bool ) const; + + static double getMinInterval( const QList& ); + +protected: + QColor getNextColor( const QwtPlot* ); + bool existColor( const QwtPlot*, const QColor& ); + +private: + QColor myColor; + double myWidth; + double myDefWidth; +}; + +#endif // PLOT2D_HISTOGRAM_H diff --git a/src/Plot2d/Plot2d_Object.cxx b/src/Plot2d/Plot2d_Object.cxx new file mode 100755 index 000000000..98c5e324c --- /dev/null +++ b/src/Plot2d/Plot2d_Object.cxx @@ -0,0 +1,486 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : Plot2d_Object.cxx +// Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com) +// + +#include "Plot2d_Object.h" + +// color tolerance (used to compare color values) +const long COLOR_DISTANCE = 100; + +/*! + Constructor +*/ +Plot2d_Point::Plot2d_Point() + : x( 0. ), y( 0. ) +{ +} + +/*! + Constructor +*/ +Plot2d_Point::Plot2d_Point( double theX, double theY, const QString& theText ) + : x( theX ), y( theY ), text( theText ) +{ +} + +/*! + Constructor +*/ +Plot2d_Object::Plot2d_Object() +: myAutoAssign( true ), + myHorTitle( "" ), myVerTitle( "" ), + myHorUnits( "" ), myVerUnits( "" ), + myName( "" ), + myXAxis( QwtPlot::xBottom ), + myYAxis( QwtPlot::yLeft ) +{ +} + +/*! + Destructor +*/ +Plot2d_Object::~Plot2d_Object() +{ +} + +/*! + Copy constructor. Makes deep copy of data. +*/ +Plot2d_Object::Plot2d_Object( const Plot2d_Object& object ) +{ + myAutoAssign = object.isAutoAssign(); + myHorTitle = object.getHorTitle(); + myVerTitle = object.getVerTitle(); + myHorUnits = object.getHorUnits(); + myVerUnits = object.getVerUnits(); + myName = object.getName(); + myXAxis = object.getXAxis(); + myYAxis = object.getYAxis(); + myPoints = object.getPointList(); +} + +/*! + operator=. Makes deep copy of data. +*/ +Plot2d_Object& Plot2d_Object::operator=( const Plot2d_Object& object ) +{ + myAutoAssign = object.isAutoAssign(); + myHorTitle = object.getHorTitle(); + myVerTitle = object.getVerTitle(); + myHorUnits = object.getHorUnits(); + myVerUnits = object.getVerUnits(); + myName = object.getName(); + myXAxis = object.getXAxis(); + myYAxis = object.getYAxis(); + myPoints = object.getPointList(); + return *this; +} + +/*! + Auto fill parameters of object by plot view +*/ +void Plot2d_Object::autoFill( const QwtPlot* ) +{ +} + +/*! + * Updates object fields + */ +void Plot2d_Object::updatePlotItem( QwtPlotItem* theItem ) +{ + if ( !theItem || theItem->rtti() != rtti() ) + return; + + if ( theItem->yAxis() != getYAxis() || theItem->xAxis() != getXAxis() ) { + theItem->setAxis( getXAxis(), getYAxis() ); + + QwtPlot* aPlot = theItem->plot(); + if ( aPlot ) { + theItem->detach(); + theItem->attach( aPlot ); + } + } + theItem->setTitle( !getName().isEmpty() ? getName() : getVerTitle() ); +} + +/*! + \return title of table +*/ +QString Plot2d_Object::getTableTitle() const +{ + return QString(); +} + +/*! + Sets object's horizontal title +*/ +void Plot2d_Object::setHorTitle( const QString& title ) +{ + myHorTitle = title; +} + +/*! + Gets object's horizontal title +*/ +QString Plot2d_Object::getHorTitle() const +{ + return myHorTitle; +} + +/*! + Sets object's vertical title +*/ +void Plot2d_Object::setVerTitle( const QString& title ) +{ + myVerTitle = title; +} + +/*! + Gets object's vertical title +*/ +QString Plot2d_Object::getVerTitle() const +{ + return myVerTitle; +} + +/*! + Sets object's horizontal units +*/ +void Plot2d_Object::setHorUnits( const QString& units ) +{ + myHorUnits = units; +} + +/*! + Gets object's horizontal units +*/ +QString Plot2d_Object::getHorUnits() const +{ + return myHorUnits; +} + +/*! + Sets object's vertical units +*/ +void Plot2d_Object::setVerUnits( const QString& units ) +{ + myVerUnits = units; +} + +/*! + Gets object's vertical units +*/ +QString Plot2d_Object::getVerUnits() const +{ + return myVerUnits; +} + +/*! + Sets object's name + */ +void Plot2d_Object::setName( const QString& theName ) +{ + myName = theName; +} +/*! + Gets object's name + */ +QString Plot2d_Object::getName() const +{ + return myName; +} + +/*! + Adds one point for object. +*/ +void Plot2d_Object::addPoint( double theX, double theY, const QString& theText ) +{ + addPoint( Plot2d_Point( theX, theY, theText ) ); +} + +/*! + Adds one point for object. +*/ +void Plot2d_Object::addPoint( const Plot2d_Point& thePoint ) +{ + myPoints.append( thePoint ); +} + +/*! + Insert one point for object on some position. +*/ +void Plot2d_Object::insertPoint( int thePos, double theX, double theY, + const QString& theText ) +{ + insertPoint( thePos, Plot2d_Point( theX, theY, theText ) ); +} + +/*! + Insert one point for object on some position. +*/ +void Plot2d_Object::insertPoint( int thePos, const Plot2d_Point& thePoint ) +{ + if ( thePos < 0 ) + myPoints.append( thePoint ); + else + myPoints.insert( thePos, thePoint ); +} + +/*! + Delete one point for object on some position. +*/ +void Plot2d_Object::deletePoint(int thePos) +{ + if ( thePos >= 0 && thePos < myPoints.count() ) + myPoints.removeAt( thePos ); +} + +/*! + Remove all points for object. +*/ +void Plot2d_Object::clearAllPoints() +{ + myPoints.clear(); +} + +/*! + Gets object's data : abscissas of points +*/ +pointList Plot2d_Object::getPointList() const +{ + return myPoints; +} + +/*! + Gets object's data : abscissas of points +*/ +void Plot2d_Object::setPointList( const pointList& points ) +{ + myPoints = points; +} + +/*! + Sets object's data. +*/ +void Plot2d_Object::setData( const double* hData, const double* vData, long size, const QStringList& lst ) +{ + clearAllPoints(); + QStringList::const_iterator anIt = lst.begin(), aLast = lst.end(); + for ( long i = 0; i < size; i++, anIt++ ) + addPoint( hData[i], vData[i], anIt==aLast ? QString() : *anIt ); +} + +/*! + Gets object's data : abscissas of points +*/ +double* Plot2d_Object::horData() const +{ + int aNPoints = nbPoints(); + double* aX = new double[aNPoints]; + for (int i = 0; i < aNPoints; i++) { + aX[i] = myPoints[i].x; + } + return aX; +} + +/*! + Gets object's data : ordinates of points +*/ +double* Plot2d_Object::verData() const +{ + int aNPoints = nbPoints(); + double* aY = new double[aNPoints]; + for (int i = 0; i < aNPoints; i++) { + aY[i] = myPoints[i].y; + } + return aY; +} + +/*! + Gets object's data +*/ +long Plot2d_Object::getData( double** theX, double** theY ) const +{ + int aNPoints = nbPoints(); + *theX = new double[aNPoints]; + *theY = new double[aNPoints]; + for (int i = 0; i < aNPoints; i++) { + (*theX)[i] = myPoints[i].x; + (*theY)[i] = myPoints[i].y; + } + return aNPoints; +} + +/*! + Changes text assigned to point of object + \param ind -- index of point + \param txt -- new text +*/ +void Plot2d_Object::setText( const int ind, const QString& txt ) +{ + if ( ind >= 0 && ind < myPoints.count() ) + myPoints[ind].text = txt; +} + +/*! + \return text assigned to point + \param ind -- index of point +*/ +QString Plot2d_Object::text( const int ind ) const +{ + return ( ind >= 0 && ind < myPoints.count() ) ? myPoints[ind].text : QString(); +} + +/*! + Gets object's data : number of points +*/ +int Plot2d_Object::nbPoints() const +{ + return myPoints.count(); +} + +/*! + Returns true if object has no data +*/ +bool Plot2d_Object::isEmpty() const +{ + return myPoints.isEmpty(); +} + +/*! + Sets object's AutoAssign flag - in this case attributes will be set automatically +*/ +void Plot2d_Object::setAutoAssign( bool on ) +{ + myAutoAssign = on; +} + +/*! + Gets object's AutoAssign flag state +*/ +bool Plot2d_Object::isAutoAssign() const +{ + return myAutoAssign; +} + +/*! + Sets object's x axis +*/ +void Plot2d_Object::setXAxis(QwtPlot::Axis theXAxis) +{ + if (theXAxis == QwtPlot::xBottom || theXAxis == QwtPlot::xTop) + myXAxis = theXAxis; +} + +/*! + Gets object's x axis +*/ +QwtPlot::Axis Plot2d_Object::getXAxis() const +{ + return myXAxis; +} + +/*! + Sets object's y axis +*/ +void Plot2d_Object::setYAxis(QwtPlot::Axis theYAxis) +{ + if (theYAxis == QwtPlot::yLeft || theYAxis == QwtPlot::yRight) + myYAxis = theYAxis; +} + +/*! + Gets object's y axis +*/ +QwtPlot::Axis Plot2d_Object::getYAxis() const +{ + return myYAxis; +} + +/*! + Gets object's minimal abscissa +*/ +double Plot2d_Object::getMinX() const +{ + double aMinX = 1e150; + pointList::const_iterator aIt; + for (aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) + aMinX = qMin( aMinX, (*aIt).x ); + return aMinX; +} + +/*! + Gets object's maximal abscissa +*/ +double Plot2d_Object::getMaxX() const +{ + double aMaxX = -1e150; + pointList::const_iterator aIt; + for (aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) + aMaxX = qMax( aMaxX, (*aIt).x ); + return aMaxX; +} + +/*! + Gets object's minimal ordinate +*/ +double Plot2d_Object::getMinY() const +{ + double aMinY = 1e150; + pointList::const_iterator aIt; + for (aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) + aMinY = qMin( aMinY, (*aIt).y ); + return aMinY; +} + +/*! + Gets object's maximal ordinate +*/ +double Plot2d_Object::getMaxY() const +{ + double aMaxY = -1e150; + pointList::const_iterator aIt; + for (aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) + aMaxY = qMax( aMaxY, (*aIt).y ); + return aMaxY; +} + +/*! + Checks if two colors are close to each other [ static ] + uses COLOR_DISTANCE variable as max tolerance for comparing of colors +*/ + +bool Plot2d_Object::closeColors( const QColor& color1, + const QColor& color2, + int distance ) +{ + long tol = + qAbs( color2.red() - color1.red() ) + + qAbs( color2.green() - color1.green() ) + + qAbs( color2.blue() - color1.blue() ) - + ( distance < 0 ? COLOR_DISTANCE : distance ); + + return tol <= 0; +} + diff --git a/src/Plot2d/Plot2d_Object.h b/src/Plot2d/Plot2d_Object.h new file mode 100755 index 000000000..e86f9cb35 --- /dev/null +++ b/src/Plot2d/Plot2d_Object.h @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : Plot2d_Object.h +// Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com) +// + +#ifndef PLOT2D_OBJECT_H +#define PLOT2D_OBJECT_H + +#include "Plot2d.h" + +#include +#include + +struct PLOT2D_EXPORT Plot2d_Point +{ + double x; + double y; + QString text; + Plot2d_Point(); + Plot2d_Point( double theX, double theY, const QString& theText = QString() ); +}; + +typedef QList pointList; + +class PLOT2D_EXPORT Plot2d_Object +{ +public: + Plot2d_Object(); + Plot2d_Object( const Plot2d_Object& ); + + virtual ~Plot2d_Object(); + Plot2d_Object& operator= ( const Plot2d_Object& ); + + virtual int rtti() = 0; + virtual QwtPlotItem* createPlotItem() = 0; + virtual void autoFill( const QwtPlot* ); + virtual void updatePlotItem( QwtPlotItem* ); + + virtual QString getTableTitle() const; + + void setHorTitle( const QString& ); + QString getHorTitle() const; + void setVerTitle( const QString& ); + QString getVerTitle() const; + + void setHorUnits( const QString& ); + QString getHorUnits() const; + void setVerUnits( const QString& ); + QString getVerUnits() const; + + void setName( const QString& ); + QString getName() const; + + void addPoint( double, double, const QString& = QString() ); + void addPoint( const Plot2d_Point& ); + void insertPoint( int, double, double, const QString& = QString() ); + void insertPoint( int, const Plot2d_Point& ); + void deletePoint( int ); + void clearAllPoints(); + pointList getPointList() const; + void setPointList( const pointList& points ); + + void setData( const double*, const double*, + long, const QStringList& = QStringList() ); + double* horData() const; + double* verData() const; + long getData( double**, double** ) const; + + void setText( const int, const QString& ); + QString text( const int ) const; + + int nbPoints() const; + bool isEmpty() const; + + void setAutoAssign( bool ); + bool isAutoAssign() const; + + void setXAxis( QwtPlot::Axis ); + QwtPlot::Axis getXAxis() const; + void setYAxis( QwtPlot::Axis ); + QwtPlot::Axis getYAxis() const; + + // Protection against QwtObject::drawLines() bug in Qwt 0.4.x: + // it crashes if switched to X/Y logarithmic mode, when one or more points have + // non-positive X/Y coordinate + double getMinX() const; + double getMaxX() const; + double getMinY() const; + double getMaxY() const; + + static bool closeColors( const QColor&, const QColor&, int distance = -1 ); + +protected: + bool myAutoAssign; + QString myHorTitle; + QString myVerTitle; + QString myHorUnits; + QString myVerUnits; + QString myName; + QwtPlot::Axis myXAxis; + QwtPlot::Axis myYAxis; + + pointList myPoints; +}; + +typedef QList objectList; + +#endif diff --git a/src/Plot2d/Plot2d_PlotItems.cxx b/src/Plot2d/Plot2d_PlotItems.cxx new file mode 100644 index 000000000..3352c2477 --- /dev/null +++ b/src/Plot2d/Plot2d_PlotItems.cxx @@ -0,0 +1,628 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : Plot2d_HistogramItem.cxx +// Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com) + +#include "Plot2d_PlotItems.h" + +#include +#include +#include +#include +#include +#include +#include + +const char* yAxisLeft[] = { + "12 12 2 1", + " c None", + ". c #000000", + " ", + " . ", + " ... ", + " . . . ", + " . ", + " . ", + " . . ", + " . . ", + " ........ ", + " . ", + " . ", + " "}; + +const char* yAxisRight[] = { + "12 12 2 1", + " c None", + ". c #000000", + " ", + " . ", + " ... ", + " . . . ", + " . ", + " . ", + " . . ", + " . . ", + " ........ ", + " . ", + " . ", + " "}; + +/*! + Constructor of Plot2d_QwtLegendItem +*/ +Plot2d_QwtLegendItem::Plot2d_QwtLegendItem( QWidget* parent ) : + QwtLegendItem( parent ), + myYAxisIdentifierMode( IM_None ) +{ + myYAxisLeftIcon = yAxisLeft; + myYAxisRightIcon = yAxisRight; + int anIconWidth = qMax( myYAxisLeftIcon.width(), myYAxisRightIcon.width() ); + + mySpacingCollapsed = spacing(); + mySpacingExpanded = anIconWidth - mySpacingCollapsed; +} + +/*! + Destructor of Plot2d_QwtLegendItem +*/ +Plot2d_QwtLegendItem::~Plot2d_QwtLegendItem() +{ +} + +/*! + Set Y axis identifier displaying mode +*/ +void Plot2d_QwtLegendItem::setYAxisIdentifierMode( const int theMode ) +{ + myYAxisIdentifierMode = theMode; + setSpacing( theMode == IM_None ? mySpacingCollapsed : mySpacingExpanded ); +} + +/*! + Redefined method of drawing identifier of legend item +*/ +void Plot2d_QwtLegendItem::drawIdentifier( QPainter* painter, const QRect& rect ) const +{ + QwtLegendItem::drawIdentifier( painter, rect ); + + if( myYAxisIdentifierMode != IM_None ) { + QPixmap aPixmap( myYAxisIdentifierMode == IM_Left ? yAxisLeft : yAxisRight ); + painter->save(); + painter->drawPixmap( rect.topRight() + QPoint( mySpacingExpanded/2, mySpacingExpanded/2 ), aPixmap ); + painter->restore(); + } +} + +/*! + Constructor of Plot2d_QwtPlotCurve +*/ +Plot2d_QwtPlotCurve::Plot2d_QwtPlotCurve( const QString& title, + QwtPlot::Axis yAxis /*const int index*/ ) : + QwtPlotCurve( title ), + myYAxis( yAxis ), + myYAxisIdentifierEnabled( false ) +{ +} + +/*! + Destructor of Plot2d_QwtPlotCurve +*/ +Plot2d_QwtPlotCurve::~Plot2d_QwtPlotCurve() +{ +} + +/*! + Enable / disable Y axis identifier +*/ +void Plot2d_QwtPlotCurve::setYAxisIdentifierEnabled( const bool on ) +{ + myYAxisIdentifierEnabled = on; +} + +/*! + Redefined method, which updates legend of the curve +*/ +void Plot2d_QwtPlotCurve::updateLegend( QwtLegend* legend ) const +{ + QwtPlotCurve::updateLegend( legend ); + + if ( legend ) { + QWidget* widget = legend->find( this ); + if( Plot2d_QwtLegendItem* anItem = dynamic_cast( widget ) ) { + int aMode = Plot2d_QwtLegendItem::IM_None; + if( myYAxisIdentifierEnabled ) + aMode = myYAxis == QwtPlot::yRight ? + Plot2d_QwtLegendItem::IM_Right : + Plot2d_QwtLegendItem::IM_Left; + anItem->setYAxisIdentifierMode( aMode ); + } + } +} + +/*! + Redefined method, which creates and returns legend item of the curve +*/ +QWidget* Plot2d_QwtPlotCurve::legendItem() const +{ + return new Plot2d_QwtLegendItem; +} + +/*! + Constructor +*/ +Plot2d_HistogramQwtItem::Plot2d_HistogramQwtItem( const QwtText& theTitle ) +: QwtPlotItem( theTitle ) +{ + init(); +} + +/*! + Constructor +*/ +Plot2d_HistogramQwtItem::Plot2d_HistogramQwtItem( const QString& theTitle ) +: QwtPlotItem( QwtText( theTitle ) ) +{ + init(); +} + +/*! + Destructor +*/ +Plot2d_HistogramQwtItem::~Plot2d_HistogramQwtItem() +{ +} + +/*! + Initialization of object +*/ +void Plot2d_HistogramQwtItem::init() +{ + myReference = 0.0; + myAttributes = Plot2d_HistogramQwtItem::Auto; + + setItemAttribute( QwtPlotItem::AutoScale, true ); + setItemAttribute( QwtPlotItem::Legend, true ); + + setZ( 20.0 ); +} + +/*! + Sets base line to object + @param theRef +*/ +void Plot2d_HistogramQwtItem::setBaseline( double theRef ) +{ + if ( myReference != theRef ) { + myReference = theRef; + itemChanged(); + } +} + +/*! + Returns base line of object +*/ +double Plot2d_HistogramQwtItem::baseline() const +{ + return myReference; +} + +/*! + Sets data to object +*/ +void Plot2d_HistogramQwtItem::setData( const QwtIntervalData& theData ) +{ + myData = theData; + itemChanged(); +} + +/*! + Returns data from object +*/ +const QwtIntervalData& Plot2d_HistogramQwtItem::data() const +{ + return myData; +} + +/*! + Sets color to object +*/ +void Plot2d_HistogramQwtItem::setColor( const QColor& theColor ) +{ + if ( myColor != theColor ) { + myColor = theColor; + itemChanged(); + } +} + +/*! + Returns color from object +*/ +QColor Plot2d_HistogramQwtItem::color() const +{ + return myColor; +} + +/*! + Returns bounding rect of object +*/ +QwtDoubleRect Plot2d_HistogramQwtItem::boundingRect() const +{ + QwtDoubleRect aRect = myData.boundingRect(); + if ( !aRect.isValid() ) + return aRect; + + if ( myAttributes & Xfy ) { + aRect = QwtDoubleRect( aRect.y(), aRect.x(), + aRect.height(), aRect.width() ); + if ( aRect.left() > myReference ) + aRect.setLeft( myReference ); + else if ( aRect.right() < myReference ) + aRect.setRight( myReference ); + } + else { + if ( aRect.bottom() < myReference ) + aRect.setBottom( myReference ); + else if ( aRect.top() > myReference ) + aRect.setTop( myReference ); + } + return aRect; +} + +/*! + Returns type of plot object +*/ +int Plot2d_HistogramQwtItem::rtti() const +{ + return QwtPlotItem::Rtti_PlotHistogram; +} + +/*! + Sets histogram attributes +*/ +void Plot2d_HistogramQwtItem::setHistogramAttribute( HistogramAttribute theAttr, + bool isOn ) +{ + if ( testHistogramAttribute( theAttr ) != isOn ) { + if ( isOn ) + myAttributes |= theAttr; + else + myAttributes &= ~theAttr; + + itemChanged(); + } +} + +/*! + Tests histogram attributes +*/ +bool Plot2d_HistogramQwtItem::testHistogramAttribute( HistogramAttribute theAttr ) const +{ + return myAttributes & theAttr; +} + +/*! + Draws histogram object +*/ +void Plot2d_HistogramQwtItem::draw( QPainter* thePainter, + const QwtScaleMap& theXMap, + const QwtScaleMap& theYMap, + const QRect& ) const +{ + thePainter->setPen( QPen( myColor ) ); + + const int x0 = theXMap.transform( baseline() ); + const int y0 = theYMap.transform( baseline() ); + + for ( int i = 0; i < (int)myData.size(); i++ ) { + if ( myAttributes & Plot2d_HistogramQwtItem::Xfy ) { + const int x2 = theXMap.transform( myData.value( i ) ); + if ( x2 == x0 ) + continue; + int y1 = theYMap.transform( myData.interval( i ).minValue() ); + int y2 = theYMap.transform( myData.interval( i ).maxValue() ); + if ( y1 > y2 ) + qSwap( y1, y2 ); + + if ( i < (int)myData.size() - 2 ) { + const int yy1 = theYMap.transform( myData.interval(i+1).minValue() ); + const int yy2 = theYMap.transform( myData.interval(i+1).maxValue() ); + if ( y2 == qwtMin( yy1, yy2 ) ) { + const int xx2 = theXMap.transform( myData.interval(i+1).minValue() ); + if ( xx2 != x0 && ( ( xx2 < x0 && x2 < x0 ) || + ( xx2 > x0 && x2 > x0 ) ) ) { + // One pixel distance between neighboured bars + y2++; + } + } + } + drawBar( thePainter, Qt::Horizontal, QRect( x0, y1, x2 - x0, y2 - y1 ) ); + } + else { + const int y2 = theYMap.transform( myData.value( i ) ); + if ( y2 == y0 ) + continue; + int x1 = theXMap.transform( myData.interval( i ).minValue() ); + int x2 = theXMap.transform( myData.interval( i ).maxValue() ); + if ( x1 > x2 ) + qSwap( x1, x2 ); + + if ( i < (int)myData.size() - 2 ) { + const int xx1 = theXMap.transform( myData.interval(i+1).minValue() ); + const int xx2 = theXMap.transform( myData.interval(i+1).maxValue() ); + if ( x2 == qwtMin( xx1, xx2 ) ) { + const int yy2 = theYMap.transform( myData.value(i+1) ); + if ( yy2 != y0 && ( ( yy2 < y0 && y2 < y0 ) || + ( yy2 > y0 && y2 > y0 ) ) ) { + // One pixel distance between neighboured bars + x2--; + } + } + } + drawBar( thePainter, Qt::Vertical, QRect( x1, y0, x2 - x1, y2 - y0 ) ); + } + } +} + +/*! + Draws single bar of histogram +*/ +void Plot2d_HistogramQwtItem::drawBar( QPainter* thePainter, + Qt::Orientation, + const QRect& theRect ) const +{ + thePainter->save(); + + const QColor color( thePainter->pen().color() ); + QRect r = theRect.normalized(); + + const int factor = 125; + const QColor light( color.light( factor ) ); + const QColor dark( color.dark( factor ) ); + + thePainter->setBrush( color ); + thePainter->setPen( Qt::NoPen ); + QwtPainter::drawRect( thePainter, r.x() + 1, r.y() + 1, + r.width() - 2, r.height() - 2 ); + thePainter->setBrush( Qt::NoBrush ); + + thePainter->setPen( QPen( light, 2 ) ); + QwtPainter::drawLine( thePainter, r.left() + 1, r.top() + 2, + r.right() + 1, r.top() + 2 ); + + thePainter->setPen( QPen( dark, 2 ) ); + QwtPainter::drawLine( thePainter, r.left() + 1, r.bottom(), + r.right() + 1, r.bottom() ); + thePainter->setPen( QPen( light, 1 ) ); + + QwtPainter::drawLine( thePainter, r.left(), r.top() + 1, + r.left(), r.bottom() ); + QwtPainter::drawLine( thePainter, r.left() + 1, r.top() + 2, + r.left() + 1, r.bottom() - 1 ); + thePainter->setPen( QPen( dark, 1 ) ); + + QwtPainter::drawLine( thePainter, r.right() + 1, r.top() + 1, + r.right() + 1, r.bottom() ); + QwtPainter::drawLine(thePainter, r.right(), r.top() + 2, + r.right(), r.bottom() - 1 ); + thePainter->restore(); +} + +/*! + Constructor +*/ +Plot2d_HistogramItem::Plot2d_HistogramItem( const QwtText& theTitle ) +: Plot2d_HistogramQwtItem( theTitle ), + myCrossed( true ) +{ +} + +/*! + Constructor +*/ +Plot2d_HistogramItem::Plot2d_HistogramItem( const QString& theTitle ) +: Plot2d_HistogramQwtItem( theTitle ), + myCrossed( true ) +{ +} + +/*! + Destructor +*/ +Plot2d_HistogramItem::~Plot2d_HistogramItem() +{ +} + +/*! + Get histogram bar items +*/ +QList Plot2d_HistogramItem::getBars() const +{ + return myBarItems; +} + +/*! + Set to legend item symbol with color of item +*/ +void Plot2d_HistogramItem::updateLegend( QwtLegend* theLegend ) const +{ + if ( !theLegend ) + return; + + Plot2d_HistogramQwtItem::updateLegend( theLegend ); + + QWidget* theWidget = theLegend->find( this ); + if ( !theWidget || !theWidget->inherits( "QwtLegendItem" ) ) + return; + + QwtLegendItem* anItem = ( QwtLegendItem* )theWidget; + QFontMetrics aFMetrics( anItem->font() ); + int aSize = aFMetrics.height(); + QwtSymbol aSymbol( QwtSymbol::Rect, QBrush( color() ), + QPen( color() ), QSize( aSize, aSize ) ); + anItem->setSymbol( aSymbol ); + anItem->setIdentifierMode( theLegend->identifierMode() + | QwtLegendItem::ShowSymbol ); + anItem->update(); +} + +/*! + Draws histogram object +*/ +void Plot2d_HistogramItem::draw( QPainter* thePainter, + const QwtScaleMap& theXMap, + const QwtScaleMap& theYMap, + const QRect& ) const +{ + // nds: clear list of bar items + Plot2d_HistogramItem* anItem = (Plot2d_HistogramItem*)this; + anItem->myBarItems.clear(); + + thePainter->setPen( QPen( color() ) ); + const int x0 = theXMap.transform( baseline() ); + const int y0 = theYMap.transform( baseline() ); + + const QwtIntervalData& iData = data(); + + for ( int i = 0; i < (int)iData.size(); i++ ) { + if ( testHistogramAttribute( Plot2d_HistogramItem::Xfy ) ) { + const int x2 = theXMap.transform( iData.value( i ) ); + if ( x2 == x0 ) + continue; + int y1 = theYMap.transform( iData.interval( i ).minValue() ); + int y2 = theYMap.transform( iData.interval( i ).maxValue() ); + if ( y1 > y2 ) + qSwap( y1, y2 ); + + if ( i < (int)iData.size() - 2 ) { + const int yy1 = theYMap.transform( iData.interval(i+1).minValue() ); + const int yy2 = theYMap.transform( iData.interval(i+1).maxValue() ); + if ( y2 == qwtMin( yy1, yy2 ) ) { + const int xx2 = theXMap.transform( iData.interval(i+1).minValue() ); + if ( xx2 != x0 && ( ( xx2 < x0 && x2 < x0 ) || + ( xx2 > x0 && x2 > x0 ) ) ) { + // One pixel distance between neighboured bars + y2++; + } + } + } + // nds: draw rect with the other lower rects + QRect aRect( x0, y1, x2 - x0, y2 - y1 ); + drawRectAndLowers( thePainter, Qt::Horizontal, aRect ); + anItem->myBarItems.append( aRect ); + } + else { + const int y2 = theYMap.transform( iData.value( i ) ); + if ( y2 == y0 ) + continue; + int x1 = theXMap.transform( iData.interval( i ).minValue() ); + int x2 = theXMap.transform( iData.interval( i ).maxValue() ); + if ( x1 > x2 ) + qSwap( x1, x2 ); + + if ( i < (int)iData.size() - 2 ) { + const int xx1 = theXMap.transform( iData.interval(i+1).minValue() ); + const int xx2 = theXMap.transform( iData.interval(i+1).maxValue() ); + if ( x2 == qwtMin( xx1, xx2 ) ) { + const int yy2 = theYMap.transform( iData.value(i+1) ); + if ( yy2 != y0 && ( ( yy2 < y0 && y2 < y0 ) || + ( yy2 > y0 && y2 > y0 ) ) ) { + // One pixel distance between neighboured bars + x2--; + } + } + } + // nds: draw rect with the other lower rects + QRect aRect(x1, y0, x2 - x1, y2 - y0 ); + drawRectAndLowers( thePainter, Qt::Vertical, aRect ); + anItem->myBarItems.append( aRect ); + } + } +} + +/*! + Set/clear "cross items" option +*/ +void Plot2d_HistogramItem::setCrossItems( bool theCross ) +{ + myCrossed = theCross; +} + +/*! + Get "cross items" option +*/ +bool Plot2d_HistogramItem::isCrossItems() const +{ + return myCrossed; +} + +/*! + Draws bar of histogram and on it bars of histograms with lower height. +*/ +void Plot2d_HistogramItem::drawRectAndLowers( QPainter* thePainter, + Qt::Orientation theOr, + const QRect& theRect ) const +{ + QRect aRect = theRect; + // theRect has inversed coordinates on Y axis. + // The top of the rect is bottom in standard QRect coordinates, + // and it bottom is the top. + if ( myCrossed )//&& theOr == Qt::Horizontal ) + aRect.setTop( getCrossedTop( theRect ) ); + + drawBar( thePainter, Qt::Horizontal, aRect ); +} + +/*! + Returns top value of the given rect in the context of other bars. + + It's necessary to remember, that \a theRect has inverted coordinate Y. +*/ +int Plot2d_HistogramItem::getCrossedTop( const QRect& theRect ) const +{ + int aRes = theRect.top(); + QwtPlot* aPlot = plot(); + // int aHeight = theRect.height(); + if ( aPlot ) { + QwtPlotItemList anItems = aPlot->itemList(); + QwtPlotItemIterator anIt = anItems.begin(), aLast = anItems.end(); + Plot2d_HistogramItem* anItem; + QList aRects; + for ( ; anIt != aLast; anIt++ ) { + if ( !(*anIt)->rtti() == QwtPlotItem::Rtti_PlotHistogram ) + continue; + anItem = dynamic_cast( *anIt ); + if( !anItem || anItem == this ) + continue; + aRects.clear(); + aRects = anItem->getBars(); + for ( int i = 0, aSize = aRects.size(); i < aSize; i++ ) { + if ( qMax( theRect.x(), aRects[i].x() ) <= + qMin( theRect.left(), aRects[i].left() ) ) { + if ( theRect.bottom() < aRects[i].bottom() ) + if ( aRects[i].bottom() < aRes ) + aRes = aRects[i].bottom(); + } + } + } + } + return aRes; +} diff --git a/src/Plot2d/Plot2d_PlotItems.h b/src/Plot2d/Plot2d_PlotItems.h new file mode 100644 index 000000000..00d44feaf --- /dev/null +++ b/src/Plot2d/Plot2d_PlotItems.h @@ -0,0 +1,146 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : Plot2d_HistogramItem.h +// Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com) + +#ifndef PLOT2D_PLOTITEMS_H +#define PLOT2D_PLOTITEMS_H + +#include "Plot2d.h" + +#include +#include +#include +#include +#include + +class PLOT2D_EXPORT Plot2d_QwtLegendItem : public QwtLegendItem +{ +public: + enum YAxisIdentifierMode { IM_None = 0, IM_Left, IM_Right }; + +public: + Plot2d_QwtLegendItem( QWidget* = 0 ); + virtual ~Plot2d_QwtLegendItem(); + +public: + void setYAxisIdentifierMode( const int ); + +protected: + virtual void drawIdentifier( QPainter*, const QRect& ) const; + +private: + int myYAxisIdentifierMode; + QPixmap myYAxisLeftIcon; + QPixmap myYAxisRightIcon; + int mySpacingCollapsed; + int mySpacingExpanded; +}; + +class PLOT2D_EXPORT Plot2d_QwtPlotCurve : public QwtPlotCurve +{ +public: + Plot2d_QwtPlotCurve( const QString&, QwtPlot::Axis = QwtPlot::yLeft ); + virtual ~Plot2d_QwtPlotCurve(); + +public: + virtual void setYAxisIdentifierEnabled( const bool ); + +protected: + virtual void updateLegend( QwtLegend* ) const; + virtual QWidget* legendItem() const; + +private: + QwtPlot::Axis myYAxis; + bool myYAxisIdentifierEnabled; +}; + +class PLOT2D_EXPORT Plot2d_HistogramQwtItem: public QwtPlotItem +{ +public: + enum HistogramAttribute + { + Auto = 0, + Xfy = 1 + }; + + explicit Plot2d_HistogramQwtItem( const QString& = QString() ); + explicit Plot2d_HistogramQwtItem( const QwtText& ); + virtual ~Plot2d_HistogramQwtItem(); + + void setData( const QwtIntervalData& ); + const QwtIntervalData& data() const; + + void setColor( const QColor& ); + QColor color() const; + + virtual QwtDoubleRect boundingRect() const; + virtual int rtti() const; + virtual void draw( QPainter*, const QwtScaleMap&, + const QwtScaleMap&, const QRect& ) const; + + void setBaseline( double ); + double baseline() const; + + void setHistogramAttribute( HistogramAttribute, bool = true ); + bool testHistogramAttribute( HistogramAttribute ) const; + +protected: + virtual void drawBar( QPainter*, Qt::Orientation, const QRect& ) const; + +private: + void init(); + +private: + int myAttributes; + QwtIntervalData myData; + QColor myColor; + double myReference; +}; + +class PLOT2D_EXPORT Plot2d_HistogramItem : public Plot2d_HistogramQwtItem +{ +public: + explicit Plot2d_HistogramItem( const QString& = QString() ); + explicit Plot2d_HistogramItem( const QwtText& ); + virtual ~Plot2d_HistogramItem(); + + QList getBars() const; + + virtual void updateLegend( QwtLegend* ) const; + virtual void draw( QPainter*, const QwtScaleMap&, + const QwtScaleMap&, const QRect& ) const; + + void setCrossItems( bool theCross ); + bool isCrossItems() const; + +protected: + void drawRectAndLowers( QPainter*, Qt::Orientation, + const QRect& ) const; + int getCrossedTop( const QRect& ) const; + +protected: + QList myBarItems; + bool myCrossed; +}; + +#endif // PLOT2D_PLOTITEMS_H diff --git a/src/Plot2d/Plot2d_Prs.cxx b/src/Plot2d/Plot2d_Prs.cxx index b582f3dab..3288c3880 100755 --- a/src/Plot2d/Plot2d_Prs.cxx +++ b/src/Plot2d/Plot2d_Prs.cxx @@ -20,13 +20,6 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME OCCViewer : build OCC Viewer into Salome desktop -// File : Plot2d_Prs.cxx -// Author : Sergey ANIKIN -// Module : SALOME -// $Header$ -// -#include #include "Plot2d_Prs.h" /*! @@ -40,7 +33,7 @@ Plot2d_Prs::Plot2d_Prs( bool theDelete ) /*! Standard constructor */ -Plot2d_Prs::Plot2d_Prs( const Plot2d_Curve* obj, bool theDelete ) +Plot2d_Prs::Plot2d_Prs( Plot2d_Object* obj, bool theDelete ) : mySecondY( false), myIsAutoDel( theDelete ) { AddObject( obj ); @@ -52,23 +45,23 @@ Plot2d_Prs::Plot2d_Prs( const Plot2d_Curve* obj, bool theDelete ) Plot2d_Prs::~Plot2d_Prs() { if ( myIsAutoDel ) - qDeleteAll( myCurves ); + qDeleteAll( myObjects ); } /*! - Get curves list + Get objects list */ -curveList Plot2d_Prs::getCurves() const +objectList Plot2d_Prs::getObjects() const { - return myCurves; + return myObjects; } /*! Add curve */ -void Plot2d_Prs::AddObject( const Plot2d_Curve* obj ) +void Plot2d_Prs::AddObject( Plot2d_Object* obj ) { - myCurves.append((Plot2d_Curve*)obj); + myObjects.append(obj); if (obj->getYAxis() == QwtPlot::yRight) mySecondY = true; @@ -79,7 +72,7 @@ void Plot2d_Prs::AddObject( const Plot2d_Curve* obj ) */ bool Plot2d_Prs::IsNull() const { - return myCurves.isEmpty(); + return myObjects.isEmpty(); } /*! diff --git a/src/Plot2d/Plot2d_Prs.h b/src/Plot2d/Plot2d_Prs.h index 760b3eb2d..99d7aeaa8 100755 --- a/src/Plot2d/Plot2d_Prs.h +++ b/src/Plot2d/Plot2d_Prs.h @@ -24,28 +24,28 @@ #define PLOT2D_PRS_H #include "Plot2d.h" -#include "Plot2d_Curve.h" +#include "Plot2d_Object.h" class PLOT2D_EXPORT Plot2d_Prs { public: Plot2d_Prs( bool theDelete = false ); - Plot2d_Prs( const Plot2d_Curve* obj, bool theDelete = false ); + Plot2d_Prs( Plot2d_Object* obj, bool theDelete = false ); ~Plot2d_Prs(); - curveList getCurves() const; - void AddObject( const Plot2d_Curve* obj ); + objectList getObjects() const; + void AddObject( Plot2d_Object* obj ); - bool IsNull() const; + bool IsNull() const; - bool isSecondY() const; + bool isSecondY() const; - void setAutoDel(bool theDel); + void setAutoDel(bool theDel); protected: - curveList myCurves; - bool mySecondY; - bool myIsAutoDel; + objectList myObjects; + bool mySecondY; + bool myIsAutoDel; }; -#endif +#endif // PLOT2D_PRS_H diff --git a/src/Plot2d/Plot2d_ToolTip.cxx b/src/Plot2d/Plot2d_ToolTip.cxx index 7b7c8f944..af10986a0 100644 --- a/src/Plot2d/Plot2d_ToolTip.cxx +++ b/src/Plot2d/Plot2d_ToolTip.cxx @@ -19,10 +19,9 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : Plot2d_ToolTip.cxx +// Author : Alexandre SOLOVYOV, Open CASCADE S.A.S. (alexander.solovyov@opencascade.com) -// File: Plot2d_ToolTip.cxx -// Author: Alexandre SOLOVYOV -// #include "Plot2d_ToolTip.h" #include "Plot2d_ViewFrame.h" #include "Plot2d_Curve.h" @@ -37,10 +36,9 @@ const int maxDist = 3, tip_margin = 10; -Plot2d_ToolTip::Plot2d_ToolTip( Plot2d_ViewFrame* frame, Plot2d_Plot2d* plot ) -: QtxToolTip( plot->canvas() ), - myFrame( frame ), - myPlot( plot ) +Plot2d_ToolTip::Plot2d_ToolTip( Plot2d_ViewFrame* frame ) +: QtxToolTip( frame->getPlotCanvas() ), + myFrame( frame ) { connect( this, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ), this, SLOT( onToolTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) ); @@ -55,7 +53,7 @@ void Plot2d_ToolTip::onToolTip( QPoint p, QString& str, QFont& f, QRect& txtRect int pInd; double dist; - Plot2d_Curve* c = myPlot->getClosestCurve( p, dist, pInd ); + Plot2d_Curve* c = myFrame->getClosestCurve( p, dist, pInd ); if( !c || dist>maxDist ) return; diff --git a/src/Plot2d/Plot2d_ToolTip.h b/src/Plot2d/Plot2d_ToolTip.h index 9c4b09e68..7fb28a7f4 100644 --- a/src/Plot2d/Plot2d_ToolTip.h +++ b/src/Plot2d/Plot2d_ToolTip.h @@ -19,10 +19,9 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : Plot2d_ToolTip.h +// Author : Alexandre SOLOVYOV, Open CASCADE S.A.S. (alexander.solovyov@opencascade.com) -// File: Plot2d_ToolTip.h -// Author: Alexandre SOLOVYOV -// #ifndef PLOT2D_TOOLTIP_H #define PLOT2D_TOOLTIP_H @@ -30,14 +29,13 @@ #include class Plot2d_ViewFrame; -class Plot2d_Plot2d; class PLOT2D_EXPORT Plot2d_ToolTip : public QtxToolTip { Q_OBJECT public: - Plot2d_ToolTip( Plot2d_ViewFrame*, Plot2d_Plot2d* ); + Plot2d_ToolTip( Plot2d_ViewFrame* ); virtual ~Plot2d_ToolTip(); virtual bool eventFilter( QObject*, QEvent* ); @@ -47,7 +45,6 @@ public slots: private: Plot2d_ViewFrame* myFrame; - Plot2d_Plot2d* myPlot; }; -#endif +#endif // PLOT2D_TOOLTIP_H diff --git a/src/Plot2d/Plot2d_ViewFrame.cxx b/src/Plot2d/Plot2d_ViewFrame.cxx index 0380785c9..489fff70b 100755 --- a/src/Plot2d/Plot2d_ViewFrame.cxx +++ b/src/Plot2d/Plot2d_ViewFrame.cxx @@ -24,6 +24,7 @@ #include "Plot2d_Prs.h" #include "Plot2d_Curve.h" +#include "Plot2d_PlotItems.h" #include "Plot2d_FitDataDlg.h" #include "Plot2d_ViewWindow.h" #include "Plot2d_SetupViewDlg.h" @@ -149,41 +150,6 @@ const char* imageCrossCursor[] = { "................................", "................................"}; -const char* yAxisLeft[] = { - "12 12 2 1", - " c None", - ". c #000000", - " ", - " . ", - " ... ", - " . . . ", - " . ", - " . ", - " . . ", - " . . ", - " ........ ", - " . ", - " . ", - " "}; - -const char* yAxisRight[] = { - "12 12 2 1", - " c None", - ". c #000000", - " ", - " . ", - " ... ", - " . . . ", - " . ", - " . ", - " . . ", - " . . ", - " ........ ", - " . ", - " . ", - " "}; - - /*! Constructor */ @@ -193,21 +159,21 @@ Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title ) myCurveType( 1 ), myShowLegend( true ), myLegendPos( 1 ), myMarkerSize( DEFAULT_MARKER_SIZE ), - myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ), myBackground( Qt::white ), + myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ), myTitleEnabled( true ), myXTitleEnabled( true ), myYTitleEnabled( true ), myY2TitleEnabled (true), myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ), myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ), myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ), myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ), - myXMode( 0 ), myYMode( 0 ), mySecondY( false ) + myXMode( 0 ), myYMode( 0 ), mySecondY( false ), myIsDefTitle( true ) { setObjectName( title ); /* Plot 2d View */ QVBoxLayout* aLayout = new QVBoxLayout( this ); myPlot = new Plot2d_Plot2d( this ); - new Plot2d_ToolTip( this, myPlot ); + new Plot2d_ToolTip( this ); aLayout->addWidget( myPlot ); @@ -239,6 +205,8 @@ Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title ) if (mySecondY) setTitle( myY2TitleEnabled, myY2Title, Y2Title, false ); + setHorScaleMode( myXMode, false ); + setVerScaleMode( myYMode, false ); setBackgroundColor( myBackground ); setLegendPos( myLegendPos ); showLegend( myShowLegend, false ); @@ -276,11 +244,10 @@ QWidget* Plot2d_ViewFrame::getViewWidget() */ void Plot2d_ViewFrame::DisplayAll() { - curveList clist; - getCurves( clist ); - for ( int i = 0; i < (int)clist.count(); i++ ) { - updateCurve( clist.at( i ), false ); - } + objectList olist; + getObjects( olist ); + foreach ( Plot2d_Object* o, olist ) + updateObject( o, false ); myPlot->replot(); if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(); } @@ -289,8 +256,10 @@ void Plot2d_ViewFrame::DisplayAll() */ void Plot2d_ViewFrame::EraseAll() { - myPlot->clear(); - myPlot->getCurves().clear(); + objectList anObjects; + getObjects( anObjects ); + eraseObjects( anObjects, false ); + myObjects.clear(); myPlot->replot(); if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(); } @@ -309,11 +278,11 @@ void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs ) if ( !prs || prs->IsNull() ) return; - mySecondY = prs->isSecondY(); + setEnableAxis( QwtPlot::yRight, prs->isSecondY() ); // VSR: is it correct? maybe we should only enable second Y axis if required - // display all curves from presentation - curveList aCurves = prs->getCurves(); - displayCurves( aCurves ); + // display all objects from presentation + objectList anObjects = prs->getObjects(); + displayObjects( anObjects ); setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true ); setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor, myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true ); @@ -328,9 +297,9 @@ void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool ) if ( !prs || prs->IsNull() ) return; - // erase all curves from presentation - curveList aCurves = prs->getCurves(); - eraseCurves( aCurves ); + // erase all objects from presentation + objectList anObjects = prs->getObjects(); + eraseObjects( anObjects ); if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(); } @@ -382,6 +351,15 @@ bool Plot2d_ViewFrame::eventFilter( QObject* watched, QEvent* e ) void Plot2d_ViewFrame::setTitle( const QString& title ) { setTitle( myTitleEnabled, title, MainTitle, true ); + myIsDefTitle = false; +} + +/*! + Gets title +*/ +QString Plot2d_ViewFrame::getTitle() const +{ + return myTitle; } /*! @@ -422,13 +400,8 @@ void Plot2d_ViewFrame::readPreferences() if ( mySecondY ) myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor ); - int newXMode = resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode ); - newXMode = qMax( 0, qMin( 1, newXMode ) ); - setHorScaleMode( newXMode, false ); - - int newYMode = resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode ); - newYMode = qMax( 0, qMin( 1, newYMode ) ); - setVerScaleMode( newYMode, false ); + setHorScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode ) ) ), false ); + setVerScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode ) ) ), false ); } /*! @@ -581,55 +554,115 @@ QString Plot2d_ViewFrame::getInfo( const QPoint& pnt ) */ void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update ) { - if ( !curve ) + displayObject( curve, update ); +} + +/*! + Adds curves into view +*/ +void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update ) +{ + objectList objects; + foreach ( Plot2d_Curve* curve, curves ) + objects << curve; + displayObjects( objects, update ); +} + +/*! + Erases curve +*/ +void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update ) +{ + eraseObject( curve, update ); +} + +/*! + Erases curves +*/ +void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update ) +{ + objectList objects; + foreach ( Plot2d_Curve* curve, curves ) + objects << curve; + eraseObjects( objects, update ); +} + +/*! + Updates curves attributes +*/ +void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update ) +{ + updateObject( curve, update ); +} + +/*! + Gets lsit of displayed curves +*/ +int Plot2d_ViewFrame::getCurves( curveList& curves ) const +{ + curves.clear(); + + CurveDict aCurves = getCurves(); + CurveDict::iterator it; + for ( it = aCurves.begin(); it != aCurves.end(); it++ ) + curves << it.value(); + return curves.count(); +} + +CurveDict Plot2d_ViewFrame::getCurves() const +{ + CurveDict curves; + ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end(); + for ( ; it != aLast; it++ ) { + QwtPlotItem* anItem = it.key(); + if ( anItem && anItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) { + QwtPlotCurve* aPCurve = dynamic_cast( anItem ); + Plot2d_Curve* aCurve = dynamic_cast( it.value() ); + if ( aPCurve && aCurve ) + curves.insert( aPCurve, aCurve ); + } + } + return curves; +} + +/*! + Adds object into view +*/ +void Plot2d_ViewFrame::displayObject( Plot2d_Object* object, bool update ) +{ + if ( !object ) return; - if ( curve->getYAxis() == QwtPlot::yRight ) + if ( object->getYAxis() == QwtPlot::yRight ) mySecondY = true; // san -- Protection against QwtCurve bug in Qwt 0.4.x: // it crashes if switched to X/Y logarithmic mode, when one or more points have // non-positive X/Y coordinate - if ( myXMode && curve->getMinX() <= 0. ) + if ( myXMode && object->getMinX() <= 0. ) setHorScaleMode( 0, false ); - if ( myYMode && curve->getMinY() <= 0. ) + if ( myYMode && object->getMinY() <= 0. ) setVerScaleMode( 0, false ); - if ( hasPlotCurve( curve ) ) { - updateCurve( curve, update ); + if ( hasPlotObject( object ) ) { + updateObject( object, update ); } else { - Plot2d_QwtPlotCurve* aPCurve = new Plot2d_QwtPlotCurve( curve->getVerTitle(), curve->getYAxis() ); - aPCurve->attach( myPlot ); - aPCurve->setYAxis( curve->getYAxis() ); - - myPlot->getCurves().insert( aPCurve, curve ); - if ( curve->isAutoAssign() ) { - QwtSymbol::Style typeMarker; - QColor color; - Qt::PenStyle typeLine; - - myPlot->getNextMarker( typeMarker, color, typeLine ); - aPCurve->setPen( QPen( color, DEFAULT_LINE_WIDTH, typeLine ) ); - aPCurve->setSymbol( QwtSymbol( typeMarker, - QBrush( color ), - QPen( color ), - QSize( myMarkerSize, myMarkerSize ) ) ); - curve->setColor( color ); - curve->setLine( Plot2d::qwt2plotLine( typeLine ) ); - curve->setMarker( Plot2d::qwt2plotMarker( typeMarker ) ); - } - else { - Qt::PenStyle ps = Plot2d::plot2qwtLine( curve->getLine() ); - QwtSymbol::Style ms = Plot2d::plot2qwtMarker( curve->getMarker() ); - aPCurve->setPen( QPen( curve->getColor(), curve->getLineWidth(), ps ) ); - aPCurve->setSymbol( QwtSymbol( ms, - QBrush( curve->getColor() ), - QPen( curve->getColor() ), - QSize( myMarkerSize, myMarkerSize ) ) ); + if ( object->isAutoAssign() ) + object->autoFill( myPlot ); + QwtPlotItem* anItem = object->createPlotItem(); + anItem->attach( myPlot ); + myObjects.insert( anItem, object ); + //myPlot->setCurveYAxis(curveKey, curve->getYAxis()); + + if ( object->rtti() == QwtPlotItem::Rtti_PlotCurve ) { + Plot2d_Curve* aCurve = dynamic_cast( object ); + if ( aCurve ) { + aCurve->setMarkerSize( myMarkerSize ); + aCurve->updatePlotItem( anItem ); + setCurveType( getPlotCurve( aCurve ), myCurveType ); + } } - setCurveType( aPCurve, myCurveType ); - aPCurve->setData( curve->horData(), curve->verData(), curve->nbPoints() ); } updateTitles(); myPlot->updateYAxisIdentifiers(); @@ -639,17 +672,13 @@ void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update ) } /*! - Adds curves into view + Adds objects into view */ -void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update ) +void Plot2d_ViewFrame::displayObjects( const objectList& objects, bool update ) { //myPlot->setUpdatesEnabled( false ); // call this function deprecate update of legend - curveList::const_iterator it = curves.begin(); - Plot2d_Curve* aCurve; - for (; it != curves.end(); ++it ) { - aCurve = *it; - displayCurve( aCurve, false ); - } + foreach ( Plot2d_Object* object, objects ) + displayObject( object, false ); fitAll(); //myPlot->setUpdatesEnabled( true ); // update legend @@ -658,17 +687,18 @@ void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update ) } /*! - Erases curve + Erases object */ -void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update ) +void Plot2d_ViewFrame::eraseObject( Plot2d_Object* object, bool update ) { - if ( !curve ) + if ( !object ) return; - if ( hasPlotCurve( curve ) ) { - QwtPlotCurve* aPCurve = getPlotCurve( curve ); - aPCurve->hide(); - aPCurve->detach(); - myPlot->getCurves().remove( aPCurve ); + + if ( hasPlotObject( object ) ) { + QwtPlotItem* anObject = getPlotObject( object ); + anObject->hide(); + anObject->detach(); + myObjects.remove( anObject ); updateTitles(); myPlot->updateYAxisIdentifiers(); if ( update ) @@ -678,43 +708,32 @@ void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update ) } /*! - Erases curves + Erases objects */ -void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update ) +void Plot2d_ViewFrame::eraseObjects( const objectList& objects, bool update ) { - curveList::const_iterator it = curves.begin(); - Plot2d_Curve* aCurve; - for (; it != curves.end(); ++it ) { - aCurve = *it; - eraseCurve( aCurve, false ); - } -// fitAll(); + foreach ( Plot2d_Object* object, objects ) + eraseObject( object, false ); + + // fitAll(); if ( update ) myPlot->replot(); if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(); } /*! - Updates curves attributes + Updates objects attributes */ -void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update ) +void Plot2d_ViewFrame::updateObject( Plot2d_Object* object, bool update ) { - if ( !curve ) + if ( !object ) return; - if ( hasPlotCurve( curve ) ) { - QwtPlotCurve* aPCurve = getPlotCurve( curve ); - if ( !curve->isAutoAssign() ) { - Qt::PenStyle ps = Plot2d::plot2qwtLine( curve->getLine() ); - QwtSymbol::Style ms = Plot2d::plot2qwtMarker( curve->getMarker() ); - aPCurve->setPen ( QPen( curve->getColor(), curve->getLineWidth(), ps ) ); - aPCurve->setSymbol( QwtSymbol( ms, - QBrush( curve->getColor() ), - QPen( curve->getColor() ), - QSize( myMarkerSize, myMarkerSize ) ) ); - aPCurve->setData( curve->horData(), curve->verData(), curve->nbPoints() ); - } - aPCurve->setTitle( curve->getVerTitle() ); - aPCurve->setVisible( true ); + if ( hasPlotObject( object ) ) { + QwtPlotItem* anItem = getPlotObject( object ); + if ( !anItem ) + return; + object->updatePlotItem( anItem ); + anItem->setVisible( true ); if ( update ) myPlot->replot(); if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(); @@ -724,32 +743,22 @@ void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update ) /*! Gets lsit of displayed curves */ -int Plot2d_ViewFrame::getCurves( curveList& clist ) +int Plot2d_ViewFrame::getObjects( objectList& objects ) const { - clist.clear(); - - CurveDict::iterator it = myPlot->getCurves().begin(); - for ( ; it != myPlot->getCurves().end(); it++ ) - clist.append( it.value() ); - return clist.count(); -} + objects.clear(); -const CurveDict& Plot2d_ViewFrame::getCurves() -{ - return myPlot->getCurves(); + ObjectDict::const_iterator it; + for ( it = myObjects.begin(); it != myObjects.end(); it++ ) + objects << it.value(); + return objects.count(); } /*! Returns true if the curve is visible */ -bool Plot2d_ViewFrame::isVisible( Plot2d_Curve* curve ) +bool Plot2d_ViewFrame::isVisible( Plot2d_Object* object ) const { - if(curve) { - if ( hasPlotCurve( curve ) ) { - return getPlotCurve( curve )->isVisible(); - } - } - return false; + return object && hasPlotObject( object ) && getPlotObject( object )->isVisible(); } /*! @@ -759,14 +768,14 @@ void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs ) { if ( !prs || prs->IsNull() ) return; - curveList aCurves = prs->getCurves(); - curveList::iterator it = aCurves.begin(); - Plot2d_Curve* aCurve; - for (; it != aCurves.end(); ++it ) { - aCurve = *it; - if ( hasPlotCurve( aCurve ) ) - getPlotCurve( aCurve )->setTitle( aCurve->getVerTitle() ); + ObjectDict::iterator it = myObjects.begin(); + Plot2d_Object* anObj; + for (; it != myObjects.end(); ++it ) { + anObj = *it; + if ( hasPlotObject( anObj ) ) + getPlotObject( anObj )->setTitle( !anObj->getName().isEmpty() ? + anObj->getName() : anObj->getVerTitle() ); } } @@ -880,11 +889,10 @@ void Plot2d_ViewFrame::getFitRangeByCurves(double& xMin, double& xMax, double& yMin, double& yMax, double& y2Min, double& y2Max) { - CurveDict cdict = getCurves(); bool emptyV1 = true, emptyV2 = true; - if ( !cdict.isEmpty() ) { - CurveDict::const_iterator it = myPlot->getCurves().begin(); - for ( ; it != myPlot->getCurves().end(); it++ ) { + if ( !myObjects.isEmpty() ) { + ObjectDict::const_iterator it = myObjects.begin(); + for ( ; it != myObjects.end(); it++ ) { bool isV2 = it.value()->getYAxis() == QwtPlot::yRight; if ( !it.value()->isEmpty() ) { if ( emptyV1 && emptyV2 ) { @@ -950,21 +958,22 @@ int Plot2d_ViewFrame::testOperation( const QMouseEvent& me ) const int panBtn = Qt::ControlModifier | Qt::MidButton; const int fitBtn = Qt::ControlModifier | Qt::RightButton; + int op = NoOpId; if ( btn == zoomBtn ) { QPixmap zoomPixmap (imageZoomCursor); QCursor zoomCursor (zoomPixmap); myPlot->canvas()->setCursor( zoomCursor ); - return ZoomId; + op = ZoomId; } else if ( btn == panBtn ) { myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) ); - return PanId; + op = PanId; } else if ( btn == fitBtn ) { myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) ); - return FitAreaId; + op = FitAreaId; } - return NoOpId; + return op; } /*! @@ -1038,6 +1047,8 @@ void Plot2d_ViewFrame::onSettings() setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false ); // main title + if( dlg->isMainTitleEnabled() && myTitle != dlg->getMainTitle() ) + myIsDefTitle = false; setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true ); // curve type if ( myCurveType != dlg->getCurveType() ) { @@ -1119,8 +1130,9 @@ void Plot2d_ViewFrame::onChangeBackground() void Plot2d_ViewFrame::setCurveType( int curveType, bool update ) { myCurveType = curveType; - CurveDict::iterator it = myPlot->getCurves().begin(); - for ( ; it != myPlot->getCurves().end(); it++ ) { + CurveDict aCurves = getCurves(); + CurveDict::iterator it = aCurves.begin(); + for ( ; it != aCurves.end(); it++ ) { QwtPlotCurve* crv = it.key(); if ( crv ) setCurveType( crv, myCurveType ); @@ -1130,15 +1142,33 @@ void Plot2d_ViewFrame::setCurveType( int curveType, bool update ) emit vpCurveChanged(); } +/*! + Gets curve type +*/ +int Plot2d_ViewFrame::getCurveType() const +{ + return myCurveType; +} + /*! Sets curve title \param curveKey - curve id \param title - new title */ void Plot2d_ViewFrame::setCurveTitle( Plot2d_Curve* curve, const QString& title ) +{ + setObjectTitle( curve, title ); +} + +/*! + Sets object title + \param object - object id + \param title - new title +*/ +void Plot2d_ViewFrame::setObjectTitle( Plot2d_Object* object, const QString& title ) { - if ( curve && hasPlotCurve( curve ) ) - getPlotCurve( curve )->setTitle( title ); + if ( object && hasPlotObject( object ) ) + getPlotObject( object )->setTitle( title ); } /*! @@ -1188,6 +1218,14 @@ void Plot2d_ViewFrame::setLegendPos( int pos ) } } +/*! + Gets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom +*/ +int Plot2d_ViewFrame::getLegendPos() const +{ + return myLegendPos; +} + /*! Sets new marker size */ @@ -1196,8 +1234,9 @@ void Plot2d_ViewFrame::setMarkerSize( const int size, bool update ) if ( myMarkerSize != size ) { myMarkerSize = size; - CurveDict::iterator it = myPlot->getCurves().begin(); - for ( ; it != myPlot->getCurves().end(); it++ ) { + CurveDict aCurves = getCurves(); + CurveDict::iterator it = aCurves.begin(); + for ( ; it != aCurves.end(); it++ ) { QwtPlotCurve* crv = it.key(); if ( crv ) { @@ -1211,6 +1250,14 @@ void Plot2d_ViewFrame::setMarkerSize( const int size, bool update ) } } +/*! + Gets new marker size +*/ +int Plot2d_ViewFrame::getMarkerSize() const +{ + return myMarkerSize; +} + /*! Sets background color */ @@ -1343,6 +1390,8 @@ void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title, myY2Title = title; myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString() ); break; + default: + break; } if ( update ) myPlot->replot(); @@ -1362,6 +1411,8 @@ QString Plot2d_ViewFrame::getTitle( ObjectType type ) const title = myYTitle; break; case Y2Title: title = myY2Title; break; + default: + break; } return title; } @@ -1390,6 +1441,7 @@ void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update) if ( update ) myPlot->replot(); } + /*! Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic */ @@ -1414,6 +1466,15 @@ void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update ) fitAll(); emit vpModeHorChanged(); } + +/*! + Gets scale mode for horizontal axis: 0 - linear, 1 - logarithmic +*/ +int Plot2d_ViewFrame::getHorScaleMode() const +{ + return myXMode; +} + /*! Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic */ @@ -1440,6 +1501,14 @@ void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update ) emit vpModeVerChanged(); } +/*! + Gets scale mode for vertical axis: 0 - linear, 1 - logarithmic +*/ +int Plot2d_ViewFrame::getVerScaleMode() const +{ + return myYMode; +} + /*! Return, scale mode for horizontal axis */ @@ -1455,6 +1524,15 @@ bool Plot2d_ViewFrame::isModeVerLinear() { return (myYMode == 0 ? true : false); } + +/*! + Return \c True if legend is shown +*/ +bool Plot2d_ViewFrame::isLegendShow() const +{ + return myShowLegend; +} + /*! Slot, called when user presses mouse button */ @@ -1568,11 +1646,26 @@ void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event) /*! Returns qwt plot curve if it is existed in map of curves and 0 otherwise */ -QwtPlotCurve* Plot2d_ViewFrame::getPlotCurve( Plot2d_Curve* curve ) +QwtPlotCurve* Plot2d_ViewFrame::getPlotCurve( Plot2d_Curve* curve ) const +{ + return dynamic_cast( getPlotObject( curve ) ); +} +/*! + Returns true if qwt plot curve is existed in map of curves and false otherwise +*/ +bool Plot2d_ViewFrame::hasPlotCurve( Plot2d_Curve* curve ) const { - CurveDict::iterator it = myPlot->getCurves().begin(); - for ( ; it != myPlot->getCurves().end(); it++ ) { - if ( it.value() == curve ) + return hasPlotObject( curve ); +} + +/*! + Returns qwt plot curve if it is existed in map of curves and 0 otherwise +*/ +QwtPlotItem* Plot2d_ViewFrame::getPlotObject( Plot2d_Object* object ) const +{ + ObjectDict::const_iterator it = myObjects.begin(); + for ( ; it != myObjects.end(); it++ ) { + if ( it.value() == object ) return it.key(); } return 0; @@ -1580,11 +1673,11 @@ QwtPlotCurve* Plot2d_ViewFrame::getPlotCurve( Plot2d_Curve* curve ) /*! Returns true if qwt plot curve is existed in map of curves and false otherwise */ -bool Plot2d_ViewFrame::hasPlotCurve( Plot2d_Curve* curve ) +bool Plot2d_ViewFrame::hasPlotObject( Plot2d_Object* object ) const { - CurveDict::iterator it = myPlot->getCurves().begin(); - for ( ; it != myPlot->getCurves().end(); it++ ) { - if ( it.value() == curve ) + ObjectDict::const_iterator it = myObjects.begin(); + for ( ; it != myObjects.end(); it++ ) { + if ( it.value() == object ) return true; } return false; @@ -1680,8 +1773,8 @@ void Plot2d_ViewFrame::onViewGlobalPan() bool Plot2d_ViewFrame::isXLogEnabled() const { bool allPositive = true; - CurveDict::const_iterator it = myPlot->getCurves().begin(); - for ( ; allPositive && it != myPlot->getCurves().end(); it++ ) + ObjectDict::const_iterator it = myObjects.begin(); + for ( ; allPositive && it != myObjects.end(); it++ ) allPositive = ( it.value()->getMinX() > 0. ); return allPositive; } @@ -1692,12 +1785,24 @@ bool Plot2d_ViewFrame::isXLogEnabled() const bool Plot2d_ViewFrame::isYLogEnabled() const { bool allPositive = true; - CurveDict::const_iterator it = myPlot->getCurves().begin(); - for ( ; allPositive && it != myPlot->getCurves().end(); it++ ) + ObjectDict::const_iterator it = myObjects.begin(); + for ( ; allPositive && it != myObjects.end(); it++ ) allPositive = ( it.value()->getMinY() > 0. ); return allPositive; } +/** + * + */ +void Plot2d_ViewFrame::setEnableAxis( QwtPlot::Axis theAxis, bool isEnable ) +{ + if ( myPlot->axisEnabled( theAxis ) == isEnable ) + return; + myPlot->enableAxis( theAxis, isEnable ); + if ( theAxis == QwtPlot::yRight ) + mySecondY = isEnable; +} + class Plot2d_QwtPlotZoomer : public QwtPlotZoomer { public: @@ -1754,6 +1859,12 @@ Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent ) myPlotZoomer->setEnabled( true ); myPlotZoomer->setZoomBase(); + + setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); +} + +Plot2d_Plot2d::~Plot2d_Plot2d() +{ } /*! @@ -1773,17 +1884,18 @@ void Plot2d_Plot2d::setLogScale( int axisId, bool log10 ) void Plot2d_Plot2d::replot() { // the following code is intended to enable only axes - // that are really used by displayed curves - bool enableXBottom = false, enableXTop = false; - bool enableYLeft = false, enableYRight = false; - CurveDict::iterator it = myCurves.begin(); - for( ; it != myCurves.end(); it++ ) { - QwtPlotCurve* aCurve = it.key(); - if( aCurve ) { - enableXBottom |= aCurve->xAxis() == QwtPlot::xBottom; - enableXTop |= aCurve->xAxis() == QwtPlot::xTop; - enableYLeft |= aCurve->yAxis() == QwtPlot::yLeft; - enableYRight |= aCurve->yAxis() == QwtPlot::yRight; + // that are really used by displayed objects + bool enableXBottom = false, enableXTop = false; + bool enableYLeft = false, enableYRight = false; + const QwtPlotItemList& items = itemList(); + QwtPlotItemIterator it; + for ( it = items.begin(); it != items.end(); it++ ) { + QwtPlotItem* item = *it; + if ( item ) { + enableXBottom |= item->xAxis() == QwtPlot::xBottom; + enableXTop |= item->xAxis() == QwtPlot::xTop; + enableYLeft |= item->yAxis() == QwtPlot::yLeft; + enableYRight |= item->yAxis() == QwtPlot::yRight; } } enableAxis( QwtPlot::xBottom, enableXBottom ); @@ -1796,111 +1908,15 @@ void Plot2d_Plot2d::replot() } /*! - Checks if two colors are close to each other [ static ] - uses COLOR_DISTANCE variable as max tolerance for comparing of colors -*/ -const long COLOR_DISTANCE = 100; -const int MAX_ATTEMPTS = 10; -static bool closeColors( const QColor& color1, const QColor& color2 ) -{ - long tol = abs( color2.red() - color1.red() ) + - abs( color2.green() - color1.green() ) + - abs( color2.blue() - color1.blue() ); - - return ( tol <= COLOR_DISTANCE ); -} -/*! - Gets new unique marker for item if possible + Get legend */ -void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine ) +QwtLegend* Plot2d_Plot2d::getLegend() { - bool bOk = false; - int cnt = 1; - while ( !bOk ) { - int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color - int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ... - int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ... - int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1; // 9 markers types ( not including empty ) - int aLine = (int)( 5.0 * rand() / RAND_MAX) + 1; // 5 line types ( not including empty ) - - typeMarker = ( QwtSymbol::Style )aMarker; - color = QColor( aRed, aGreen, aBlue ); - typeLine = ( Qt::PenStyle )aLine; - - cnt++; - if ( cnt == MAX_ATTEMPTS ) - bOk = true; - else - bOk = !existMarker( typeMarker, color, typeLine ); - } -/* - static int aMarker = -1; - static int aColor = -1; - static int aLine = -1; - - if ( myColors.isEmpty() ) { - // creating colors list - myColors.append( Qt::white ); - myColors.append( Qt::blue ); - myColors.append( Qt::gray ); - myColors.append( Qt::darkGreen ); - myColors.append( Qt::magenta ); - myColors.append( Qt::darkGray ); - myColors.append( Qt::red ); - myColors.append( Qt::darkBlue ); - myColors.append( Qt::darkYellow ); - myColors.append( Qt::cyan ); - myColors.append( Qt::darkRed ); - myColors.append( Qt::darkCyan ); - myColors.append( Qt::yellow ); - myColors.append( Qt::darkMagenta ); - myColors.append( Qt::green ); - myColors.append( Qt::black ); - } - - int nbMarkers = 11; // QwtSymbol supports 11 marker types - int nbLines = 6; // Qt supports 6 line types - int nbColors = myColors.count(); // number of default colors supported - - aMarker = ( aMarker + 1 ) % nbMarkers; - if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++; - aColor = ( aColor + 1 ) % nbColors; - aLine = ( aLine + 1 ) % nbLines; - if ( aLine == Qt::NoPen ) aLine++; - - typeMarker = ( QwtSymbol::Style )aMarker; - color = myColors[ aColor ]; - typeLine = ( Qt::PenStyle )aLine; - if ( !existMarker( typeMarker, color, typeLine ) ) - return; - - int i, j, k; - for ( i = 0; i < nbMarkers; i++ ) { - aMarker = ( aMarker + 1 ) % nbMarkers; - if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++; - for ( j = 0; j < nbColors; j++ ) { - aColor = ( aColor + 1 ) % nbColors; - for ( k = 0; k < nbLines; k++ ) { - aLine = ( aLine + 1 ) % nbLines; - if ( aLine == Qt::NoPen ) aLine++; - if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) { - typeMarker = ( QwtSymbol::Style )aMarker; - color = myColors[ aColor ]; - typeLine = ( Qt::PenStyle )aLine; - return; - } - } - } - } -*/ -} - -/*! - \return the default layout behavior of the widget -*/ -QSizePolicy Plot2d_Plot2d::sizePolicy() const -{ - return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); +#if QWT_VERSION < 0x040200 + return d_legend; +#else + return legend(); /* mpv: porting to the Qwt 4.2.0 */ +#endif } /*! @@ -1934,46 +1950,19 @@ void Plot2d_Plot2d::setPickerMousePattern( int button, int state ) myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1, button, state ); } -/*! - return closest curve if it exist, else 0 -*/ -Plot2d_Curve* Plot2d_Plot2d::getClosestCurve( QPoint p, double& distance, int& index ) +bool Plot2d_Plot2d::polished() const { - CurveDict::iterator it = getCurves().begin(); - QwtPlotCurve* aCurve; - for ( ; it != getCurves().end(); it++ ) { - aCurve = it.key(); - if ( !aCurve ) - continue; - index = aCurve->closestPoint( p, &distance ); - if ( index > -1 ) - return it.value(); - } - return 0; + return myIsPolished; } -/*! - Checks if marker belongs to any enitity -*/ -bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine ) +QwtPlotGrid* Plot2d_Plot2d::grid() const { - QColor aColor = palette().color( QPalette::Background ); - if ( closeColors( color, aColor ) ) - return true; + return myGrid; +}; - CurveDict::iterator it = myCurves.begin(); - for ( ; it != myCurves.end(); it++ ) { - QwtPlotCurve* crv = it.key(); - if ( crv ) { - QwtSymbol::Style aStyle = crv->symbol().style(); - QColor aColor = crv->pen().color(); - Qt::PenStyle aLine = crv->pen().style(); -// if ( aStyle == typeMarker && aColor == color && aLine == typeLine ) - if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine ) - return true; - } - } - return false; +QwtPlotZoomer* Plot2d_Plot2d::zoomer() const +{ + return myPlotZoomer; } /*! @@ -2008,7 +1997,7 @@ void Plot2d_Plot2d::onScaleDivChanged() QwtScaleDraw* aQwtSD = axisScaleDraw(axisId); Plot2d_ScaleDraw* aPlot2dSD = dynamic_cast(aQwtSD); - if ( !aPlot2dSD && aPrecision > 6 || aPlot2dSD && aPlot2dSD->precision() != aPrecision ) + if ( ( !aPlot2dSD && aPrecision > 6 ) || ( aPlot2dSD && aPlot2dSD->precision() != aPrecision ) ) setAxisScaleDraw( axisId, new Plot2d_ScaleDraw(*aQwtSD, 'f', aPrecision) ); } } @@ -2020,27 +2009,25 @@ void Plot2d_Plot2d::onScaleDivChanged() void Plot2d_Plot2d::updateYAxisIdentifiers() { bool enableYLeft = false, enableYRight = false; - CurveDict::iterator it = myCurves.begin(); - for( ; it != myCurves.end(); it++ ) { - QwtPlotCurve* aCurve = it.key(); - if( aCurve ) { - enableYLeft |= aCurve->yAxis() == QwtPlot::yLeft; - enableYRight |= aCurve->yAxis() == QwtPlot::yRight; + const QwtPlotItemList& items = itemList(); + QwtPlotItemIterator it; + for ( it = items.begin(); it != items.end(); it++ ) { + QwtPlotItem* item = *it; + if ( item ) { + enableYLeft |= item->yAxis() == QwtPlot::yLeft; + enableYRight |= item->yAxis() == QwtPlot::yRight; } } // if several curves are attached to different axes // display corresponding identifiers in the legend, // otherwise hide them - for( it = myCurves.begin(); it != myCurves.end(); it++ ) - if( Plot2d_QwtPlotCurve* aPCurve = dynamic_cast( it.key() ) ) + for ( it = items.begin(); it != items.end(); it++ ) { + QwtPlotItem* item = *it; + if ( Plot2d_QwtPlotCurve* aPCurve = dynamic_cast( item ) ) aPCurve->setYAxisIdentifierEnabled( enableYLeft && enableYRight ); - - const QwtPlotItemList& anItemList = itemList(); - for( QwtPlotItemIterator anItemIter = anItemList.begin(); anItemIter != anItemList.end(); ++anItemIter ) { - QwtPlotItem* anItem = *anItemIter; - if( anItem && anItem->isVisible() ) - anItem->updateLegend( legend() ); + if ( item && item->isVisible() && legend() ) + item->updateLegend( legend() ); } } @@ -2108,8 +2095,7 @@ void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf ) #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" ) void Plot2d_ViewFrame::updateTitles() { - CurveDict::iterator it = myPlot->getCurves().begin(); - //QIntDictIterator it( myCurves ); + ObjectDict::iterator it = myObjects.begin(); QStringList aXTitles; QStringList aYTitles; QStringList aY2Titles; @@ -2119,32 +2105,33 @@ void Plot2d_ViewFrame::updateTitles() QStringList aTables; int i = 0; - Plot2d_Curve* aCurve; - for ( ; it != myPlot->getCurves().end(); it++ ) { + Plot2d_Object* anObject; + for ( ; it != myObjects.end(); it++ ) { // collect titles and units from all curves... - aCurve = it.value(); - QString xTitle = aCurve->getHorTitle().trimmed(); - QString yTitle = aCurve->getVerTitle().trimmed(); - QString xUnits = aCurve->getHorUnits().trimmed(); - QString yUnits = aCurve->getVerUnits().trimmed(); - bool isY2 = aCurve->getYAxis() == QwtPlot::yRight; + anObject = it.value(); + QString xTitle = anObject->getHorTitle().trimmed(); + QString yTitle = anObject->getVerTitle().trimmed(); + QString xUnits = anObject->getHorUnits().trimmed(); + QString yUnits = anObject->getVerUnits().trimmed(); + if ( anObject->getYAxis() == QwtPlot::yLeft ) { + if ( !aYTitles.contains( yTitle ) ) + aYTitles.append( yTitle ); + if ( !aYUnits.contains( yUnits ) ) + aYUnits.append( yUnits ); + } + else { + if ( !aY2Titles.contains( yTitle ) ) + aY2Titles.append( yTitle ); + if ( !aY2Units.contains( yUnits ) ) + aY2Units.append( yUnits ); + } if ( !aXTitles.contains( xTitle ) ) aXTitles.append( xTitle ); if ( !aXUnits.contains( xUnits ) ) aXUnits.append( xUnits ); - if ( isY2 ) { - aY2Titles.append( yTitle ); - if ( !aY2Units.contains( yUnits ) ) - aY2Units.append( yUnits ); - } - else { - aYTitles.append( yTitle ); - if ( !aYUnits.contains( yUnits ) ) - aYUnits.append( yUnits ); - } - QString aName = aCurve->getTableTitle(); + QString aName = anObject->getTableTitle(); if( !aName.isEmpty() && !aTables.contains( aName ) ) aTables.append( aName ); ++i; @@ -2162,7 +2149,7 @@ void Plot2d_ViewFrame::updateTitles() xTitle = aXTitles[0]; if ( aYTitles.count() == 1 ) yTitle = aYTitles[0]; - if ( aY2Titles.count() == 1 ) + if ( mySecondY && aY2Titles.count() == 1 ) y2Title = aY2Titles[0]; if ( !xTitle.isEmpty() && !xUnits.isEmpty() ) @@ -2176,7 +2163,8 @@ void Plot2d_ViewFrame::updateTitles() setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true ); if ( mySecondY ) setTitle( myY2TitleEnabled, y2Title + y2Units, Y2Title, true ); - setTitle( true, aTables.join("; "), MainTitle, true ); + if( myIsDefTitle ) + setTitle( true, aTables.join("; "), MainTitle, true ); } /*! @@ -2214,6 +2202,15 @@ bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const #endif } +/** + * Print Plot2d window + */ +void Plot2d_ViewFrame::printPlot( QPainter* p, const QRect& rect, + const QwtPlotPrintFilter& filter ) const +{ + myPlot->print( p, rect, filter ); +} + /*! \return string with all visual parameters */ @@ -2301,6 +2298,33 @@ void Plot2d_ViewFrame::incrementalZoom( const int incrX, const int incrY ) { myPlot->replot(); } +/** + * + */ +QwtPlotCanvas* Plot2d_ViewFrame::getPlotCanvas() const +{ + return myPlot ? myPlot->canvas() : 0; +} + +/*! + return closest curve if it exist, else 0 +*/ +Plot2d_Curve* Plot2d_ViewFrame::getClosestCurve( QPoint p, double& distance, int& index ) const +{ + CurveDict aCurves = getCurves(); + CurveDict::iterator it = aCurves.begin(); + QwtPlotCurve* aCurve; + for ( ; it != aCurves.end(); it++ ) { + aCurve = it.key(); + if ( !aCurve ) + continue; + index = aCurve->closestPoint( p, &distance ); + if ( index > -1 ) + return it.value(); + } + return 0; +} + #define INCREMENT_FOR_OP 10 /*! @@ -2396,103 +2420,3 @@ QwtText Plot2d_ScaleDraw::label( double value ) const return QwtScaleDraw::label( value ); } - -/*! - Constructor of Plot2d_QwtLegendItem -*/ -Plot2d_QwtLegendItem::Plot2d_QwtLegendItem( QWidget* parent ) : - QwtLegendItem( parent ), - myYAxisIdentifierMode( IM_None ) -{ - myYAxisLeftIcon = yAxisLeft; - myYAxisRightIcon = yAxisRight; - int anIconWidth = qMax( myYAxisLeftIcon.width(), myYAxisRightIcon.width() ); - - mySpacingCollapsed = spacing(); - mySpacingExpanded = anIconWidth - mySpacingCollapsed; -} - -/*! - Destructor of Plot2d_QwtLegendItem -*/ -Plot2d_QwtLegendItem::~Plot2d_QwtLegendItem() -{ -} - -/*! - Set Y axis identifier displaying mode -*/ -void Plot2d_QwtLegendItem::setYAxisIdentifierMode( const int theMode ) -{ - myYAxisIdentifierMode = theMode; - setSpacing( theMode == IM_None ? mySpacingCollapsed : mySpacingExpanded ); -} - -/*! - Redefined method of drawing identifier of legend item -*/ -void Plot2d_QwtLegendItem::drawIdentifier( QPainter* painter, const QRect& rect ) const -{ - QwtLegendItem::drawIdentifier( painter, rect ); - - if( myYAxisIdentifierMode != IM_None ) { - QPixmap aPixmap( myYAxisIdentifierMode == IM_Left ? yAxisLeft : yAxisRight ); - painter->save(); - painter->drawPixmap( rect.topRight() + QPoint( mySpacingExpanded/2, mySpacingExpanded/2 ), aPixmap ); - painter->restore(); - } -} - -/*! - Constructor of Plot2d_QwtPlotCurve -*/ -Plot2d_QwtPlotCurve::Plot2d_QwtPlotCurve( const QString& title, - QwtPlot::Axis yAxis /*const int index*/ ) : - QwtPlotCurve( title ), - myYAxis( yAxis ), - myYAxisIdentifierEnabled( false ) -{ -} - -/*! - Destructor of Plot2d_QwtPlotCurve -*/ -Plot2d_QwtPlotCurve::~Plot2d_QwtPlotCurve() -{ -} - -/*! - Enable / disable Y axis identifier -*/ -void Plot2d_QwtPlotCurve::setYAxisIdentifierEnabled( const bool on ) -{ - myYAxisIdentifierEnabled = on; -} - -/*! - Redefined method, which updates legend of the curve -*/ -void Plot2d_QwtPlotCurve::updateLegend( QwtLegend* legend ) const -{ - QwtPlotCurve::updateLegend( legend ); - - if ( legend ) { - QWidget* widget = legend->find( this ); - if( Plot2d_QwtLegendItem* anItem = dynamic_cast( widget ) ) { - int aMode = Plot2d_QwtLegendItem::IM_None; - if( myYAxisIdentifierEnabled ) - aMode = myYAxis == QwtPlot::yRight ? - Plot2d_QwtLegendItem::IM_Right : - Plot2d_QwtLegendItem::IM_Left; - anItem->setYAxisIdentifierMode( aMode ); - } - } -} - -/*! - Redefined method, which creates and returns legend item of the curve -*/ -QWidget* Plot2d_QwtPlotCurve::legendItem() const -{ - return new Plot2d_QwtLegendItem; -} diff --git a/src/Plot2d/Plot2d_ViewFrame.h b/src/Plot2d/Plot2d_ViewFrame.h index a903be0b8..e18069c0f 100755 --- a/src/Plot2d/Plot2d_ViewFrame.h +++ b/src/Plot2d/Plot2d_ViewFrame.h @@ -23,163 +23,180 @@ #ifndef PLOT2D_VIEWFRAME_H #define PLOT2D_VIEWFRAME_H +#include "Plot2d.h" #include "Plot2d_Curve.h" + #include #include #include -#include -#include #include #include class Plot2d_Plot2d; class Plot2d_Prs; +class Plot2d_Curve; +class Plot2d_Object; class QCustomEvent; +class QwtPlotItem; class QwtPlotCurve; class QwtPlotGrid; class QwtPlotZoomer; -typedef QMultiHash CurveDict; +typedef QMultiHash CurveDict; +typedef QMultiHash ObjectDict; class PLOT2D_EXPORT Plot2d_ViewFrame : public QWidget { Q_OBJECT - + enum { NoOpId, FitAreaId, ZoomId, PanId, GlPanId, DumpId, - ModeXLinearId, ModeXLogarithmicId, ModeYLinearId, ModeYLogarithmicId, - LegendId, CurvePointsId, CurveLinesId, CurveSplinesId }; + ModeXLinearId, ModeXLogarithmicId, ModeYLinearId, ModeYLogarithmicId, + LegendId, CurvePointsId, CurveLinesId, CurveSplinesId }; public: /* Construction/destruction */ - Plot2d_ViewFrame( QWidget* parent, const QString& title = "" ); + Plot2d_ViewFrame( QWidget*, const QString& = "" ); virtual ~Plot2d_ViewFrame(); enum ObjectType { MainTitle, XTitle, YTitle, Y2Title, XAxis, YAxis, Y2Axis }; -public: - QWidget* getViewWidget(); + QWidget* getViewWidget(); /* display */ - void DisplayAll(); - void EraseAll(); - void Repaint(); + virtual void DisplayAll(); + virtual void EraseAll(); + void Repaint(); - void Display( const Plot2d_Prs* ); - void Erase( const Plot2d_Prs*, const bool = false ); - Plot2d_Prs* CreatePrs( const char* entry = 0 ); + void Display( const Plot2d_Prs* ); + void Erase( const Plot2d_Prs*, const bool = false ); + Plot2d_Prs* CreatePrs( const char* = 0 ); - virtual bool eventFilter(QObject* watched, QEvent* e); + virtual bool eventFilter( QObject*, QEvent* ); /* operations */ - void updateTitles(); - void setTitle( const QString& title ); - QString getTitle() const { return myTitle; } - void displayCurve( Plot2d_Curve* curve, bool update = false ); - void displayCurves( const curveList& curves, bool update = false ); - void eraseCurve( Plot2d_Curve* curve, bool update = false ); - void eraseCurves( const curveList& curves, bool update = false ); - int getCurves( curveList& clist ); - const CurveDict& getCurves(); - bool isVisible( Plot2d_Curve* curve ); - void updateCurve( Plot2d_Curve* curve, bool update = false ); - void updateLegend( const Plot2d_Prs* prs ); - void fitAll(); - void fitArea( const QRect& area ); - void fitData(const int mode, - const double xMin, const double xMax, - const double yMin, const double yMax, - const double y2Min = 0, const double y2Max = 0); - - void getFitRanges(double& xMin, double& xMax, - double& yMin, double& yMax, - double& y2Min, double& y2Max); - - void getFitRangeByCurves(double& xMin, double& xMax, - double& yMin, double& yMax, - double& y2Min, double& y2Max); + void updateTitles(); + void setTitle( const QString& ); + QString getTitle() const; + + /* curves operations [ obsolete ] */ + void displayCurve( Plot2d_Curve*, bool = false ); + void displayCurves( const curveList&, bool = false ); + void eraseCurve( Plot2d_Curve*, bool = false ); + void eraseCurves( const curveList&, bool = false ); + int getCurves( curveList& ) const; + CurveDict getCurves() const; + void updateCurve( Plot2d_Curve*, bool = false ); + + /* objects operations */ + void displayObject( Plot2d_Object*, bool = false ); + void displayObjects( const objectList&, bool = false ); + void eraseObject( Plot2d_Object*, bool = false ); + void eraseObjects( const objectList&, bool = false ); + int getObjects( objectList& ) const; + bool isVisible( Plot2d_Object* ) const; + void updateObject( Plot2d_Object*, bool = false ); + + void updateLegend( const Plot2d_Prs* ); + void fitAll(); + void fitArea( const QRect& ); + void fitData( const int, const double, const double, + const double, const double, + const double = 0, const double = 0 ); + + void getFitRanges( double&, double&, double&, double&, + double&, double&); + + void getFitRangeByCurves( double&, double&, double&, double&, + double&, double& ); /* view parameters */ - void copyPreferences( Plot2d_ViewFrame* ); - void setCurveType( int curveType, bool update = true ); - int getCurveType() const { return myCurveType; } - void setCurveTitle( Plot2d_Curve* curve, const QString& title ); - void showLegend( bool show, bool update = true ); - void setLegendPos( int pos ); - int getLegendPos() const { return myLegendPos; } - void setMarkerSize( const int size, bool update = true ); - int getMarkerSize() const { return myMarkerSize; } - void setBackgroundColor( const QColor& color ); - QColor backgroundColor() const; - void setXGrid( bool xMajorEnabled, const int xMajorMax, - bool xMinorEnabled, const int xMinorMax, bool update = true ); - void setYGrid( bool yMajorEnabled, const int yMajorMax, - bool yMinorEnabled, const int yMinorMax, - bool y2MajorEnabled, const int y2MajorMax, - bool y2MinorEnabled, const int y2MinorMax, bool update = true ); - void setTitle( bool enabled, const QString& title, ObjectType type, bool update = true ); - QString getTitle( ObjectType type ) const; - - void setFont( const QFont& font, ObjectType type, bool update = true ); - void setHorScaleMode( const int mode, bool update = true ); - int getHorScaleMode() const { return myXMode; } - void setVerScaleMode( const int mode, bool update = true ); - int getVerScaleMode() const { return myYMode; } - - bool isModeHorLinear(); - bool isModeVerLinear(); - bool isLegendShow() { return myShowLegend; }; + void copyPreferences( Plot2d_ViewFrame* ); + void setCurveType( int, bool = true ); + int getCurveType() const; + void setCurveTitle( Plot2d_Curve*, const QString& ); + void setObjectTitle( Plot2d_Object*, const QString& ); + void showLegend( bool, bool = true ); + void setLegendPos( int ); + int getLegendPos() const; + void setMarkerSize( const int, bool = true ); + int getMarkerSize() const; + void setBackgroundColor( const QColor& ); + QColor backgroundColor() const; + void setXGrid( bool, const int, bool, const int, bool = true ); + void setYGrid( bool, const int, bool, const int, + bool, const int, bool, const int, bool = true ); + void setTitle( bool, const QString&, ObjectType, bool = true ); + QString getTitle( ObjectType ) const; + + void setFont( const QFont&, ObjectType, bool = true ); + void setHorScaleMode( const int, bool = true ); + int getHorScaleMode() const; + void setVerScaleMode( const int, bool = true ); + int getVerScaleMode() const; + + bool isModeHorLinear(); + bool isModeVerLinear(); + bool isLegendShow() const; // Protection against QwtCurve::drawLines() bug in Qwt 0.4.x: // it crashes if switched to X/Y logarithmic mode, when one or more points have // non-positive X/Y coordinate - bool isXLogEnabled() const; - bool isYLogEnabled() const; + bool isXLogEnabled() const; + bool isYLogEnabled() const; + void setEnableAxis( QwtPlot::Axis, bool ); + + virtual bool print( const QString&, const QString& ) const; + void printPlot( QPainter*, const QRect&, + const QwtPlotPrintFilter& = QwtPlotPrintFilter() ) const; - virtual bool print( const QString& file, const QString& format ) const; + QString getVisualParameters(); + void setVisualParameters( const QString& ); - QString getVisualParameters(); - void setVisualParameters( const QString& parameters ); + void incrementalPan ( const int, const int ); + void incrementalZoom( const int, const int ); - void incrementalPan ( const int incrX, const int incrY ); - void incrementalZoom( const int incrX, const int incrY ); + QwtPlotCanvas* getPlotCanvas() const; + Plot2d_Curve* getClosestCurve( QPoint, double&, int& ) const; protected: - int testOperation( const QMouseEvent& ); - void readPreferences(); - void writePreferences(); - QString getInfo( const QPoint& pnt ); - virtual void wheelEvent( QWheelEvent* ); - QwtPlotCurve* getPlotCurve( Plot2d_Curve* curve ); - bool hasPlotCurve( Plot2d_Curve* curve ); - void setCurveType( QwtPlotCurve* curve, int curveType ); + int testOperation( const QMouseEvent& ); + void readPreferences(); + void writePreferences(); + QString getInfo( const QPoint& ); + virtual void wheelEvent( QWheelEvent* ); + QwtPlotCurve* getPlotCurve( Plot2d_Curve* ) const; + bool hasPlotCurve( Plot2d_Curve* ) const; + void setCurveType( QwtPlotCurve*, int ); + QwtPlotItem* getPlotObject( Plot2d_Object* ) const; + bool hasPlotObject( Plot2d_Object* ) const; public slots: - void onViewPan(); - void onViewZoom(); - void onViewFitAll(); - void onViewFitArea(); - void onViewGlobalPan(); - void onSettings(); - void onFitData(); - void onChangeBackground(); - void onPanLeft(); - void onPanRight(); - void onPanUp(); - void onPanDown(); - void onZoomIn(); - void onZoomOut(); + void onViewPan(); + void onViewZoom(); + void onViewFitAll(); + void onViewFitArea(); + void onViewGlobalPan(); + void onSettings(); + void onFitData(); + void onChangeBackground(); + void onPanLeft(); + void onPanRight(); + void onPanUp(); + void onPanDown(); + void onZoomIn(); + void onZoomOut(); protected: - virtual void customEvent( QEvent* ); - void plotMousePressed( const QMouseEvent& ); - bool plotMouseMoved( const QMouseEvent& ); - void plotMouseReleased( const QMouseEvent& ); + virtual void customEvent( QEvent* ); + void plotMousePressed( const QMouseEvent& ); + bool plotMouseMoved( const QMouseEvent& ); + void plotMouseReleased( const QMouseEvent& ); signals: - void vpModeHorChanged(); - void vpModeVerChanged(); - void vpCurveChanged(); - void contextMenuRequested( QContextMenuEvent *e ); - void legendClicked( QwtPlotItem* ); + void vpModeHorChanged(); + void vpModeVerChanged(); + void vpCurveChanged(); + void contextMenuRequested( QContextMenuEvent* ); + void legendClicked( QwtPlotItem* ); protected: Plot2d_Plot2d* myPlot; @@ -200,54 +217,43 @@ protected: int myXMode, myYMode; double myXDistance, myYDistance, myYDistance2; bool mySecondY; + ObjectDict myObjects; + bool myIsDefTitle; }; class Plot2d_Plot2d : public QwtPlot { Q_OBJECT public: - Plot2d_Plot2d( QWidget* parent ); + Plot2d_Plot2d( QWidget* ); + virtual ~Plot2d_Plot2d(); - void setLogScale( int axisId, bool log10 ); + void setLogScale( int, bool ); - void replot(); - void getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine ); - QwtLegend* getLegend() { -#if QWT_VERSION < 0x040200 - return d_legend; -#else - return legend(); /* mpv: porting to the Qwt 4.2.0 */ -#endif - } - virtual QSize sizeHint() const; - virtual QSizePolicy sizePolicy() const; - virtual QSize minimumSizeHint() const; - void defaultPicker(); - void setPickerMousePattern( int button, int state = Qt::NoButton ); + void replot(); + QwtLegend* getLegend(); + QSize sizeHint() const; + QSize minimumSizeHint() const; + void defaultPicker(); + void setPickerMousePattern( int, int = Qt::NoButton ); - bool polished() const { return myIsPolished; } - QwtPlotGrid* grid() { return myGrid; }; - CurveDict& getCurves() { return myCurves; } - Plot2d_Curve* getClosestCurve( QPoint p, double& distance, int& index ); - QwtPlotZoomer* zoomer() const { return myPlotZoomer; } + bool polished() const; + QwtPlotGrid* grid() const; + QwtPlotZoomer* zoomer() const; - virtual void updateYAxisIdentifiers(); + virtual void updateYAxisIdentifiers(); public slots: - virtual void polish(); - -protected: - bool existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine ); + virtual void polish(); protected slots: - void onScaleDivChanged(); + void onScaleDivChanged(); protected: - CurveDict myCurves; - QwtPlotGrid* myGrid; - QList myColors; - bool myIsPolished; - QwtPlotZoomer* myPlotZoomer; + QwtPlotGrid* myGrid; + QList myColors; + bool myIsPolished; + QwtPlotZoomer* myPlotZoomer; }; class Plot2d_ScaleDraw: public QwtScaleDraw @@ -265,45 +271,4 @@ private: int myPrecision; }; -class Plot2d_QwtLegendItem : public QwtLegendItem -{ -public: - enum YAxisIdentifierMode { IM_None = 0, IM_Left, IM_Right }; - -public: - Plot2d_QwtLegendItem( QWidget* = 0 ); - virtual ~Plot2d_QwtLegendItem(); - -public: - void setYAxisIdentifierMode( const int ); - -protected: - virtual void drawIdentifier( QPainter*, const QRect& ) const; - -private: - int myYAxisIdentifierMode; - QPixmap myYAxisLeftIcon; - QPixmap myYAxisRightIcon; - int mySpacingCollapsed; - int mySpacingExpanded; -}; - -class Plot2d_QwtPlotCurve : public QwtPlotCurve -{ -public: - Plot2d_QwtPlotCurve( const QString&, QwtPlot::Axis = QwtPlot::yLeft ); - virtual ~Plot2d_QwtPlotCurve(); - -public: - virtual void setYAxisIdentifierEnabled( const bool ); - -protected: - virtual void updateLegend( QwtLegend* ) const; - virtual QWidget* legendItem() const; - -private: - QwtPlot::Axis myYAxis; - bool myYAxisIdentifierEnabled; -}; - #endif diff --git a/src/Plot2d/Plot2d_ViewManager.cxx b/src/Plot2d/Plot2d_ViewManager.cxx index db4560d5e..cca1341b6 100755 --- a/src/Plot2d/Plot2d_ViewManager.cxx +++ b/src/Plot2d/Plot2d_ViewManager.cxx @@ -25,6 +25,9 @@ #include "Plot2d_ViewWindow.h" #include "Plot2d_ViewFrame.h" +#include "SUIT_PreferenceMgr.h" +#include "SUIT_ResourceMgr.h" + /*! Constructor */ @@ -108,3 +111,78 @@ Plot2d_ViewWindow* Plot2d_ViewManager::cloneView( Plot2d_ViewWindow* srcWnd ) return newWnd; } + +/*! + Fills preference manager for viewer +*/ +int Plot2d_ViewManager::fillPreferences( SUIT_PreferenceMgr* thePrefMgr, const int theId ) +{ + int aGrpId = thePrefMgr->addItem( tr( "PREF_GROUP_PLOT2DVIEWER" ), theId, + SUIT_PreferenceMgr::GroupBox ); + + thePrefMgr->addItem( tr( "PREF_SHOW_LEGEND" ), aGrpId, + SUIT_PreferenceMgr::Bool, "Plot2d", "ShowLegend" ); + + int legendPosition = thePrefMgr->addItem( tr( "PREF_LEGEND_POSITION" ), aGrpId, + SUIT_PreferenceMgr::Selector, "Plot2d", "LegendPos" ); + QStringList aLegendPosList; + aLegendPosList.append( tr("PREF_LEFT") ); + aLegendPosList.append( tr("PREF_RIGHT") ); + aLegendPosList.append( tr("PREF_TOP") ); + aLegendPosList.append( tr("PREF_BOTTOM") ); + + QList anIndexesList; + anIndexesList.append(0); + anIndexesList.append(1); + anIndexesList.append(2); + anIndexesList.append(3); + + thePrefMgr->setItemProperty( "strings", aLegendPosList, legendPosition ); + thePrefMgr->setItemProperty( "indexes", anIndexesList, legendPosition ); + + int curveType = thePrefMgr->addItem( tr( "PREF_CURVE_TYPE" ), aGrpId, + SUIT_PreferenceMgr::Selector, "Plot2d", "CurveType" ); + QStringList aCurveTypesList; + aCurveTypesList.append( tr("PREF_POINTS") ); + aCurveTypesList.append( tr("PREF_LINES") ); + aCurveTypesList.append( tr("PREF_SPLINE") ); + + anIndexesList.clear(); + anIndexesList.append(0); + anIndexesList.append(1); + anIndexesList.append(2); + + thePrefMgr->setItemProperty( "strings", aCurveTypesList, curveType ); + thePrefMgr->setItemProperty( "indexes", anIndexesList, curveType ); + + int markerSize = thePrefMgr->addItem( tr( "PREF_MARKER_SIZE" ), aGrpId, + SUIT_PreferenceMgr::IntSpin, "Plot2d", "MarkerSize" ); + + thePrefMgr->setItemProperty( "min", 0, markerSize ); + thePrefMgr->setItemProperty( "max", 100, markerSize ); + + QStringList aScaleModesList; + aScaleModesList.append( tr("PREF_LINEAR") ); + aScaleModesList.append( tr("PREF_LOGARITHMIC") ); + + anIndexesList.clear(); + anIndexesList.append(0); + anIndexesList.append(1); + + int horScale = thePrefMgr->addItem( tr( "PREF_HOR_AXIS_SCALE" ), aGrpId, + SUIT_PreferenceMgr::Selector, "Plot2d", "HorScaleMode" ); + + thePrefMgr->setItemProperty( "strings", aScaleModesList, horScale ); + thePrefMgr->setItemProperty( "indexes", anIndexesList, horScale ); + + int verScale = thePrefMgr->addItem( tr( "PREF_VERT_AXIS_SCALE" ), aGrpId, + SUIT_PreferenceMgr::Selector, "Plot2d", "VerScaleMode" ); + + thePrefMgr->setItemProperty( "strings", aScaleModesList, verScale ); + thePrefMgr->setItemProperty( "indexes", anIndexesList, verScale ); + + thePrefMgr->addItem( tr( "PREF_VIEWER_BACKGROUND" ), aGrpId, + SUIT_PreferenceMgr::Color, "Plot2d", "Background" ); + + return aGrpId; +} diff --git a/src/Plot2d/Plot2d_ViewManager.h b/src/Plot2d/Plot2d_ViewManager.h index 6bb39b5cc..3c0b714c3 100755 --- a/src/Plot2d/Plot2d_ViewManager.h +++ b/src/Plot2d/Plot2d_ViewManager.h @@ -27,6 +27,7 @@ #include "SUIT_ViewManager.h" class SUIT_Desktop; +class SUIT_PreferenceMgr; class Plot2d_ViewWindow; class Plot2d_Viewer; class Plot2d_ViewFrame; @@ -42,6 +43,8 @@ public: Plot2d_Viewer* getPlot2dModel() const; Plot2d_ViewWindow* cloneView( Plot2d_ViewWindow* srcWnd ); + static int fillPreferences( SUIT_PreferenceMgr*, const int ); + protected: bool insertView(SUIT_ViewWindow* theView); diff --git a/src/Plot2d/Plot2d_ViewModel.cxx b/src/Plot2d/Plot2d_ViewModel.cxx index a36346e0b..66a7ad782 100755 --- a/src/Plot2d/Plot2d_ViewModel.cxx +++ b/src/Plot2d/Plot2d_ViewModel.cxx @@ -57,10 +57,11 @@ Plot2d_Viewer::~Plot2d_Viewer() */ SUIT_ViewWindow* Plot2d_Viewer::createView(SUIT_Desktop* theDesktop) { - Plot2d_ViewWindow* aPlot2dView = new Plot2d_ViewWindow(theDesktop, this); + Plot2d_ViewWindow* aView = new Plot2d_ViewWindow(theDesktop, this); + aView->initLayout(); if (myPrs) - aPlot2dView->getViewFrame()->Display(myPrs); - return aPlot2dView; + aView->getViewFrame()->Display(myPrs); + return aView; } /*! diff --git a/src/Plot2d/Plot2d_ViewModel.h b/src/Plot2d/Plot2d_ViewModel.h index 1a9fa1551..04e1308df 100755 --- a/src/Plot2d/Plot2d_ViewModel.h +++ b/src/Plot2d/Plot2d_ViewModel.h @@ -25,7 +25,7 @@ #include "Plot2d.h" #include "SUIT_ViewModel.h" -#include "qwt_plot.h" +#include class SUIT_ViewWindow; class SUIT_Desktop; diff --git a/src/Plot2d/Plot2d_ViewWindow.cxx b/src/Plot2d/Plot2d_ViewWindow.cxx index 0160b605e..6941e6f15 100755 --- a/src/Plot2d/Plot2d_ViewWindow.cxx +++ b/src/Plot2d/Plot2d_ViewWindow.cxx @@ -30,7 +30,9 @@ #include #include #include +#include +#include #include #include #include @@ -43,6 +45,11 @@ #include #include #include +#include +#include +#include + +#include /*! \class Plot2d_ViewWindow @@ -58,8 +65,21 @@ Plot2d_ViewWindow::Plot2d_ViewWindow( SUIT_Desktop* theDesktop, Plot2d_Viewer* t : SUIT_ViewWindow( theDesktop ) { myModel = theModel; - myDumpImage = QImage(); +} +/*! + \brief Destructor. +*/ +Plot2d_ViewWindow::~Plot2d_ViewWindow() +{ +} + +/*! + \brief Internal initialization. +*/ +void Plot2d_ViewWindow::initLayout() +{ + myDumpImage = QImage(); myViewFrame = new Plot2d_ViewFrame( this, "plotView" ); setCentralWidget( myViewFrame ); @@ -75,13 +95,6 @@ Plot2d_ViewWindow::Plot2d_ViewWindow( SUIT_Desktop* theDesktop, Plot2d_Viewer* t myViewFrame->installEventFilter( this ); } -/*! - \brief Destructor. -*/ -Plot2d_ViewWindow::~Plot2d_ViewWindow() -{ -} - /*! \brief Get view model. \return Plot2d view model @@ -374,6 +387,15 @@ void Plot2d_ViewWindow::createActions() connect( aAction, SIGNAL( triggered( bool ) ), this, SIGNAL( cloneView() ) ); mgr->registerAction( aAction, CloneId ); + // 10. Print + aAction = new QtxAction( tr( "MNU_PRINT_VIEW" ), + aResMgr->loadPixmap( "STD", tr( "ICON_PRINT" ) ), + tr( "MNU_PRINT_VIEW" ), + 0, this); + aAction->setStatusTip( tr( "DSC_PRINT_VIEW" ) ); + connect( aAction, SIGNAL( triggered( bool ) ), this, SLOT( onPrintView() ) ); + mgr->registerAction( aAction, PrintId ); + // Set initial values onChangeCurveMode(); onChangeHorMode(); @@ -405,6 +427,7 @@ void Plot2d_ViewWindow::createToolBar() mgr->append( LegendId, myToolBar ); mgr->append( CurvSettingsId, myToolBar ); mgr->append( CloneId, myToolBar ); + mgr->append( PrintId, myToolBar ); } /*! @@ -624,6 +647,151 @@ QString Plot2d_ViewWindow::filter() const return filters.join( ";;" ); } +/*! + \brief Called when the "Print view" action is activated. +*/ +void Plot2d_ViewWindow::onPrintView() +{ + if ( !myViewFrame ) + return; + +#if !defined(WIN32) && !defined(QT_NO_CUPS) +#if QT_VERSION < 0x040303 + if ( !Qtx::hasAnyPrinters() ) { + SUIT_MessageBox::warning( this, tr( "WRN_WARNING" ), + tr( "WRN_NO_PRINTERS" ) ); + return; + } +#endif +#endif + + // stored settings for further starts + static QString aPrinterName; + static int aColorMode = -1; + static int anOrientation = -1; + + QPrinter aPrinter; + + // restore settinds from previous launching + + // printer name + if ( !aPrinterName.isEmpty() ) + aPrinter.setPrinterName( aPrinterName ); + else + { + // Nothing to do for the first printing. aPrinter contains default printer name by default + } + + // color mode + if ( aColorMode >= 0 ) + aPrinter.setColorMode( (QPrinter::ColorMode)aColorMode ); + else + { + // Black-and-wight printers are often used + aPrinter.setColorMode( QPrinter::GrayScale ); + } + + if ( anOrientation >= 0 ) + aPrinter.setOrientation( (QPrinter::Orientation)anOrientation ); + else + aPrinter.setOrientation( QPrinter::Landscape ); + + QPrintDialog printDlg( &aPrinter, this ); + printDlg.setPrintRange( QAbstractPrintDialog::AllPages ); + if ( printDlg.exec() != QDialog::Accepted ) + return; + + // store printer settings for further starts + aPrinterName = aPrinter.printerName(); + aColorMode = aPrinter.colorMode(); + anOrientation = aPrinter.orientation(); + + int W, H; + QPainter aPainter; + + bool needColorCorrection = aPrinter.colorMode() == QPrinter::GrayScale; + + // work arround for printing on real printer + if ( aPrinter.outputFileName().isEmpty() && aPrinter.orientation() == QPrinter::Landscape ) + { + aPrinter.setFullPage( false ); + // set paper orientation and rotate painter + aPrinter.setOrientation( QPrinter::Portrait ); + + W = aPrinter.height(); + H = aPrinter.width(); + + aPainter.begin( &aPrinter ); + aPainter.translate( QPoint( H, 0 ) ); + aPainter.rotate( 90 ); + } + else + { + aPrinter.setFullPage( false ); + aPainter.begin( &aPrinter ); + W = aPrinter.width(); + H = aPrinter.height(); + } + + QMap< QwtPlotCurve*, QPen > aCurvToPen; + QMap< QwtPlotCurve*, QwtSymbol > aCurvToSymbol; + + if ( needColorCorrection ) + { + // Iterate through, store temporary their parameters and assign + // parameters proper for printing + + CurveDict aCurveDict = myViewFrame->getCurves(); + CurveDict::iterator it; + for ( it = aCurveDict.begin(); it != aCurveDict.end(); it++ ) + { + QwtPlotCurve* aCurve = it.key(); + if ( !aCurve ) + continue; + + // pen + QPen aPen = aCurve->pen(); + aCurvToPen[ aCurve ] = aPen; + + aPen.setColor( QColor( 0, 0, 0 ) ); + aPen.setWidthF( 1.5 ); + + aCurve->setPen( aPen ); + + // symbol + QwtSymbol aSymbol = aCurve->symbol(); + aCurvToSymbol[ aCurve ] = aSymbol; + aPen = aSymbol.pen(); + aPen.setColor( QColor( 0, 0, 0 ) ); + aPen.setWidthF( 1.5 ); + aSymbol.setPen( aPen ); + + aCurve->setSymbol( aSymbol ); + } + } + + myViewFrame->printPlot( &aPainter, QRect( 0, 0, W, H ) ); + aPainter.end(); + + // restore old pens and symbols + if ( needColorCorrection && !aCurvToPen.isEmpty() ) + { + CurveDict aCurveDict = myViewFrame->getCurves(); + CurveDict::iterator it; + for ( it = aCurveDict.begin(); it != aCurveDict.end(); it++ ) + { + QwtPlotCurve* aCurve = it.key(); + if ( !aCurve || + !aCurvToPen.contains( aCurve ) || + !aCurvToSymbol.contains( aCurve ) ) + continue; + + aCurve->setPen( aCurvToPen[ aCurve ] ); + aCurve->setSymbol( aCurvToSymbol[ aCurve ] ); + } + } +} + /*! \fn void Plot2d_ViewWindow::cloneView(); \brief Emitted when the "Clone View" action is activated. diff --git a/src/Plot2d/Plot2d_ViewWindow.h b/src/Plot2d/Plot2d_ViewWindow.h index 9c0813056..256d1052d 100755 --- a/src/Plot2d/Plot2d_ViewWindow.h +++ b/src/Plot2d/Plot2d_ViewWindow.h @@ -53,10 +53,10 @@ public: MoveOpId, PanId, GlobalPanId, PModeXLinearId, PModeXLogarithmicId, PModeYLinearId, PModeYLogarithmicId, - CurvPointsId, CurvLinesId, CurvSplinesId, - LegendId, - CurvSettingsId, - CloneId }; + CurvPointsId, CurvLinesId, CurvSplinesId, + LegendId, + CurvSettingsId, + CloneId, PrintId }; public: Plot2d_ViewWindow( SUIT_Desktop*, Plot2d_Viewer* ); @@ -66,6 +66,7 @@ public: void putInfo( const QString&); Plot2d_ViewFrame* getViewFrame(); QToolBar* getToolBar(); + virtual void initLayout(); void contextMenuPopup( QMenu* ); virtual bool eventFilter( QObject*, QEvent* ); @@ -95,6 +96,7 @@ public slots: void onCurves(); void onDumpView(); + void onPrintView(); protected: virtual QImage dumpView(); diff --git a/src/Plot2d/resources/Plot2d_images.ts b/src/Plot2d/resources/Plot2d_images.ts index ce8f0a3d8..0008fbe7e 100644 --- a/src/Plot2d/resources/Plot2d_images.ts +++ b/src/Plot2d/resources/Plot2d_images.ts @@ -88,5 +88,9 @@ ICON_PLOT2D_SHOW_LEGEND plot2d_legend.png + + ICON_PLOT2D_PRINT + plot2d_print.png + diff --git a/src/Plot2d/resources/Plot2d_msg_en.ts b/src/Plot2d/resources/Plot2d_msg_en.ts index 08b09ca76..20d717d6c 100644 --- a/src/Plot2d/resources/Plot2d_msg_en.ts +++ b/src/Plot2d/resources/Plot2d_msg_en.ts @@ -39,6 +39,10 @@ MNU_CLONE_VIEW Clone View + + MNU_PRINT_VIEW + Print View + POSTSCRIPT_FILES PostScript files (*.ps) @@ -143,6 +147,10 @@ DSC_CLONE_VIEW Create new OCC viewer for the active scene + + DSC_PRINT_VIEW + Print active view + DASH_LINE_LBL Dash @@ -507,5 +515,73 @@ Logarithmic scale for ordinate axis is not allowed. PLOT2D_VIEW_TITLE Plot2d scene:%M - viewer:%V + + PREF_GROUP_PLOT2DVIEWER + Plot2d Viewer + + + PREF_SHOW_LEGEND + Show legend + + + PREF_LEGEND_POSITION + Legend position: + + + PREF_LEFT + Left + + + PREF_RIGHT + Right + + + PREF_TOP + Top + + + PREF_BOTTOM + Bottom + + + PREF_CURVE_TYPE + Curve type: + + + PREF_POINTS + Points + + + PREF_LINES + Lines + + + PREF_SPLINE + Spline + + + PREF_MARKER_SIZE + Marker size: + + + PREF_LINEAR + Linear + + + PREF_LOGARITHMIC + Logarithmic + + + PREF_HOR_AXIS_SCALE + Horizontal axis scale: + + + PREF_VERT_AXIS_SCALE + Vertical axis scale: + + + PREF_VIEWER_BACKGROUND + Background color + diff --git a/src/Plot2d/resources/plot2d_print.png b/src/Plot2d/resources/plot2d_print.png new file mode 100755 index 0000000000000000000000000000000000000000..37ca7c24d941032c079bb45cfd377d1d07c85882 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!7%)r1n>(-?sKn{O^Pl)S*0|#1~TK@lM_z%Pk z3>q;Poq!Z$NswPKgTu2MX&_FLx4R2Vf5y!~AV;jkHKHUqKdq!Zu_%=xJu}UyATM3P zNY6me&^B&g22e$$r;B4q#T;9|+nfxB9H(Pt7Z~4RVU=~r_%{EgRO>H6zopr06D=?0RR91 literal 0 HcmV?d00001 -- 2.39.2