From: rnv Date: Wed, 2 Nov 2011 08:39:54 +0000 (+0000) Subject: Implementation of the "0021383: [CEA 507] Plot2d Add analytic functions on curves... X-Git-Tag: V6_4_0b1~9 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=da59e5e1265802b637eb1650b24ed92faab421e5;p=modules%2Fgui.git Implementation of the "0021383: [CEA 507] Plot2d Add analytic functions on curves" issue. --- diff --git a/src/Plot2d/Makefile.am b/src/Plot2d/Makefile.am index 7281b669d..02922e499 100755 --- a/src/Plot2d/Makefile.am +++ b/src/Plot2d/Makefile.am @@ -30,22 +30,30 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am 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 \ - Plot2d_ViewFrame.h \ - Plot2d_ViewManager.h \ - Plot2d_ViewModel.h \ - Plot2d_ViewWindow.h \ - Plot2d_SetupCurveDlg.h \ - Plot2d_SetupCurveScaleDlg.h \ - Plot2d_ToolTip.h +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 \ + Plot2d_ViewFrame.h \ + Plot2d_ViewManager.h \ + Plot2d_ViewModel.h \ + Plot2d_ViewWindow.h \ + Plot2d_SetupCurveDlg.h \ + Plot2d_ToolTip.h \ + Plot2d_SetupCurveScaleDlg.h + +if ENABLE_PYCONSOLE +salomeinclude_HEADERS += \ + Plot2d_AnaliticCurve.h \ + Plot2d_AnaliticCurveDlg.h \ + Plot2d_AnaliticParcer.h +endif + dist_libPlot2d_la_SOURCES = \ Plot2d.cxx \ @@ -62,7 +70,14 @@ dist_libPlot2d_la_SOURCES = \ Plot2d_ViewWindow.cxx \ Plot2d_SetupCurveDlg.cxx \ Plot2d_SetupCurveScaleDlg.cxx \ - Plot2d_ToolTip.cxx + Plot2d_ToolTip.cxx + +if ENABLE_PYCONSOLE +dist_libPlot2d_la_SOURCES += \ + Plot2d_AnaliticCurve.cxx \ + Plot2d_AnaliticCurveDlg.cxx \ + Plot2d_AnaliticParcer.cxx +endif MOC_FILES = \ Plot2d_FitDataDlg_moc.cxx \ @@ -74,6 +89,11 @@ MOC_FILES = \ Plot2d_SetupCurveDlg_moc.cxx \ Plot2d_SetupCurveScaleDlg_moc.cxx \ Plot2d_ToolTip_moc.cxx + +if ENABLE_PYCONSOLE +MOC_FILES += Plot2d_AnaliticCurveDlg_moc.cxx +endif + nodist_libPlot2d_la_SOURCES = $(MOC_FILES) dist_salomeres_DATA = \ @@ -93,6 +113,7 @@ dist_salomeres_DATA = \ resources/plot2d_print.png \ resources/plot2d_settings.png \ resources/plot2d_splines.png \ + resources/plot2d_analitic_curve.png \ resources/plot2d_zoom.png nodist_salomeres_DATA = \ @@ -103,6 +124,6 @@ nodist_salomeres_DATA = \ libPlot2d_la_CPPFLAGS = $(QT_INCLUDES) $(PYTHON_INCLUDES) $(QWT_INCLUDES) \ -I$(srcdir)/../Qtx -I$(srcdir)/../SUIT -libPlot2d_la_LDFLAGS = $(QWT_LIBS) $(QT_MT_LIBS) ../SUIT/libsuit.la +libPlot2d_la_LDFLAGS = $(QWT_LIBS) $(QT_MT_LIBS) $(PYTHON_LIBS) ../SUIT/libsuit.la diff --git a/src/Plot2d/Plot2d.cxx b/src/Plot2d/Plot2d.cxx index 4074f0d86..721ab545a 100755 --- a/src/Plot2d/Plot2d.cxx +++ b/src/Plot2d/Plot2d.cxx @@ -24,6 +24,34 @@ #include +#include +#include + +const int MSIZE = 9; +const int MAX_ATTEMPTS = 10; // max attempts + +// 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 ) +{ +} + + /*! \brief Convert Plot2d marker type to Qwt marker type. \param m Plot2d marker type @@ -348,3 +376,113 @@ void Plot2d::drawMarker( QPainter* painter, int x, int y, int w, int h, { drawMarker( painter, QPoint( x, y ), QRect( 0, 0, w, h ), plot2qwtMarker( type ), color ); } + + +/*! + \brief Create icon pixmap according to the marker type. + \param size icon size + \param type marker type + \param color icon color + \return icon +*/ +QPixmap Plot2d::markerIcon(const QSize &size, const QColor& color, Plot2d::MarkerType type ) +{ + + QPixmap px( size ); + px.fill( QColor( 255, 255, 255, 0 ) ); + QPainter p( &px ); + Plot2d::drawMarker( &p, size.width()/2, size.height()/2, MSIZE, MSIZE, type, color ); + return px; +} + + +/*! + \brief Create icon pixmap according to the line type. + \param size icon size + \param type line type + \param color icon color + \return icon +*/ +QPixmap Plot2d::lineIcon( const QSize& size, const QColor& color, Plot2d::LineType type ) +{ + + QPixmap px( size ); + px.fill( QColor( 255, 255, 255, 0 ) ); + QPainter p( &px ); + drawLine( &p, 5, size.height()/2, size.width()-5, size.height()/2, type, + color, 1 ); + return px; +} + +/*! + Gets new unique marker for item if possible +*/ +void Plot2d::getNextMarker( const int rtti, const QwtPlot* thePlot, QwtSymbol::Style& typeMarker, + QColor& color, Qt::PenStyle& typeLine ) +{ + 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 ) + + typeMarker = ( QwtSymbol::Style )aMarker; + color = QColor( aRed, aGreen, aBlue ); + typeLine = ( Qt::PenStyle )aLine; + + bOk = ( ++cnt == MAX_ATTEMPTS ) || !existMarker( rtti, thePlot, typeMarker, color, typeLine ); + } +} + +/*! + Checks if marker belongs to any enitity +*/ +bool Plot2d::existMarker( const int rtti, const QwtPlot* thePlot, const QwtSymbol::Style typeMarker, + const QColor& color, const Qt::PenStyle typeLine ) +{ + bool ok = false; + + 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; +} + +/*! + Checks if two colors are close to each other + uses COLOR_DISTANCE variable as max tolerance for comparing of colors +*/ + +bool Plot2d::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.h b/src/Plot2d/Plot2d.h index b6886c1cb..b0e496fb9 100755 --- a/src/Plot2d/Plot2d.h +++ b/src/Plot2d/Plot2d.h @@ -40,6 +40,19 @@ #include class QPainter; +class QwtPlot; + +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; + namespace Plot2d { @@ -95,6 +108,24 @@ namespace Plot2d void drawMarker( QPainter*, int, int, int, int, MarkerType = Circle, const QColor& = Qt::black ); + + QPixmap markerIcon( const QSize&, const QColor&, + Plot2d::MarkerType ); + + QPixmap lineIcon( const QSize&, const QColor&, + Plot2d::LineType ); + + void getNextMarker( const int rtti, const QwtPlot*, QwtSymbol::Style&, + QColor&, Qt::PenStyle& ); + + bool existMarker( const int rtti , const QwtPlot*, const QwtSymbol::Style, + const QColor&, const Qt::PenStyle ); + + + bool closeColors( const QColor&, + const QColor&, + int distance = -1 ); + } #if defined WIN32 diff --git a/src/Plot2d/Plot2d_AnaliticCurve.cxx b/src/Plot2d/Plot2d_AnaliticCurve.cxx new file mode 100644 index 000000000..b6052d51e --- /dev/null +++ b/src/Plot2d/Plot2d_AnaliticCurve.cxx @@ -0,0 +1,464 @@ +// Copyright (C) 2007-2011 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_AnaliticCurve.cxx +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com) + +#include "Plot2d_AnaliticParcer.h" +#include "Plot2d_AnaliticCurve.h" +#include "Plot2d_PlotItems.h" + + +//Init static data; + +int Plot2d_AnaliticCurve::myNbCurves = 0; + +/*! + Constructor +*/ +Plot2d_AnaliticCurve::Plot2d_AnaliticCurve() : + myAutoAssign(true), + myColor( 0, 0, 0 ), + myMarker( Plot2d::Circle ), + myMarkerSize( 0 ), + myLine( Plot2d::Solid ), + myLineWidth( 0 ), + myRangeBegin(0.0), + myRangeEnd(100.0), + myNbIntervals(100), + myExpression(""), + myAction(Plot2d_AnaliticCurve::ActAddInView), + myState(Plot2d_AnaliticCurve::StateNeedUpdate), + myCurve(0), + myActive(true) +{ + myName = QString("Analitic Curve %1").arg(++myNbCurves); +} + + +/*! + Destructor +*/ +Plot2d_AnaliticCurve::~Plot2d_AnaliticCurve() +{ +} + +/*! + Copy constructor. Makes deep copy of data +*/ +Plot2d_AnaliticCurve::Plot2d_AnaliticCurve( const Plot2d_AnaliticCurve& curve ) +{ + myAutoAssign = curve.isAutoAssign(); + myColor = curve.getColor(); + myMarker = curve.getMarker(); + myMarkerSize = curve.getMarkerSize(); + myLine = curve.getLine(); + myLineWidth = curve.getLineWidth(); + myRangeBegin = curve.getRangeBegin(); + myRangeEnd = curve.getRangeEnd(); + myNbIntervals= curve.getNbIntervals(); + myPoints = curve.myPoints; + myAction = curve.getAction(); + myName = curve.getName(); + myExpression = curve.getExpression(); + myState = curve.state(); + myCurve = curve.myCurve; + myActive = curve.isActive(); +} + +/*! + operator=. Makes deep copy of data +*/ +Plot2d_AnaliticCurve& Plot2d_AnaliticCurve::operator=( const Plot2d_AnaliticCurve& curve ) +{ + myAutoAssign = curve.isAutoAssign(); + myColor = curve.getColor(); + myMarker = curve.getMarker(); + myMarkerSize = curve.getMarkerSize(); + myLine = curve.getLine(); + myLineWidth = curve.getLineWidth(); + myRangeBegin = curve.getRangeBegin(); + myRangeEnd = curve.getRangeEnd(); + myNbIntervals= curve.getNbIntervals(); + myPoints = curve.myPoints; + myAction = curve.getAction(); + myName = curve.getName(); + myExpression = curve.getExpression(); + myState = curve.state(); + myCurve = curve.myCurve; + myActive = curve.isActive(); + return *this; +} + +/*! + Create plot object for the curve +*/ +QwtPlotItem* Plot2d_AnaliticCurve::plotItem() +{ + if(!myCurve) { + myCurve = new Plot2d_QwtPlotCurve(QString("")); + updatePlotItem(); + } + return myCurve; +} + +/*! + Auto fill parameters of object by plot view +*/ +void Plot2d_AnaliticCurve::autoFill( const QwtPlot* thePlot ) +{ + QwtSymbol::Style typeMarker; + QColor color; + Qt::PenStyle typeLine; + Plot2d::getNextMarker( QwtPlotItem::Rtti_PlotCurve, thePlot, typeMarker, color, typeLine ); + + setColor( color ); + setLine( Plot2d::qwt2plotLine( typeLine )); + setLineWidth(1); + setMarker( Plot2d::qwt2plotMarker( typeMarker ) ); +} + +/*! + Updates curve fields +*/ +void Plot2d_AnaliticCurve::updatePlotItem() +{ + if ( !myCurve ) + return; + + Plot2d_QwtPlotCurve* aCurve = dynamic_cast(myCurve); + + if(!aCurve) + return; + + QwtPlot* aPlot = aCurve->plot(); + if ( aPlot ) { + aCurve->detach(); + aCurve->attach( aPlot ); + } + + Qt::PenStyle ps = Plot2d::plot2qwtLine( getLine() ); + QwtSymbol::Style ms = Plot2d::plot2qwtMarker( getMarker() ); + + 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 ); + aCurve->setTitle(getName()); +} + + +/*! + Calculate the curve points. +*/ +void Plot2d_AnaliticCurve::calculate() { + if( state() == Plot2d_AnaliticCurve::StateOk ) + return; + + if(myRangeBegin > myRangeEnd) + return; + + Plot2d_AnaliticParcer* parcer = Plot2d_AnaliticParcer::parcer(); + double* x = 0; + double* y = 0; + int nb = parcer->calculate(getExpression(), getRangeBegin(), getRangeEnd(), + getNbIntervals(),&x,&y); + if( nb > 0 ) { + myPoints.clear(); + for( int i = 0; i < nb; i++ ) { + Plot2d_Point pnt(x[i], y[i]); + myPoints.append(pnt); + } + delete x; + delete y; + myState = Plot2d_AnaliticCurve::StateOk; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets object's data +*/ +long Plot2d_AnaliticCurve::getData( double** theX, double** theY ) const +{ + int aNPoints = getNbIntervals() + 1; + *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; +} + +/*! + Sets curves's AutoAssign flag - in this case attributes will be set automatically +*/ +void Plot2d_AnaliticCurve::setAutoAssign( bool on ) +{ + if( myAutoAssign != on ) { + myAutoAssign = on; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets curve's AutoAssign flag state +*/ +bool Plot2d_AnaliticCurve::isAutoAssign() const +{ + return myAutoAssign; +} + +/*! + Sets curve's color. +*/ +void Plot2d_AnaliticCurve::setColor( const QColor& color ) +{ + if(myColor != color) { + myColor = color; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets curve's color +*/ +QColor Plot2d_AnaliticCurve::getColor() const +{ + return myColor; +} + + +/*! + Sets marker type ( and resets AutoAssign flag ) +*/ +void Plot2d_AnaliticCurve::setMarker( Plot2d::MarkerType marker ) +{ + if(myMarker != marker) { + myMarker = marker; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets marker type +*/ +Plot2d::MarkerType Plot2d_AnaliticCurve::getMarker() const +{ + return myMarker; +} + +/*! + Sets new marker size +*/ +void Plot2d_AnaliticCurve::setMarkerSize( const int theSize ) +{ + if( myMarkerSize != theSize ) { + myMarkerSize = theSize < 0 ? 0 : theSize; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets marker size +*/ +int Plot2d_AnaliticCurve::getMarkerSize() const +{ + return myMarkerSize; +} + +/*! + Sets line type +*/ +void Plot2d_AnaliticCurve::setLine( Plot2d::LineType line ) +{ + if(myLine != line) { + myLine = line; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets line type +*/ +Plot2d::LineType Plot2d_AnaliticCurve::getLine() const +{ + return myLine; +} + + +/*! + Sets line width +*/ +void Plot2d_AnaliticCurve::setLineWidth( const int lineWidth ) +{ + if( myLineWidth != lineWidth ) { + myLineWidth = lineWidth < 0 ? 0 : lineWidth; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets line width +*/ +int Plot2d_AnaliticCurve::getLineWidth() const +{ + return myLineWidth; +} + +/*! + Sets number of points +*/ +void Plot2d_AnaliticCurve::setNbIntervals( const long nb ) +{ + if( myNbIntervals != nb ) { + myNbIntervals = nb < 1 ? 1 : nb; + myState = Plot2d_AnaliticCurve::StateNeedUpdate; + } +} + +/*! + Gets number of points +*/ +long Plot2d_AnaliticCurve::getNbIntervals() const +{ + return myNbIntervals; +} + +/*! + Sets X coordinate of the first curve points +*/ +void Plot2d_AnaliticCurve::setRangeBegin( const double coord) { + if( myRangeBegin != coord ) { + myRangeBegin = coord; + myState = Plot2d_AnaliticCurve::StateNeedUpdate; + } +} + +/*! + Gets X coordinate of the first curve points +*/ +double Plot2d_AnaliticCurve::getRangeBegin() const { + return myRangeBegin; +} + +/*! + Sets X coordinate of the last curve points +*/ +void Plot2d_AnaliticCurve::setRangeEnd( const double coord) { + if( myRangeEnd != coord ) { + myRangeEnd = coord; + myState = Plot2d_AnaliticCurve::StateNeedUpdate; + } +} + +/*! + Gets X coordinate of the last curve points +*/ +double Plot2d_AnaliticCurve::getRangeEnd() const { + return myRangeEnd; +} + +/*! + Sets the curve expression. +*/ +void Plot2d_AnaliticCurve::setExpression( const QString& expr ) { + if( myExpression != expr ) { + myExpression = expr; + myState = Plot2d_AnaliticCurve::StateNeedUpdate; + } +} + +/*! + Gets the curve expression. +*/ +QString Plot2d_AnaliticCurve::getExpression() const { + return myExpression; +} + +/*! + Sets the curve name. +*/ +void Plot2d_AnaliticCurve::setName( const QString& name ) { + if( myName != name ) { + myName = name; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets the curve name. +*/ +QString Plot2d_AnaliticCurve::getName() const { + return myName; +} + + +/*! + Sets the curve action. +*/ +void Plot2d_AnaliticCurve::setAction(const int act) { + if( act == Plot2d_AnaliticCurve::ActNothing ) { + myAction = act; + return; + } + + if(myAction != Plot2d_AnaliticCurve::ActAddInView && + myAction != Plot2d_AnaliticCurve::ActRemoveFromView) { + myAction = act; + } +} + +/*! + Gets the curve action. +*/ +int Plot2d_AnaliticCurve::getAction() const { + return myAction; +} + +/*! + Gets the curve state. +*/ +int Plot2d_AnaliticCurve::state() const { + return myState; +} + +/*! + Sets the curve active status. +*/ +void Plot2d_AnaliticCurve::setActive(const bool on) { + if( myActive != on ) { + myActive = on; + setAction(Plot2d_AnaliticCurve::ActUpdateInView); + } +} + +/*! + Gets the curve active status. +*/ +bool Plot2d_AnaliticCurve::isActive() const { + return myActive; +} diff --git a/src/Plot2d/Plot2d_AnaliticCurve.h b/src/Plot2d/Plot2d_AnaliticCurve.h new file mode 100644 index 000000000..2cf9914b8 --- /dev/null +++ b/src/Plot2d/Plot2d_AnaliticCurve.h @@ -0,0 +1,140 @@ +// Copyright (C) 2007-2011 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_AnaliticCurve.h +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com) + +#ifndef PLOT2D_ANALITIC_CURVE_H +#define PLOT2D_ANALITIC_CURVE_H + +#include "Plot2d.h" + + +class QwtPlot; +class QwtPlotItem; + + +class PLOT2D_EXPORT Plot2d_AnaliticCurve +{ +public: + + /* + Action enumeration. + */ + enum { + ActAddInView = 0, //! Add curve in view + ActRemoveFromView, //! Remove curve from view + ActUpdateInView, //! Update curve in view + ActNothing //! Do nothing + }; + + /* + State enumeration. + */ + enum { + StateOk = 0, + StateNeedUpdate + }; + + Plot2d_AnaliticCurve(); + Plot2d_AnaliticCurve( const Plot2d_AnaliticCurve& ); + Plot2d_AnaliticCurve& operator= ( const Plot2d_AnaliticCurve& ); + + virtual ~Plot2d_AnaliticCurve(); + + virtual QwtPlotItem* plotItem(); + virtual void autoFill( const QwtPlot* ); + virtual void updatePlotItem(); + + virtual void calculate(); + + long getData( double** , double** ) const; + + + void setAutoAssign( bool ); + bool isAutoAssign( ) const; + + void setColor( const QColor& ); + QColor getColor() const; + + void setMarker( Plot2d::MarkerType ); + Plot2d::MarkerType getMarker() const; + + void setMarkerSize( const int ); + int getMarkerSize() const; + + void setLine( Plot2d::LineType ); + Plot2d::LineType getLine() const; + + void setLineWidth( const int ); + int getLineWidth() const; + + void setNbIntervals( const long ); + long getNbIntervals() const; + + void setRangeBegin( const double ); + double getRangeBegin() const; + + void setRangeEnd( const double ); + double getRangeEnd() const; + + void setExpression( const QString& ); + QString getExpression() const; + + void setName( const QString& ); + QString getName() const; + + void setActive(const bool); + bool isActive() const; + + void setAction(const int); + int getAction() const; + int state() const; + + +protected: + + bool myAutoAssign; + QColor myColor; + Plot2d::MarkerType myMarker; + int myMarkerSize; + Plot2d::LineType myLine; + int myLineWidth; + long myNbIntervals; + pointList myPoints; + double myRangeBegin; + double myRangeEnd; + QString myExpression; + QString myName; + int myAction; + int myState; + QwtPlotItem* myCurve; + bool myActive; + +private: + static int myNbCurves; + +}; + +typedef QList AnaliticCurveList; + +#endif //PLOT2D_ANALITIC_CURVE_H + diff --git a/src/Plot2d/Plot2d_AnaliticCurveDlg.cxx b/src/Plot2d/Plot2d_AnaliticCurveDlg.cxx new file mode 100644 index 000000000..62db6b8fa --- /dev/null +++ b/src/Plot2d/Plot2d_AnaliticCurveDlg.cxx @@ -0,0 +1,510 @@ +// Copyright (C) 2007-2011 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_AnaliticCurveDlg.cxx +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com) + +//Local includes +#include "Plot2d_AnaliticCurveDlg.h" +#include "Plot2d_AnaliticCurve.h" +#include "Plot2d_ViewFrame.h" + +//Qtx includes +#include +#include + +//SUIT includes +#include + +//Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//qwt includes +#include +#include + + +//debug +#include + +// Controls +#define MIN 0 +#define MAX 10000 +#define STEP 1 +#define MAX_LINE_WIDTH 10 + + +/*! + Constructor +*/ +Plot2d_AnaliticCurveDlg::Plot2d_AnaliticCurveDlg( QWidget* parent, QwtPlot* plot ) + : QDialog( parent , Qt::WindowTitleHint | Qt::WindowSystemMenuHint ), + myPlot(plot) +{ + setWindowTitle( tr( "ANALITIC_CURVE_TLT" ) ); + QGridLayout* mainLayout = new QGridLayout(this); + + //Curves list widget + myCurvesList = new QListWidget( this ); + myCurvesList->setSelectionMode(QAbstractItemView::SingleSelection); + myCurvesList->setMaximumSize(QSize(150, 16777215)); + + //Curve parameters group box + myCurveParams = new QGroupBox( tr( "AC_CURVE_PARAMS" ), this ); + QGridLayout* paramsLayout = new QGridLayout( myCurveParams ); + + QLabel* formulaLabel = new QLabel( tr( "AC_FORMULA" ), myCurveParams ); + myFormula = new QLineEdit( myCurveParams ); + + QLabel* nbIntervalsLabel = new QLabel( tr( "AC_NB_INTERVALS" ), myCurveParams ); + myNbIntervals = new QtxIntSpinBox( 1, MAX, STEP, myCurveParams ); + + paramsLayout->addWidget( formulaLabel, 0, 0, 1, 1 ); + paramsLayout->addWidget( myFormula, 0, 1, 1, 1 ); + paramsLayout->addWidget( nbIntervalsLabel, 1, 0, 1, 1 ); + paramsLayout->addWidget( myNbIntervals, 1, 1, 1, 1 ); + + //Curve properties group box + myCurveProps = new QGroupBox( tr( "AC_CURVE_PROPS" ), this ); + QGridLayout* propsLayout = new QGridLayout( myCurveProps ); + + myAutoAssign = new QCheckBox( tr( "AC_AUTO_ASSIGN" ), myCurveProps ); + + QLabel* markerLabel = new QLabel( tr( "AC_MARKER_TYPE" ), myCurveProps ); + myMarkerType = new QComboBox( myCurveProps ); + + + QLabel* lineTypeLabel = new QLabel( tr( "AC_LINE_TYPE" ), myCurveProps ); + myLineType = new QComboBox( myCurveProps ); + + + QLabel* lineWidthLabel = new QLabel( tr( "AC_LINE_WIDTH" ), myCurveProps ); + myLineWidth = new QtxIntSpinBox( MIN, MAX_LINE_WIDTH, STEP, myCurveProps ); + + + + QLabel* colorLabel = new QLabel( tr("AC_CURVE_COLOR"), myCurveProps ); + myColor = new QtxColorButton(myCurveProps); + + propsLayout->addWidget( myAutoAssign, 0, 0, 1, 1 ); + propsLayout->addWidget( markerLabel, 1, 0, 1, 1 ); + propsLayout->addWidget( myMarkerType, 1, 1, 1, 1 ); + propsLayout->addWidget( lineTypeLabel, 2, 0, 1, 1 ); + propsLayout->addWidget( myLineType, 2, 1, 1, 1 ); + propsLayout->addWidget( lineWidthLabel, 3, 0, 1, 1 ); + propsLayout->addWidget( myLineWidth, 3, 1, 1, 1 ); + propsLayout->addWidget( colorLabel, 4, 0, 1, 1 ); + propsLayout->addWidget( myColor, 4, 1, 1, 1 ); + + propsLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), 3, 0, 1, 1 ); + propsLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), 3, 1, 1, 1 ); + + + //Add && Remove buttons + QPushButton* addButton = new QPushButton( tr("AC_ADD_BTN"), this ); + QPushButton* updateButton = new QPushButton( tr("AC_UPD_BTN"), this ); + QPushButton* removeButton = new QPushButton( tr("AC_REM_BTN"), this ); + + //Ok && Close buttons + QFrame* frame = new QFrame( this ); + QHBoxLayout* horizontalLayout = new QHBoxLayout(frame); + + frame->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum ) ); + frame->setFrameShape( QFrame::StyledPanel ); + frame->setFrameShadow( QFrame::Raised ); + + QPushButton* closeButton = new QPushButton( tr( "AC_CLOSE_BTN" ), frame ); + + + horizontalLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + horizontalLayout->addWidget( closeButton ); + horizontalLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + + + mainLayout->addWidget( myCurvesList, 0, 0, 3, 1 ); + mainLayout->addWidget( myCurveParams, 0, 1, 1, 5 ); + mainLayout->addWidget( myCurveProps, 1, 1, 1, 5 ); + mainLayout->addWidget( addButton, 2, 1, 1, 1 ); + mainLayout->addItem( new QSpacerItem( 13, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 2, 2, 1, 1 ); + mainLayout->addWidget( removeButton, 2, 3, 1, 1 ); + mainLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum), 2, 4, 1, 1); + mainLayout->addWidget( updateButton, 2, 5, 1, 1); + mainLayout->addWidget(frame, 3, 0, 1, 6); + + //Fill combobox + QColor cl = myMarkerType->palette().color( QPalette::Text ); + QSize sz(16, 16); + myMarkerType->setIconSize(sz); + + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::None ), tr( "NONE_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Circle ), tr( "CIRCLE_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Rectangle ), tr( "RECTANGLE_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Diamond ), tr( "DIAMOND_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::DTriangle ), tr( "DTRIANGLE_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::UTriangle ), tr( "UTRIANGLE_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::LTriangle ), tr( "LTRIANGLE_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::RTriangle ), tr( "RTRIANGLE_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Cross ), tr( "CROSS_MARKER_LBL" ) ); + myMarkerType->addItem( Plot2d::markerIcon( sz, cl, Plot2d::XCross ), tr( "XCROSS_MARKER_LBL" ) ); + + cl = myLineType->palette().color( QPalette::Text ); + QSize lsz( 40, 16 ); + myLineType->setIconSize( lsz ); + + myLineType->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::NoPen ), tr( "NONE_LINE_LBL" ) ); + myLineType->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::Solid ), tr( "SOLID_LINE_LBL" ) ); + myLineType->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::Dash ), tr( "DASH_LINE_LBL" ) ); + myLineType->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::Dot ), tr( "DOT_LINE_LBL" ) ); + myLineType->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::DashDot ), tr( "DASHDOT_LINE_LBL" ) ); + myLineType->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::DashDotDot ), tr( "DAHSDOTDOT_LINE_LBL" ) ); + + //Connections + connect( closeButton, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( addButton, SIGNAL( clicked() ), this, SLOT( onAddCurve() ) ); + connect( myAutoAssign, SIGNAL( stateChanged(int) ), this, SLOT( onAutoAssign(int) ) ); + connect( removeButton, SIGNAL( clicked()), this, SLOT(onRemoveCurve())); + connect( updateButton, SIGNAL( clicked()), this, SLOT(onUpdateCurve())); + connectSelectionChanged(); + + //Default values + myNbIntervals->setValue(100); + checkState(); +} + +/*! + Destructor +*/ +Plot2d_AnaliticCurveDlg::~Plot2d_AnaliticCurveDlg() +{ +} + +void Plot2d_AnaliticCurveDlg::setCurveList( AnaliticCurveList& theList ) { + AnaliticCurveList::iterator it = theList.begin(); + QListWidgetItem* newItem = 0; + Plot2d_AnaliticCurve* curve; + for( ;it != theList.end(); it++ ) { + curve = *it; + if(!curve) continue; + newItem = new QListWidgetItem(curve->getName()); + newItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled); + newItem->setCheckState(Qt::Checked); + myCurvesList->addItem(newItem); + newItem->setCheckState(curve->isActive() ? Qt::Checked : Qt::Unchecked ); + QVariant var; + var.setValue((void*)curve); + newItem->setData(Qt::UserRole,var); + } + setCurrentCurve(newItem); + checkState(); +} + +/*! + Return list of the curves. +*/ +/*void Plot2d_AnaliticCurveDlg::reject() { + if( myCurvesList->count() == 0 ) + QDialog::reject(); + + QList items = myCurvesList->selectedItems(); + QListWidgetItem* item = items.size() > 0 ? items[0] : 0; + if(item) { + if(!checkItem(item)) { + showErrorMsg(); + return; + } else { + updateInView(myCurrentItem); + QDialog::reject(); + } + } +} +*/ + +/*! + Update curve parameters and curve properties. +*/ +void Plot2d_AnaliticCurveDlg::setCurrentCurve(QListWidgetItem* item, bool select) { + if(item) { + QVariant var = item->data(Qt::UserRole); + Plot2d_AnaliticCurve* curve = (Plot2d_AnaliticCurve*)var.value(); + if(curve) { + myFormula->setText( curve->getExpression() ); + myNbIntervals->setValue( curve->getNbIntervals() ); + myAutoAssign->setChecked( curve->isAutoAssign() ); + if(!curve->isAutoAssign()) { + myMarkerType->setCurrentIndex( curve->getMarker() ); + myLineType->setCurrentIndex( curve->getLine() ); + myLineWidth->setValue( curve->getLineWidth() ); + myColor->setColor( curve->getColor() ); + } else { + myMarkerType->setCurrentIndex( 0 ); + myLineType->setCurrentIndex( 0 ); + myLineWidth->setValue( 1 ); + myColor->setColor( QColor() ); + } + myCurrentItem = item; + if( select ) { + disconnectSelectionChanged(); + item->setSelected(true); + connectSelectionChanged(); + } + } + } +} + +/*! + Enable/Disable "curve parameters" and "curve properties" widgets. +*/ +void Plot2d_AnaliticCurveDlg::checkState() { + bool isEnable = myCurvesList->count() > 0; + myCurveParams->setEnabled(isEnable); + myCurveProps->setEnabled(isEnable); +} +/*! + Show error message + */ +void Plot2d_AnaliticCurveDlg::showErrorMsg() { + SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "AC_CANT_CALCULATE" ) ); +} + +/*! + Check the curve attached to the item. +*/ +bool Plot2d_AnaliticCurveDlg::checkItem(const QListWidgetItem* item) { + bool res = false; + if( !myFormula->text().isEmpty() && item ) { + QVariant var = item->data(Qt::UserRole); + Plot2d_AnaliticCurve* curve = (Plot2d_AnaliticCurve*)var.value(); + + if( curve ) { + curve->setExpression(myFormula->text()); + QwtScaleDiv* div = myPlot->axisScaleDiv(QwtPlot::xBottom); + curve->setRangeBegin(div->lowerBound()); + curve->setRangeEnd(div->upperBound()); + curve->setNbIntervals(myNbIntervals->value()); + curve->calculate(); + if( curve->state() == Plot2d_AnaliticCurve::StateOk ) + res = true; + } + } + return res; +} +/*! + Store properties of the curve attached to the item from "Curve properties" widget. +*/ +void Plot2d_AnaliticCurveDlg::storeProps( const QListWidgetItem* item) { + if( item ) { + QVariant var = item->data(Qt::UserRole); + Plot2d_AnaliticCurve* curve = (Plot2d_AnaliticCurve*)var.value(); + if(curve) { + curve->setAutoAssign(myAutoAssign->isChecked()); + curve->setName(item->text()); + curve->setActive(item->checkState() == Qt::Checked); + if(!myAutoAssign->isChecked()) { + curve->setMarker((Plot2d::MarkerType)myMarkerType->currentIndex()); + curve->setLine((Plot2d::LineType)myLineType->currentIndex()); + curve->setLineWidth(myLineWidth->value()); + curve->setColor(myColor->color()); + } + } + } +} + +/*! + Connect currentItemChanged signal. +*/ +void Plot2d_AnaliticCurveDlg::connectSelectionChanged() { + connect( myCurvesList, SIGNAL( itemSelectionChanged ()), + this, SLOT( onCurveSelectionChanged() ) ); +} + +/*! + Disconnect currentItemChanged signal. +*/ +void Plot2d_AnaliticCurveDlg::disconnectSelectionChanged() { + disconnect( myCurvesList, SIGNAL( itemSelectionChanged ()), + this, SLOT( onCurveSelectionChanged() ) ); +} + +/*! + Private slot. Called then "Add curve" button is clicked +*/ +void Plot2d_AnaliticCurveDlg::onAddCurve() { + /* QList items = myCurvesList->selectedItems(); + QListWidgetItem* item = items.size() > 0 ? items[0] : 0; + if(item) { + if(!checkItem(item)) { + showErrorMsg(); + return; + } + else { + updateInView(item); + } + } + */ + + Plot2d_AnaliticCurve* curve = new Plot2d_AnaliticCurve(); + QListWidgetItem* newItem = new QListWidgetItem(curve->getName()); + newItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled); + newItem->setCheckState(Qt::Checked); + myCurvesList->addItem(newItem); + QVariant var; + var.setValue((void*)curve); + newItem->setData(Qt::UserRole,var); + + bool autoFlag = curve->isAutoAssign(); + if(autoFlag) { + curve->autoFill(myPlot); + } + + setCurrentCurve(newItem); + checkState(); +} + +/*! + Private slot. Called then "Remove curve" button is clicked +*/ +void Plot2d_AnaliticCurveDlg::onRemoveCurve() { + disconnectSelectionChanged(); + QList items = myCurvesList->selectedItems(); + QListWidgetItem* selected = items.size() > 0 ? items[0] : 0; + int row = myCurvesList->row(selected); + int prevRow = (row == 0) ? 1 : row - 1; + if( selected ) { + QVariant var = selected->data(Qt::UserRole); + Plot2d_AnaliticCurve* curve = (Plot2d_AnaliticCurve*)var.value(); + if( curve ) { + if( curve->getAction() == Plot2d_AnaliticCurve::ActAddInView ) { + delete curve; + } else { + curve->setAction(Plot2d_AnaliticCurve::ActRemoveFromView); + updateInView(selected); + } + } + } + + if( prevRow >= 0 && prevRow < myCurvesList->count() ) { + myCurvesList->item(prevRow)->setSelected(true); + setCurrentCurve(myCurvesList->item(prevRow)); + } + + selected = myCurvesList->takeItem(row); + delete selected; + connectSelectionChanged(); + checkState(); +} + +/*! + Private slot. Called then selection in the curve list is changed. +*/ +void Plot2d_AnaliticCurveDlg::onCurveSelectionChanged() { + + QList items = myCurvesList->selectedItems(); + QListWidgetItem* selected = items.size() > 0 ? items[0] : 0; + + /* bool ok = myCurrentItem ? checkItem(myCurrentItem) : true; + + if(!ok) { + showErrorMsg(); + disconnectSelectionChanged(); + + if( selected ) + selected->setSelected(false); + + if( myCurrentItem ) { + myCurrentItem->setSelected(true); + myCurvesList->setCurrentItem(myCurrentItem); + } + + connectSelectionChanged(); + + } else { + updateInView(myCurrentItem); + */ + + if(selected) { + setCurrentCurve(selected, false); + } + //} +} + +/*! + Private slot. Called then "Auto assign" checkbox is clicked +*/ +void Plot2d_AnaliticCurveDlg::onAutoAssign(int state){ + bool flag = !state; + myMarkerType->setEnabled(flag); + myLineType->setEnabled(flag); + myLineWidth->setEnabled(flag); + myColor->setEnabled(flag); + + QList items = myCurvesList->selectedItems(); + QListWidgetItem* selected = items.size() > 0 ? items[0] : 0; + if(selected) { + QVariant var = selected->data(Qt::UserRole); + Plot2d_AnaliticCurve* curve = (Plot2d_AnaliticCurve*)var.value(); + if(curve) { + curve->setAutoAssign(state); + } + setCurrentCurve(selected); + } +} + +/*! + Update curve in the view +*/ +void Plot2d_AnaliticCurveDlg::updateInView( QListWidgetItem* item ) { + storeProps(item); + Plot2d_ViewFrame* fr = qobject_cast(parent()); + QVariant var = item->data(Qt::UserRole); + + Plot2d_AnaliticCurve* curve = (Plot2d_AnaliticCurve*)var.value(); + if( fr && curve ) { + fr->updateAnaliticCurve(curve, true); + } +} + +/*! + Private slot. Called then "Update Curve" checkbox is clicked +*/ +void Plot2d_AnaliticCurveDlg::onUpdateCurve() { + QList items = myCurvesList->selectedItems(); + int sz = items.size(); + if( sz > 0 ) { + QListWidgetItem* selected = items[0]; + + bool ok = myCurrentItem ? checkItem(myCurrentItem) : false; + if(!ok) { + showErrorMsg(); + return; + } else { + updateInView(selected); + } + } +} diff --git a/src/Plot2d/Plot2d_AnaliticCurveDlg.h b/src/Plot2d/Plot2d_AnaliticCurveDlg.h new file mode 100644 index 000000000..ca26a160d --- /dev/null +++ b/src/Plot2d/Plot2d_AnaliticCurveDlg.h @@ -0,0 +1,94 @@ +// Copyright (C) 2007-2011 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_AnaliticCurveDlg.h +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com) + + +#ifndef PLOT2D_ANALITIC_CURVE_DLG_H +#define PLOT2D_ANALITIC_CURVE_DLG_H + +#include "Plot2d.h" +#include "Plot2d_AnaliticCurve.h" + +#include + + +class QListWidget; +class QListWidgetItem; +class QGroupBox; +class QLineEdit; +class QCheckBox; +class QComboBox; + +class QtxIntSpinBox; +class QtxColorButton; +class QwtPlot; + +class Plot2d_AnaliticCurve; +class Plot2d_ViewFrame; + +class PLOT2D_EXPORT Plot2d_AnaliticCurveDlg : public QDialog { + Q_OBJECT +public: + + Plot2d_AnaliticCurveDlg( QWidget* parent, QwtPlot* plot ); + ~Plot2d_AnaliticCurveDlg(); + + AnaliticCurveList getCurveList(); + void setCurveList( AnaliticCurveList& ); + +private: + void setCurrentCurve( QListWidgetItem* , bool = true); + void checkState(); + void showErrorMsg(); + bool checkItem(const QListWidgetItem* ); + void storeProps( const QListWidgetItem* ); + void connectSelectionChanged(); + void disconnectSelectionChanged(); + void updateInView(QListWidgetItem*); + +private slots: + void onAddCurve(); + void onRemoveCurve(); + void onAutoAssign(int); + void onUpdateCurve(); + void onCurveSelectionChanged( ); + +private: + QListWidget* myCurvesList; + + QGroupBox* myCurveParams; + QLineEdit* myFormula; + QtxIntSpinBox* myNbIntervals; + + QGroupBox* myCurveProps; + QCheckBox* myAutoAssign; + QComboBox* myMarkerType; + QComboBox* myLineType; + QtxIntSpinBox* myLineWidth; + QtxColorButton* myColor; + + QwtPlot* myPlot; + QListWidgetItem* myCurrentItem; +}; + +#endif //PLOT2D_ANALITIC_CURVE_DLG_H diff --git a/src/Plot2d/Plot2d_AnaliticParcer.cxx b/src/Plot2d/Plot2d_AnaliticParcer.cxx new file mode 100644 index 000000000..75ebf76f1 --- /dev/null +++ b/src/Plot2d/Plot2d_AnaliticParcer.cxx @@ -0,0 +1,272 @@ +// Copyright (C) 2007-2011 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_AnaliticParcer.cxx +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com) +#include "Plot2d_AnaliticParcer.h" +#include + + +/* ================================== + * =========== PYTHON ============== + * ==================================*/ + +typedef struct { + PyObject_HEAD + int softspace; + std::string *out; + } PyStdOut; + +static void +PyStdOut_dealloc(PyStdOut *self) +{ + PyObject_Del(self); +} + +static PyObject * +PyStdOut_write(PyStdOut *self, PyObject *args) +{ + char *c; + int l; + if (!PyArg_ParseTuple(args, "t#:write",&c, &l)) + return NULL; + + //std::cerr << c ; + *(self->out)=*(self->out)+c; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef PyStdOut_methods[] = { + {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, + PyDoc_STR("write(string) -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef PyStdOut_memberlist[] = { + {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0, + (char*)"flag indicating that a space needs to be printed; used by print"}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject PyStdOut_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "PyOut", /*tp_name*/ + sizeof(PyStdOut), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PyStdOut_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + /* softspace is writable: we must supply tp_setattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PyStdOut_methods, /*tp_methods*/ + PyStdOut_memberlist, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +PyObject * newPyStdOut( std::string& out ) +{ + PyStdOut *self; + self = PyObject_New(PyStdOut, &PyStdOut_Type); + if (self == NULL) + return NULL; + self->softspace = 0; + self->out=&out; + return (PyObject*)self; +} + + +////////////////////////END PYTHON/////////////////////////// + + +//! The only one instance of parcer +Plot2d_AnaliticParcer* Plot2d_AnaliticParcer::myParcer = 0; + +//Define the script +QString Plot2d_AnaliticParcer::myScript = QString(""); + +/*! + \brief Return the only instance of the Plot2d_AnaliticParcer + \return instance of the Plot2d_AnaliticParcer +*/ +Plot2d_AnaliticParcer* Plot2d_AnaliticParcer::parcer() +{ + if ( !myParcer ) + myParcer = new Plot2d_AnaliticParcer(); + return myParcer; +} + +/*! + \brief Constructor. + + Construct the parcer and initialize python interpritator. +*/ +Plot2d_AnaliticParcer::Plot2d_AnaliticParcer() +{ + /* Initialize the Python interpreter */ + if (Py_IsInitialized()) { + PyGILState_STATE gstate = PyGILState_Ensure(); + myMainMod = PyImport_AddModule("__main__"); + myMainDict = PyModule_GetDict(myMainMod); + PyGILState_Release(gstate); + initScript(); + } +} + +int Plot2d_AnaliticParcer::calculate( const QString& theExpr, + const double theMin, + const double theMax, + const int theNbStep, + double** theX, + double** theY) { + + QString aPyScript = myScript; + aPyScript = aPyScript.arg(theExpr); + int result = -1; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* obj = PyRun_String(qPrintable(aPyScript), Py_file_input, myMainDict, NULL); + + if(obj == NULL) { + PyErr_Print(); + PyGILState_Release(gstate); + return result; + + } else { + Py_DECREF(obj); + } + + PyObject* func = NULL; + PyObject* f_y = NULL; + + if(PyObject_HasAttrString(myMainMod, "Y")) { + f_y = PyObject_GetAttrString(myMainMod, "Y"); + } + + if(PyObject_HasAttrString(myMainMod, "coordCalculator")) { + func = PyObject_GetAttrString(myMainMod, "coordCalculator"); + } + + PyObject* new_stderr = NULL; + + if( f_y == NULL || func == NULL ) { + fflush(stderr); + std::string err_description=""; + new_stderr = newPyStdOut(err_description); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + PyGILState_Release(gstate); + return result; + } + + PyObject* coords; + coords = PyObject_CallFunction(func,(char*)"(d, d, i)", theMin, theMax, theNbStep ); + + new_stderr = NULL; + + if (coords == NULL){ + fflush(stderr); + std::string err_description=""; + new_stderr = newPyStdOut(err_description); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + PyGILState_Release(gstate); + return result; + } + + Py_ssize_t size = PyList_Size( coords ); + if( size <= 0 ) { + Py_DECREF(coords); + return result; + } + + result = size; + + *theX = new double[size]; + *theY = new double[size]; + + for ( Py_ssize_t i = 0; i< size; ++i ) { + PyObject* coord = PyList_GetItem( coords, i ); + (*theX)[i] = PyFloat_AsDouble(PyList_GetItem(coord, 0)); + (*theY)[i] = PyFloat_AsDouble(PyList_GetItem(coord, 1)); + } + + PyGILState_Release(gstate); + return result; +} + +/*! + \brief Initialize python script. +*/ +void Plot2d_AnaliticParcer::initScript() { + myScript.clear(); + myScript += "from math import * \n"; + myScript += "def Y(x): \n"; + myScript += " return "; + myScript += "%1\n"; + + myScript += "def coordCalculator(xmin, xmax, nstep): \n"; + myScript += " coords = [] \n"; + myScript +=" xstep = (xmax - xmin) / nstep \n"; + myScript +=" n = 0 \n"; + myScript +=" while n <= nstep : \n"; + myScript +=" x = xmin + n*xstep \n"; + myScript +=" coords.append([x,Y(x)]) \n"; + myScript +=" n = n+1 \n"; + myScript +=" return coords \n"; +} diff --git a/src/Plot2d/Plot2d_AnaliticParcer.h b/src/Plot2d/Plot2d_AnaliticParcer.h new file mode 100644 index 000000000..3db0cb0bf --- /dev/null +++ b/src/Plot2d/Plot2d_AnaliticParcer.h @@ -0,0 +1,52 @@ +// Copyright (C) 2007-2011 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_AnaliticParcer.h +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com) + +#ifndef PLOT2D_ANALITIC_PARCER_H +#define PLOT2D_ANALITIC_PARCER_H +#include + +#include "Plot2d.h" + +class PLOT2D_EXPORT Plot2d_AnaliticParcer { +public: + ~Plot2d_AnaliticParcer(); + + + static Plot2d_AnaliticParcer* parcer(); + int calculate( const QString&, const double, + const double, const int, + double**, double**); + +private: + Plot2d_AnaliticParcer(); + void initScript(); + +private: + static Plot2d_AnaliticParcer* myParcer; //!< instance of the parcer + PyObject* myMainMod; //!< main python module + PyObject* myMainDict; //!< main python dictionary + static QString myScript; //!< python script +}; + +#endif //PLOT2D_ANALITIC_PARCER_H diff --git a/src/Plot2d/Plot2d_Curve.cxx b/src/Plot2d/Plot2d_Curve.cxx index c225716a2..ad4b544c9 100755 --- a/src/Plot2d/Plot2d_Curve.cxx +++ b/src/Plot2d/Plot2d_Curve.cxx @@ -28,7 +28,6 @@ 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 @@ -103,7 +102,7 @@ void Plot2d_Curve::autoFill( const QwtPlot* thePlot ) QwtSymbol::Style typeMarker; QColor color; Qt::PenStyle typeLine; - getNextMarker( thePlot, typeMarker, color, typeLine ); + Plot2d::getNextMarker( rtti(), thePlot, typeMarker, color, typeLine ); setColor( color ); setLine( Plot2d::qwt2plotLine( typeLine ), DEFAULT_LINE_WIDTH ); @@ -259,57 +258,3 @@ int Plot2d_Curve::getLineWidth() const return myLineWidth; } -/*! - Gets new unique marker for item if possible -*/ -void Plot2d_Curve::getNextMarker( const QwtPlot* thePlot, QwtSymbol::Style& typeMarker, - QColor& color, Qt::PenStyle& typeLine ) -{ - 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 ) - - typeMarker = ( QwtSymbol::Style )aMarker; - color = QColor( aRed, aGreen, aBlue ); - typeLine = ( Qt::PenStyle )aLine; - - bOk = ( ++cnt == MAX_ATTEMPTS ) || !existMarker( thePlot, typeMarker, color, typeLine ); - } -} - -/*! - Checks if marker belongs to any enitity -*/ -bool Plot2d_Curve::existMarker( const QwtPlot* thePlot, const QwtSymbol::Style typeMarker, - const QColor& color, const Qt::PenStyle typeLine ) -{ - bool ok = false; - - 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 cbb95289a..9517dddc7 100755 --- a/src/Plot2d/Plot2d_Curve.h +++ b/src/Plot2d/Plot2d_Curve.h @@ -59,12 +59,6 @@ public: void setLineWidth( const int ); int getLineWidth() const; -protected: - void getNextMarker( const QwtPlot*, QwtSymbol::Style&, - QColor&, Qt::PenStyle& ); - bool existMarker( const QwtPlot*, const QwtSymbol::Style, - const QColor&, const Qt::PenStyle ); - protected: QColor myColor; Plot2d::MarkerType myMarker; diff --git a/src/Plot2d/Plot2d_Histogram.cxx b/src/Plot2d/Plot2d_Histogram.cxx index f2832fdf1..7bcf09b76 100644 --- a/src/Plot2d/Plot2d_Histogram.cxx +++ b/src/Plot2d/Plot2d_Histogram.cxx @@ -213,7 +213,7 @@ bool Plot2d_Histogram::existColor( const QwtPlot* thePlot, const QColor& theColo bool ok = false; QColor bgColor = thePlot->palette().color( QPalette::Background ); - if ( closeColors( theColor, bgColor ) ) { + if ( Plot2d::closeColors( theColor, bgColor ) ) { ok = true; } else { @@ -226,11 +226,11 @@ bool Plot2d_Histogram::existColor( const QwtPlot* thePlot, const QColor& theColo continue; if ( anItem->rtti() == rtti() ) { Plot2d_HistogramItem* aHItem = dynamic_cast( anItem ); - ok = aHItem && closeColors( theColor, aHItem->color() ); + ok = aHItem && Plot2d::closeColors( theColor, aHItem->color() ); } else if ( anItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) { QwtPlotCurve* aCurve = dynamic_cast( anItem ); - ok = aCurve && closeColors( theColor, aCurve->pen().color() ); + ok = aCurve && Plot2d::closeColors( theColor, aCurve->pen().color() ); } } } diff --git a/src/Plot2d/Plot2d_Object.cxx b/src/Plot2d/Plot2d_Object.cxx index 6f07e7042..3498791bd 100755 --- a/src/Plot2d/Plot2d_Object.cxx +++ b/src/Plot2d/Plot2d_Object.cxx @@ -29,10 +29,6 @@ #include #include -// color tolerance (used to compare color values) -const long COLOR_DISTANCE = 100; - - // Static members QColor Plot2d_Object::mySelectionColor; QColor Plot2d_Object::myHighlightedLegendTextColor; @@ -52,22 +48,6 @@ void Plot2d_Object::initColors() { } } -/*! - 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 */ @@ -512,24 +492,6 @@ double Plot2d_Object::getMaxY() const 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; -} - /*! Sets object's selected property */ diff --git a/src/Plot2d/Plot2d_Object.h b/src/Plot2d/Plot2d_Object.h index bc7a5babc..3b7c048f8 100755 --- a/src/Plot2d/Plot2d_Object.h +++ b/src/Plot2d/Plot2d_Object.h @@ -31,16 +31,6 @@ #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 { @@ -113,8 +103,6 @@ public: void setSelected(const bool); bool isSelected() const; - - static bool closeColors( const QColor&, const QColor&, int distance = -1 ); static void initColors(); diff --git a/src/Plot2d/Plot2d_SetupCurveDlg.cxx b/src/Plot2d/Plot2d_SetupCurveDlg.cxx index f4b52f65c..d03b57430 100644 --- a/src/Plot2d/Plot2d_SetupCurveDlg.cxx +++ b/src/Plot2d/Plot2d_SetupCurveDlg.cxx @@ -64,7 +64,8 @@ Plot2d_SetupCurveDlg::Plot2d_SetupCurveDlg( QWidget* parent ) myLineCombo = new QComboBox( this ); myLineCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); myLineCombo->setMinimumWidth( MIN_COMBO_WIDTH ); - myLineCombo->setIconSize( QSize( 40, 16 ) ); + QSize lsz( 40, 16 ); + myLineCombo->setIconSize( lsz ); // curve width QLabel* aLineWidthLab = new QLabel( tr( "CURVE_LINE_WIDTH_LAB" ), this ); @@ -80,7 +81,8 @@ Plot2d_SetupCurveDlg::Plot2d_SetupCurveDlg( QWidget* parent ) myMarkerCombo = new QComboBox( this ); myMarkerCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); myMarkerCombo->setMinimumWidth( MIN_COMBO_WIDTH ); - myMarkerCombo->setIconSize( QSize( 16, 16 ) ); + QSize sz(16, 16); + myMarkerCombo->setIconSize(sz); // curve color QLabel* aColorLab = new QLabel( tr( "CURVE_COLOR_LAB" ), this ); @@ -125,23 +127,27 @@ Plot2d_SetupCurveDlg::Plot2d_SetupCurveDlg( QWidget* parent ) topLayout->addLayout( btnLayout, 5, 0, 1, 3 ); // fill then combo boxes - myLineCombo->addItem( lineIcon( Plot2d::NoPen ), tr( "NONE_LINE_LBL" ) ); - myLineCombo->addItem( lineIcon( Plot2d::Solid ), tr( "SOLID_LINE_LBL" ) ); - myLineCombo->addItem( lineIcon( Plot2d::Dash ), tr( "DASH_LINE_LBL" ) ); - myLineCombo->addItem( lineIcon( Plot2d::Dot ), tr( "DOT_LINE_LBL" ) ); - myLineCombo->addItem( lineIcon( Plot2d::DashDot ), tr( "DASHDOT_LINE_LBL" ) ); - myLineCombo->addItem( lineIcon( Plot2d::DashDotDot ), tr( "DAHSDOTDOT_LINE_LBL" ) ); - - myMarkerCombo->addItem( markerIcon( Plot2d::None ), tr( "NONE_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::Circle ), tr( "CIRCLE_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::Rectangle ), tr( "RECTANGLE_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::Diamond ), tr( "DIAMOND_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::DTriangle ), tr( "DTRIANGLE_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::UTriangle ), tr( "UTRIANGLE_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::LTriangle ), tr( "LTRIANGLE_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::RTriangle ), tr( "RTRIANGLE_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::Cross ), tr( "CROSS_MARKER_LBL" ) ); - myMarkerCombo->addItem( markerIcon( Plot2d::XCross ), tr( "XCROSS_MARKER_LBL" ) ); + QColor cl = myLineCombo->palette().color( QPalette::Text ); + + myLineCombo->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::NoPen ), tr( "NONE_LINE_LBL" ) ); + myLineCombo->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::Solid ), tr( "SOLID_LINE_LBL" ) ); + myLineCombo->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::Dash ), tr( "DASH_LINE_LBL" ) ); + myLineCombo->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::Dot ), tr( "DOT_LINE_LBL" ) ); + myLineCombo->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::DashDot ), tr( "DASHDOT_LINE_LBL" ) ); + myLineCombo->addItem( Plot2d::lineIcon( lsz, cl, Plot2d::DashDotDot ), tr( "DAHSDOTDOT_LINE_LBL" ) ); + + cl = myMarkerCombo->palette().color( QPalette::Text ); + + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::None ), tr( "NONE_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Circle ), tr( "CIRCLE_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Rectangle ), tr( "RECTANGLE_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Diamond ), tr( "DIAMOND_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::DTriangle ), tr( "DTRIANGLE_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::UTriangle ), tr( "UTRIANGLE_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::LTriangle ), tr( "LTRIANGLE_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::RTriangle ), tr( "RTRIANGLE_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::Cross ), tr( "CROSS_MARKER_LBL" ) ); + myMarkerCombo->addItem( Plot2d::markerIcon( sz, cl, Plot2d::XCross ), tr( "XCROSS_MARKER_LBL" ) ); // default settings setLine( Plot2d::Solid, 0 ); // solid line, width = 0 @@ -244,38 +250,6 @@ QColor Plot2d_SetupCurveDlg::getColor() const return myColorBtn->color(); } -/*! - \brief Create icon pixmap according to the line type. - \param type line type - \return icon -*/ -QPixmap Plot2d_SetupCurveDlg::lineIcon( Plot2d::LineType type ) const -{ - QSize sz = myLineCombo->iconSize(); - QPixmap px( sz ); - px.fill( QColor( 255, 255, 255, 0 ) ); - QPainter p( &px ); - Plot2d::drawLine( &p, 5, sz.height()/2, sz.width()-5, sz.height()/2, type, - myLineCombo->palette().color( QPalette::Text ), 1 ); - return px; -} - -/*! - \brief Create icon pixmap according to the marker type. - \param type marker type - \return icon -*/ -QPixmap Plot2d_SetupCurveDlg::markerIcon( Plot2d::MarkerType type ) const -{ - QSize sz = myMarkerCombo->iconSize(); - QPixmap px( sz ); - px.fill( QColor( 255, 255, 255, 0 ) ); - QPainter p( &px ); - Plot2d::drawMarker( &p, sz.width()/2, sz.height()/2, MSIZE, MSIZE, type, - myMarkerCombo->palette().color( QPalette::Text ) ); - return px; -} - /* \brief Update preview widget. */ diff --git a/src/Plot2d/Plot2d_SetupCurveDlg.h b/src/Plot2d/Plot2d_SetupCurveDlg.h index 51b7e8ca1..a944da4db 100644 --- a/src/Plot2d/Plot2d_SetupCurveDlg.h +++ b/src/Plot2d/Plot2d_SetupCurveDlg.h @@ -55,9 +55,6 @@ public: void setColor( const QColor& ); QColor getColor() const; -private: - QPixmap lineIcon( Plot2d::LineType ) const; - QPixmap markerIcon( Plot2d::MarkerType ) const; private slots: void updatePreview(); diff --git a/src/Plot2d/Plot2d_ViewFrame.cxx b/src/Plot2d/Plot2d_ViewFrame.cxx index 1a231a758..ea4972f95 100755 --- a/src/Plot2d/Plot2d_ViewFrame.cxx +++ b/src/Plot2d/Plot2d_ViewFrame.cxx @@ -28,6 +28,10 @@ #include "Plot2d_FitDataDlg.h" #include "Plot2d_ViewWindow.h" #include "Plot2d_SetupViewDlg.h" +#ifndef DISABLE_PYCONSOLE +#include "Plot2d_AnaliticCurveDlg.h" +#include "Plot2d_AnaliticCurve.h" +#endif #include "Plot2d_ToolTip.h" #include "SUIT_Tools.h" @@ -1123,6 +1127,79 @@ void Plot2d_ViewFrame::onSettings() delete dlg; } +#ifndef DISABLE_PYCONSOLE +/*! + "Analitic Curves" toolbar action slot +*/ +void Plot2d_ViewFrame::onAnaliticCurve() { + Plot2d_AnaliticCurveDlg* dlg = new Plot2d_AnaliticCurveDlg(this, myPlot); + dlg->setCurveList(myAnaliticCurves); + dlg->exec(); + delete dlg; +} +#endif + + +#ifndef DISABLE_PYCONSOLE +/* + Update analitic curve +*/ +void Plot2d_ViewFrame::updateAnaliticCurve(Plot2d_AnaliticCurve* c, bool updateView){ + if(!c) return; + QwtScaleDiv* div = myPlot->axisScaleDiv(QwtPlot::xBottom); + c->setRangeBegin(div->lowerBound()); + c->setRangeEnd(div->upperBound()); + c->calculate(); + c->setMarkerSize(myMarkerSize); + QwtPlotItem* item = c->plotItem(); + + switch( c->getAction() ) { + case Plot2d_AnaliticCurve::ActAddInView: + if( c->isActive() ) { + item->attach( myPlot ); + } + myAnaliticCurves.append(c); + c->setAction(Plot2d_AnaliticCurve::ActNothing); + break; + + case Plot2d_AnaliticCurve::ActUpdateInView: + if(c->isActive()) { + item->attach( myPlot ); + c->updatePlotItem(); + item->show(); + } else { + item->hide(); + item->detach(); + } + + c->setAction(Plot2d_AnaliticCurve::ActNothing); + break; + case Plot2d_AnaliticCurve::ActRemoveFromView: + item->hide(); + item->detach(); + myAnaliticCurves.removeAll(c); + delete c; + break; + } + + if(updateView) + myPlot->replot(); +} +#endif + +#ifndef DISABLE_PYCONSOLE +/* + Update analitic curves +*/ +void Plot2d_ViewFrame::updateAnaliticCurves() { + AnaliticCurveList::iterator it = myAnaliticCurves.begin(); + for( ; it != myAnaliticCurves.end(); it++) { + updateAnaliticCurve(*it); + } + myPlot->replot(); +} +#endif + /*! "Fit Data" command slot */ @@ -1138,6 +1215,9 @@ void Plot2d_ViewFrame::onFitData() fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max); } delete dlg; +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -1682,7 +1762,12 @@ void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me ) QContextMenuEvent aEvent( QContextMenuEvent::Mouse, me.pos(), me.globalPos() ); emit contextMenuRequested( &aEvent ); + } +#ifndef DISABLE_PYCONSOLE + else { + updateAnaliticCurves(); } +#endif myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) ); myPlot->defaultPicker(); @@ -1715,6 +1800,9 @@ void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event) myPlot->replot(); if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase(); myPnt = event->pos(); +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -2293,8 +2381,50 @@ QString Plot2d_ViewFrame::getVisualParameters() double xmin, xmax, ymin, ymax, y2min, y2max; getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max ); QString retStr; - retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e", myXMode, - myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max ); + //Store font in the visual parameters string as: + // + // ...*FontFamily|FontSize|B|I|U|r:g:b*... + + retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%s|%i|%i|%i|%i|%i:%i:%i", + myXMode, myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max, + qPrintable(myLegendFont.family()), myLegendFont.pointSize(),myLegendFont.bold(), + myLegendFont.italic(), myLegendFont.underline(),myLegendColor.red(), + myLegendColor.green(), myLegendColor.blue()); + +#ifndef DISABLE_PYCONSOLE + //store all analitic curves + //store each curve in the following format + // ...*Name|isActive|Expresion|NbInervals|isAutoAssign[|MarkerType|LineType|LineWidth|r:g:b] + // parameters in the [ ] is optional in case if isAutoAssign == true + AnaliticCurveList::iterator it = myAnaliticCurves.begin(); + Plot2d_AnaliticCurve* c = 0; + bool isAuto; + for( ; it != myAnaliticCurves.end(); it++) { + c = (*it); + if(!c) continue; + QString curveString(""); + isAuto = c->isAutoAssign(); + curveString.sprintf("*%s|%i|%s|%i|%i", + qPrintable(c->getName()), + c->isActive(), + qPrintable(c->getExpression()), + c->getNbIntervals(), + isAuto); + + retStr+=curveString; + if(!isAuto) { + QString optCurveString(""); + optCurveString.sprintf("|%i|%i|%i|%i:%i:%i", + (int)c->getMarker(), + (int)c->getLine(), + c->getLineWidth(), + c->getColor().red(), + c->getColor().green(), + c->getColor().blue()); + retStr+=optCurveString; + } + } +#endif return retStr; } @@ -2303,9 +2433,10 @@ QString Plot2d_ViewFrame::getVisualParameters() */ void Plot2d_ViewFrame::setVisualParameters( const QString& parameters ) { + double xmin, xmax; QStringList paramsLst = parameters.split( '*' ); - if ( paramsLst.size() == 9 ) { - double xmin, xmax, ymin, ymax, y2min, y2max; + if ( paramsLst.size() >= 9 ) { + double ymin, ymax, y2min, y2max; myXMode = paramsLst[0].toInt(); myYMode = paramsLst[1].toInt(); mySecondY = (bool)paramsLst[2].toInt(); @@ -2328,7 +2459,62 @@ void Plot2d_ViewFrame::setVisualParameters( const QString& parameters ) fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max ); fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max ); - } + } + + //Restore legend font + if(paramsLst.size() >= 10) { + QStringList fontList = paramsLst[9].split( '|' ); + if(fontList.size() == 6) { + myLegendFont = QFont(fontList[0]); + myLegendFont.setPointSize(fontList[1].toInt()); + myLegendFont.setBold(fontList[2].toInt()); + myLegendFont.setItalic(fontList[3].toInt()); + myLegendFont.setUnderline(fontList[4].toInt()); + QStringList colorList = fontList[5].split(":"); + setLegendFont( myLegendFont ); + + if(colorList.size() == 3) { + myLegendColor = QColor(colorList[0].toInt(), + colorList[1].toInt(), + colorList[2].toInt()); + setLegendFontColor( myLegendColor ); + } + } + } + +#ifndef DISABLE_PYCONSOLE + //Restore all analitical curves + int startCurveIndex = 10; + if( paramsLst.size() >= startCurveIndex+1 ) { + for( int i=startCurveIndex; isetName(curveLst[0]); + c->setActive(curveLst[1].toInt()); + c->setExpression(curveLst[2]); + c->setNbIntervals(curveLst[3].toLong()); + c->setAutoAssign(curveLst[4].toInt()); + if( !c->isAutoAssign() ) { + c->setMarker((Plot2d::MarkerType)curveLst[5].toInt()); + c->setLine((Plot2d::LineType)curveLst[6].toInt()); + c->setLineWidth(curveLst[7].toInt()); + QStringList colorList = curveLst[8].split(":"); + if( colorList.size() == 3 ) { + c->setColor(QColor(colorList[0].toInt(), + colorList[1].toInt(), + colorList[2].toInt())); + } + } else { + c->autoFill( myPlot ); + } + c->setAction(Plot2d_AnaliticCurve::ActAddInView); + updateAnaliticCurve(c); + } + } + myPlot->replot(); + } +#endif } /*! @@ -2407,6 +2593,9 @@ Plot2d_Curve* Plot2d_ViewFrame::getClosestCurve( QPoint p, double& distance, int void Plot2d_ViewFrame::onPanLeft() { this->incrementalPan( -INCREMENT_FOR_OP, 0 ); +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -2415,6 +2604,9 @@ void Plot2d_ViewFrame::onPanLeft() void Plot2d_ViewFrame::onPanRight() { this->incrementalPan( INCREMENT_FOR_OP, 0 ); +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -2423,6 +2615,9 @@ void Plot2d_ViewFrame::onPanRight() void Plot2d_ViewFrame::onPanUp() { this->incrementalPan( 0, -INCREMENT_FOR_OP ); +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -2431,6 +2626,9 @@ void Plot2d_ViewFrame::onPanUp() void Plot2d_ViewFrame::onPanDown() { this->incrementalPan( 0, INCREMENT_FOR_OP ); +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -2439,6 +2637,9 @@ void Plot2d_ViewFrame::onPanDown() void Plot2d_ViewFrame::onZoomIn() { this->incrementalZoom( INCREMENT_FOR_OP, INCREMENT_FOR_OP ); +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -2447,6 +2648,9 @@ void Plot2d_ViewFrame::onZoomIn() void Plot2d_ViewFrame::onZoomOut() { this->incrementalZoom( -INCREMENT_FOR_OP, -INCREMENT_FOR_OP ); +#ifndef DISABLE_PYCONSOLE + updateAnaliticCurves(); +#endif } /*! @@ -2510,5 +2714,3 @@ QwtText Plot2d_ScaleDraw::label( double value ) const return QwtScaleDraw::label( value ); } - - diff --git a/src/Plot2d/Plot2d_ViewFrame.h b/src/Plot2d/Plot2d_ViewFrame.h index 874188919..5c49e9f10 100755 --- a/src/Plot2d/Plot2d_ViewFrame.h +++ b/src/Plot2d/Plot2d_ViewFrame.h @@ -25,6 +25,9 @@ #include "Plot2d.h" #include "Plot2d_Curve.h" +#ifndef DISABLE_PYCONSOLE +#include "Plot2d_AnaliticCurve.h" +#endif #include #include @@ -108,6 +111,10 @@ public: void getFitRangeByCurves( double&, double&, double&, double&, double&, double& ); +#ifndef DISABLE_PYCONSOLE + void updateAnaliticCurves(); + void updateAnaliticCurve( Plot2d_AnaliticCurve*, bool = false ); +#endif /* view parameters */ void copyPreferences( Plot2d_ViewFrame* ); @@ -187,6 +194,9 @@ public slots: void onViewFitArea(); void onViewGlobalPan(); void onSettings(); +#ifndef DISABLE_PYCONSOLE + void onAnaliticCurve(); +#endif void onFitData(); void onChangeBackground(); void onPanLeft(); @@ -210,28 +220,31 @@ signals: void legendClicked( QwtPlotItem* ); protected: - Plot2d_Plot2d* myPlot; - int myOperation; - QPoint myPnt; - - int myCurveType; - bool myShowLegend; - int myLegendPos; - QFont myLegendFont; - QColor myLegendColor; - int myMarkerSize; - QColor myBackground; - QString myTitle, myXTitle, myYTitle, myY2Title; - bool myTitleEnabled, myXTitleEnabled, myYTitleEnabled, myY2TitleEnabled; - bool myXGridMajorEnabled, myYGridMajorEnabled, myY2GridMajorEnabled; - bool myXGridMinorEnabled, myYGridMinorEnabled, myY2GridMinorEnabled; - int myXGridMaxMajor, myYGridMaxMajor, myY2GridMaxMajor; - int myXGridMaxMinor, myYGridMaxMinor, myY2GridMaxMinor; - int myXMode, myYMode; - double myXDistance, myYDistance, myYDistance2; - bool mySecondY; - ObjectDict myObjects; - bool myIsDefTitle; + Plot2d_Plot2d* myPlot; + int myOperation; + QPoint myPnt; + + int myCurveType; + bool myShowLegend; + int myLegendPos; + QFont myLegendFont; + QColor myLegendColor; + int myMarkerSize; + QColor myBackground; + QString myTitle, myXTitle, myYTitle, myY2Title; + bool myTitleEnabled, myXTitleEnabled, myYTitleEnabled, myY2TitleEnabled; + bool myXGridMajorEnabled, myYGridMajorEnabled, myY2GridMajorEnabled; + bool myXGridMinorEnabled, myYGridMinorEnabled, myY2GridMinorEnabled; + int myXGridMaxMajor, myYGridMaxMajor, myY2GridMaxMajor; + int myXGridMaxMinor, myYGridMaxMinor, myY2GridMaxMinor; + int myXMode, myYMode; + double myXDistance, myYDistance, myYDistance2; + bool mySecondY; + ObjectDict myObjects; +#ifndef DISABLE_PYCONSOLE + AnaliticCurveList myAnaliticCurves; +#endif + bool myIsDefTitle; }; class Plot2d_Plot2d : public QwtPlot diff --git a/src/Plot2d/Plot2d_ViewWindow.cxx b/src/Plot2d/Plot2d_ViewWindow.cxx index eb9fdb2cc..d4bcf6c94 100755 --- a/src/Plot2d/Plot2d_ViewWindow.cxx +++ b/src/Plot2d/Plot2d_ViewWindow.cxx @@ -374,11 +374,23 @@ void Plot2d_ViewWindow::createActions() aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_SETTINGS" ) ), tr( "MEN_PLOT2D_SETTINGS" ), 0, this ); + aAction->setStatusTip( tr( "PRP_PLOT2D_SETTINGS" ) ); connect( aAction, SIGNAL( triggered( bool ) ), myViewFrame, SLOT( onSettings() ) ); mgr->registerAction( aAction, CurvSettingsId ); - // 9. Clone + // 9. Analitic curves + aAction = new QtxAction( tr( "TOT_PLOT2D_ANALITIC_CURVES" ), + aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_ANALITIC_CURVES" ) ), + tr( "MEN_PLOT2D_ANALITIC_CURVES" ), + 0, this ); + + aAction->setStatusTip( tr( "PRP_PLOT2D_ANALITIC_CURVES" ) ); + connect( aAction, SIGNAL( triggered( bool ) ), myViewFrame, SLOT( onAnaliticCurve() ) ); + mgr->registerAction( aAction, AnaliticCurveId ); + + + // 10. Clone aAction = new QtxAction( tr( "MNU_CLONE_VIEW" ), aResMgr->loadPixmap( "Plot2d", tr( "ICON_PLOT2D_CLONE_VIEW" ) ), tr( "MNU_CLONE_VIEW" ), @@ -387,7 +399,7 @@ void Plot2d_ViewWindow::createActions() connect( aAction, SIGNAL( triggered( bool ) ), this, SIGNAL( cloneView() ) ); mgr->registerAction( aAction, CloneId ); - // 10. Print + // 11. Print aAction = new QtxAction( tr( "MNU_PRINT_VIEW" ), aResMgr->loadPixmap( "STD", tr( "ICON_PLOT2D_PRINT" ) ), tr( "MNU_PRINT_VIEW" ), @@ -426,6 +438,7 @@ void Plot2d_ViewWindow::createToolBar() mgr->append( toolMgr()->separator(), myToolBar ); mgr->append( LegendId, myToolBar ); mgr->append( CurvSettingsId, myToolBar ); + mgr->append( AnaliticCurveId, myToolBar ); mgr->append( CloneId, myToolBar ); mgr->append( PrintId, myToolBar ); } diff --git a/src/Plot2d/Plot2d_ViewWindow.h b/src/Plot2d/Plot2d_ViewWindow.h index fc3bed5b2..86e52053c 100755 --- a/src/Plot2d/Plot2d_ViewWindow.h +++ b/src/Plot2d/Plot2d_ViewWindow.h @@ -56,7 +56,8 @@ public: CurvPointsId, CurvLinesId, CurvSplinesId, LegendId, CurvSettingsId, - CloneId, PrintId }; + CloneId, PrintId, + AnaliticCurveId }; public: Plot2d_ViewWindow( SUIT_Desktop*, Plot2d_Viewer* ); diff --git a/src/Plot2d/resources/Plot2d_images.ts b/src/Plot2d/resources/Plot2d_images.ts index ca85468c5..3c39ca19d 100644 --- a/src/Plot2d/resources/Plot2d_images.ts +++ b/src/Plot2d/resources/Plot2d_images.ts @@ -55,6 +55,10 @@ ICON_PLOT2D_SETTINGS plot2d_settings.png + + ICON_PLOT2D_ANALITIC_CURVES + plot2d_analitic_curve.png + ICON_PLOT2D_CURVES_LINES plot2d_lines.png diff --git a/src/Plot2d/resources/Plot2d_msg_en.ts b/src/Plot2d/resources/Plot2d_msg_en.ts index 81a5ede48..41f368acb 100644 --- a/src/Plot2d/resources/Plot2d_msg_en.ts +++ b/src/Plot2d/resources/Plot2d_msg_en.ts @@ -203,6 +203,10 @@ TOT_PLOT2D_SETTINGS Settings + + TOT_PLOT2D_ANALITIC_CURVES + Analitic curves + PLOT2D_CURVE_TYPE_LINES Lines @@ -349,10 +353,14 @@ Logarithmic scale for ordinate axis is not allowed. DSC_ZOOM_VIEW Zoom the view + + PRP_PLOT2D_ANALITIC_CURVES + Setups analitic curves properties + PRP_PLOT2D_SETTINGS Setups view properties - + INF_COORDINATES_SOME_Y Coordinates: X : %1, Y : %2 ( %3 ) @@ -441,6 +449,10 @@ Logarithmic scale for ordinate axis is not allowed. MEN_PLOT2D_SETTINGS &Settings + + MEN_PLOT2D_ANALITIC_CURVES + Analitic curvse + CIRCLE_MARKER_LBL Circle @@ -588,6 +600,70 @@ Logarithmic scale for ordinate axis is not allowed. Background color + + Plot2d_AnaliticCurveDlg + + ANALITIC_CURVE_TLT + Analitic curves properties + + + AC_CURVE_PARAMS + Curve parameters + + + AC_CURVE_PROPS + Curve properties + + + AC_FORMULA + y(x) = + + + AC_NB_INTERVALS + Nb. intervals + + + AC_AUTO_ASSIGN + Auto assign + + + AC_MARKER_TYPE + Marker type + + + AC_LINE_TYPE + Line type + + + AC_LINE_WIDTH + Line Width + + + AC_CURVE_COLOR + Curve color + + + AC_ADD_BTN + Add curve + + + AC_REM_BTN + Remove curve + + + AC_UPD_BTN + Update Curve + + + AC_CANT_CALCULATE + Can't calculate curve. +Please, check input parameters!!! + + + AC_CLOSE_BTN + &Close + + Plot2d_SetupCurveScaleDlg @@ -600,3 +676,4 @@ Logarithmic scale for ordinate axis is not allowed. + diff --git a/src/Plot2d/resources/plot2d_analitic_curve.png b/src/Plot2d/resources/plot2d_analitic_curve.png new file mode 100755 index 000000000..7ceb5f220 Binary files /dev/null and b/src/Plot2d/resources/plot2d_analitic_curve.png differ