diff --git a/kmplot/function.cpp b/kmplot/function.cpp index f893207..89abc03 100644 --- a/kmplot/function.cpp +++ b/kmplot/function.cpp @@ -1,1196 +1,1196 @@ /* * KmPlot - a math. function plotter for the KDE-Desktop * * Copyright (C) 1998, 1999, 2000, 2002 Klaus-Dieter Möller * 2006 David Saxton * * This file is part of the KDE Project. * KmPlot is part of the KDE-EDU Project. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "function.h" #include "ksliderwindow.h" #include "settings.h" #include "view.h" #include "xparser.h" #include #include #include #include #include int MAX_PM = 4; //BEGIN class Value Value::Value( const QString & expression ) { m_value = 0.0; if ( expression.isEmpty() ) m_expression = '0'; else updateExpression( expression ); } Value::Value( double value ) { updateExpression( value ); } bool Value::updateExpression( const QString & expression ) { Parser::Error error; double newValue = XParser::self()->eval( expression, & error ); if ( error != Parser::ParseSuccess ) return false; m_value = newValue; m_expression = expression; return true; } void Value::updateExpression( double value ) { m_value = value; m_expression = Parser::number( value ); } bool Value::operator == ( const Value & other ) const { return m_expression == other.expression(); } //END class Value //BEGIN class PlotAppearance PlotAppearance::PlotAppearance( ) { lineWidth = 0.3; color = Qt::black; useGradient = false; visible = false; style = Qt::SolidLine; showExtrema = false; showTangentField = false; showPlotName = false; } bool PlotAppearance::operator !=( const PlotAppearance & other ) const { return (lineWidth != other.lineWidth) || (color != other.color) || (useGradient != other.useGradient) || (gradient.stops() != other.gradient.stops()) || (visible != other.visible) || (style != other.style) || (showExtrema != other.showExtrema) || (showTangentField != other.showTangentField) || (showPlotName != other.showPlotName); } QString PlotAppearance::penStyleToString( Qt::PenStyle style ) { switch ( style ) { case Qt::NoPen: return "NoPen"; case Qt::SolidLine: return "SolidLine"; case Qt::DashLine: return "DashLine"; case Qt::DotLine: return "DotLine"; case Qt::DashDotLine: return "DashDotLine"; case Qt::DashDotDotLine: return "DashDotDotLine"; case Qt::MPenStyle: case Qt::CustomDashLine: qWarning() << "Unsupported pen style\n"; break; } qWarning() << "Unknown style " << style ; return "SolidLine"; } Qt::PenStyle PlotAppearance::stringToPenStyle( const QString & style ) { if ( style == "NoPen" ) return Qt::NoPen; if ( style == "SolidLine" ) return Qt::SolidLine; if ( style == "DashLine" ) return Qt::DashLine; if ( style == "DotLine" ) return Qt::DotLine; if ( style == "DashDotLine" ) return Qt::DashDotLine; if ( style == "DashDotDotLine" ) return Qt::DashDotDotLine; qWarning() << "Unknown style " << style ; return Qt::SolidLine; } //END class PlotAppearance //BEGIN class DifferentialState DifferentialState::DifferentialState() { x = 0; } DifferentialState::DifferentialState( int order ) { x = 0; setOrder( order ); } void DifferentialState::setOrder( int order ) { bool orderWasZero = (y0.size() == 0); y.resize( order ); y0.resize( order ); if ( orderWasZero && order >= 1 ) y0[0].updateExpression( "1" ); resetToInitial(); } bool DifferentialStates::setStep( const Value & step ) { if ( step.value() <= 0 ) return false; m_step = step; return true; } void DifferentialState::resetToInitial() { x = x0.value(); y = y0; } bool DifferentialState::operator == ( const DifferentialState & other ) const { return (x0 == other.x0) && (x == other.x) && (y0 == other.y0) && (y == other.y); } //END class DifferentialState //BEGIN class DifferentialStates DifferentialStates::DifferentialStates() { m_uniqueState = false; m_order = 0; m_step.updateExpression( 0.05 ); } void DifferentialStates::setOrder( int order ) { m_order = order; for ( int i = 0; i < m_data.size(); ++i ) m_data[i].setOrder( order ); } DifferentialState * DifferentialStates::add() { if ( !m_uniqueState || m_data.isEmpty() ) m_data << DifferentialState( order() ); else qDebug() << "Unable to add another state!\n"; return & m_data[ size() - 1 ]; } void DifferentialStates::setUniqueState( bool unique ) { m_uniqueState = unique; if ( m_uniqueState && m_data.size() > 1 ) { // Remove any states other than the first m_data.resize( 1 ); } } void DifferentialStates::resetToInitial( ) { for ( int i = 0; i < m_data.size(); ++i ) m_data[i].resetToInitial(); } //END class DifferentialStates //BEGIN class Equation Equation::Equation( Type type, Function * parent ) : m_type( type ), m_parent( parent ) { m_usesParameter = false; mptr = 0; if ( type == Differential || type == Cartesian ) { differentialStates.setUniqueState( type == Cartesian ); differentialStates.setOrder( order() ); differentialStates.add(); } } Equation::~ Equation() { } int Equation::order( ) const { if ( type() == Cartesian ) { // For drawing integrals return 1; } else return name(false).count( '\'' ); } int Equation::pmCount() const { return m_fstr.count( PmSymbol ); } QString Equation::name( bool removePrimes ) const { if ( m_fstr.isEmpty() ) return QString(); int open = m_fstr.indexOf( '(' ); int equals = m_fstr.indexOf( '=' ); if ( (equals == -1) && (open == -1) ) return QString(); int pos; if ( ((equals > open) && (open != -1)) || (equals == -1) ) pos = open; else pos = equals; QString n = m_fstr.left( pos ).trimmed(); if ( removePrimes ) n.remove( '\'' ); return n; } bool Equation::looksLikeFunction( ) const { int open = m_fstr.indexOf( '(' ); int equals = m_fstr.indexOf( '=' ); if ( (open != -1) && (open < equals) ) return true; switch ( type() ) { case Cartesian: case Differential: case ParametricY: return (name() != "y"); case Polar: return (name() != "r"); case ParametricX: return (name() != "x"); case Implicit: return false; case Constant: return false; } return true; } void Equation::updateVariables() { if ( type() == Constant ) { return; } m_variables.clear(); if ( looksLikeFunction() ) { int p1 = m_fstr.indexOf( '(' ); int p2 = m_fstr.indexOf( ')' ); QStringList listSplit; if ( (p1 != -1) && (p2 != -1) ) listSplit = m_fstr.mid( p1+1, p2-p1-1 ).split( ',', QString::SkipEmptyParts ); // Variables shouldn't contain spaces! foreach ( QString s, listSplit ) { //krazy:exclude=foreach s = s.remove(' '); if ( !s.isEmpty() ) m_variables << s; } } else switch ( type() ) { case Cartesian: case Differential: m_variables << "x" << "k"; break; case Polar: m_variables << QChar( 0x3b8 ) << "k"; // (theta) break; case ParametricX: case ParametricY: m_variables << "t" << "k"; break; case Implicit: m_variables << "x" << "y" << "k"; break; case Constant: break; } // If we are a differential equation, then add on y, y', etc if ( type() == Differential && !name().isEmpty() ) { QString n = name(); int order = this->order(); for ( int i = 0; i < order; ++i ) { m_variables << n; n += '\''; } } //BEGIN Update whether we accept a parameter or not int expectedNumVariables = 0; switch ( m_type ) { case Cartesian: case ParametricX: case ParametricY: case Polar: expectedNumVariables = 1; break; case Implicit: expectedNumVariables = 2; break; case Differential: expectedNumVariables = order()+1; break; case Constant: expectedNumVariables = 0; break; } m_usesParameter = (variables().size() > expectedNumVariables); //END Update whether we accept a parameter or not } QString Equation::parameterName( ) const { if ( !usesParameter() ) return QString(); int parAt = (type() == Implicit) ? 2 : 1; return variables()[parAt]; } bool Equation::setFstr( const QString & fstr, int * error, int * errorPosition, bool force ) { #define HANDLE_ERROR \ if ( !force ) \ { \ m_fstr = prevFstr; \ updateVariables(); \ } \ else \ { \ qDebug() << "fstr "< maxArg ) { *error = Parser::TooManyArguments; HANDLE_ERROR; /// \todo indicate the position of the invalid argument? return false; } XParser::self()->initEquation( this, (Parser::Error*)error, errorPosition ); if ( *error != Parser::ParseSuccess ) { HANDLE_ERROR; if ( !force ) XParser::self()->initEquation( this ); return false; } differentialStates.setOrder( order() ); return true; } void Equation::setPMSignature( QVector< bool > pmSignature ) { differentialStates.resetToInitial(); m_pmSignature = pmSignature; } bool Equation::operator !=( const Equation & other ) { return (fstr() != other.fstr()) || (differentialStates != other.differentialStates); } Equation & Equation::operator =( const Equation & other ) { setFstr( other.fstr() ); differentialStates = other.differentialStates; return * this; } //END class Equation //BEGIN class Function Function::Function( Type type ) : m_type( type ) { x = y = 0; m_implicitMode = UnfixedXY; usecustomxmin = false; usecustomxmax = false; dmin.updateExpression( QChar('0') ); if ( Settings::anglemode() == Parser::Radians ) dmax.updateExpression( QString(QChar('2')) + PiSymbol ); else dmax.updateExpression( "360" ); switch ( m_type ) { case Cartesian: eq << new Equation( Equation::Cartesian, this ); break; case Polar: eq << new Equation( Equation::Polar, this ); usecustomxmin = true; usecustomxmax = true; break; case Parametric: eq << new Equation( Equation::ParametricX, this ); eq << new Equation( Equation::ParametricY, this ); usecustomxmin = true; usecustomxmax = true; break; case Implicit: eq << new Equation( Equation::Implicit, this ); break; case Differential: eq << new Equation( Equation::Differential, this ); break; } m_id = 0; f0.visible = true; k = 0; } Function::~Function() { foreach ( Equation * e, eq ) delete e; } bool Function::copyFrom( const Function & function ) { bool changed = false; int i = 0; #define COPY_AND_CHECK(s) \ { \ if ( s != function.s ) \ { \ s = function.s; \ changed = true; \ } \ } \ i++; COPY_AND_CHECK( f0 ); // 0 if ( type() == Cartesian ) { COPY_AND_CHECK( f1 ); // 1 COPY_AND_CHECK( f2 ); // 2 COPY_AND_CHECK( integral ); // 3 } COPY_AND_CHECK( dmin ); // 4,1 COPY_AND_CHECK( dmax ); // 5,2 COPY_AND_CHECK( usecustomxmin ); // 6,3 COPY_AND_CHECK( usecustomxmax ); // 7,4 COPY_AND_CHECK( m_parameters ); // 8,5 // handle equations separately for ( int i = 0; i < eq.size(); ++i ) { if ( *eq[i] != *function.eq[i] ) { changed = true; *eq[i] = *function.eq[i]; } } return changed; } QString Function::name() const { QString n = eq[0]->fstr(); for ( int i = 1; i < eq.size(); ++i ) n += '\n' + eq[i]->fstr(); return n; } PlotAppearance & Function::plotAppearance( PMode plot ) { // NOTE: This function is identical to the const one, so changes to this should be applied to both switch ( plot ) { case Function::Derivative0: return f0; case Function::Derivative1: return f1; case Function::Derivative2: return f2; case Function::Integral: return integral; } qCritical() << "Unknown plot " << plot << endl; return f0; } PlotAppearance Function::plotAppearance( PMode plot ) const { // NOTE: This function is identical to the none-const one, so changes to this should be applied to both switch ( plot ) { case Function::Derivative0: return f0; case Function::Derivative1: return f1; case Function::Derivative2: return f2; case Function::Integral: return integral; } qCritical() << "Unknown plot " << plot << endl; return f0; } bool Function::allPlotsAreHidden( ) const { return !f0.visible && !f1.visible && !f2.visible && !integral.visible; } QString Function::typeToString( Type type ) { switch ( type ) { case Cartesian: return "cartesian"; case Parametric: return "parametric"; case Polar: return "polar"; case Implicit: return "implicit"; case Differential: return "differential"; } qWarning() << "Unknown type " << type ; return "unknown"; } Function::Type Function::stringToType( const QString & type ) { if ( type == "cartesian" ) return Cartesian; if ( type == "parametric" ) return Parametric; if ( type == "polar" ) return Polar; if ( type == "implicit" ) return Implicit; if ( type == "differential" ) return Differential; qWarning() << "Unknown type " << type ; return Cartesian; } QList< Plot > Function::plots( PlotCombinations combinations ) const { QList< Plot > list; if ( allPlotsAreHidden() ) return list; Plot plot; plot.setFunctionID( id() ); plot.plotNumberCount = m_parameters.useList ? m_parameters.list.size() + (m_parameters.useSlider?1:0) : 1; bool singlePlot = (!m_parameters.useList && !m_parameters.useSlider) || m_parameters.animating || (~combinations & DifferentParameters) || (!m_parameters.useSlider && m_parameters.useList && m_parameters.list.isEmpty()); if ( singlePlot ) { if ( m_parameters.animating ) plot.parameter = Parameter( Parameter::Animated ); list << plot; } else { int i = 0; if ( m_parameters.useSlider ) { Parameter param( Parameter::Slider ); param.setSliderID( m_parameters.sliderID ); plot.parameter = param; plot.plotNumber = i++; list << plot; } if ( m_parameters.useList ) { const int listsize = m_parameters.list.size(); for ( int pos = 0; pos < listsize; ++pos ) { Parameter param( Parameter::List ); param.setListPos( pos ); plot.parameter = param; plot.plotNumber = i++; list << plot; } } } // Copy each plot in the list for other variations if ( (type() == Cartesian) && (combinations & DifferentDerivatives) ) { QList< Plot > duplicated; for ( PMode p = Derivative0; p <= Integral; p = PMode(p+1) ) { foreach ( Plot plot, list ) { //krazy:exclude=foreach if ( !plotAppearance(p).visible ) continue; plot.plotMode = p; duplicated << plot; } } list = duplicated; } if ( (type() == Differential) && (combinations & DifferentInitialStates) ) { QList< Plot > duplicated; for ( int i = 0; i < eq[0]->differentialStates.size(); ++i ) { foreach ( Plot plot, list ) { //krazy:exclude=foreach plot.stateNumber = i; duplicated << plot; } } list = duplicated; } if ( combinations & DifferentPMSignatures ) { int size = 0; foreach ( Equation * equation, eq ) size += equation->pmCount(); unsigned max = unsigned( std::pow( 2.0, (double)size ) ); QVector< QVector > signatures( max ); for ( unsigned i = 0; i < max; ++i ) { QVector sig( size ); for ( int j = 0; j < size; ++j ) sig[ j ] = i & (1< duplicated; foreach ( const QVector &signature, signatures ) { int at = 0; QList< QVector > pmSignature; foreach ( Equation * equation, eq ) { int pmCount = equation->pmCount(); QVector sig( pmCount ); for ( int i = 0; i < pmCount; ++i ) sig[i] = signature[ i + at]; at += pmCount; pmSignature << sig; } foreach ( Plot plot, list ) { //krazy:exclude=foreach plot.pmSignature = pmSignature; duplicated << plot; } } list = duplicated; } return list; } void Function::addFunctionDependency( Function * function ) { if ( !function || m_dependencies.contains( function->id() ) ) return; Q_ASSERT_X( !function->dependsOn( this ), "addFunctionDependency", "circular dependency" ); m_dependencies << function->id(); } bool Function::dependsOn( Function * function ) const { if ( !function ) return false; if ( m_dependencies.contains( function->id() ) ) return true; foreach ( int functionId, m_dependencies ) { Function * f = XParser::self()->functionWithID( functionId ); if ( f->dependsOn( function ) ) return true; } return false; } //END class Function //BEGIN class ParameterSettings ParameterSettings::ParameterSettings() { animating = false; useSlider = false; sliderID = 0; useList = false; } bool ParameterSettings::operator == ( const ParameterSettings & other ) const { return ( useSlider == other.useSlider ) && ( sliderID == other.sliderID ) && ( useList == other.useList ) && ( list == other.list ); } //END class ParameterSettings //BEGIN class Parameter Parameter::Parameter( Type type ) : m_type( type ) { m_sliderID = -1; m_listPos = -1; } bool Parameter::operator == ( const Parameter & other ) const { return ( type() == other.type() ) && ( listPos() == other.listPos() ) && ( sliderID() == other.sliderID() ); } //END class Parameter //BEGIN class Plot Plot::Plot( ) { stateNumber = -1; plotNumberCount = 1; plotNumber = 0; m_function = 0; m_functionID = -1; plotMode = Function::Derivative0; } bool Plot::operator ==( const Plot & other ) const { return ( m_functionID == other.functionID() ) && ( plotMode == other.plotMode ) && ( parameter == other.parameter ) && ( stateNumber == other.stateNumber ); } void Plot::setFunctionID( int id ) { m_functionID = id; updateCached(); } void Plot::updateCached() { m_function = XParser::self()->functionWithID( m_functionID ); } QString Plot::name( ) const { if ( !m_function ) return QString(); QString n = m_function->name(); if ( m_function->eq[0]->usesParameter() ) n += QString( "\n%1 = %2" ).arg( m_function->eq[0]->parameterName() ).arg( Parser::number( parameterValue() ) ); if ( plotMode == Function::Derivative1 ) n = n.section('=', 0, 0).replace('(', "\'("); if ( plotMode == Function::Derivative2 ) n = n.section('=', 0, 0).replace('(', "\'\'("); if ( plotMode == Function::Integral ) { QString functionName = n.section('=', 0, 0); - n = QChar(0x222B) + ' ' + functionName + "d" + functionName.section('(', 1, 1).remove(')').section(',', 0, 0); + n = QChar(0x222B) + ' ' + functionName + 'd' + functionName.section('(', 1, 1).remove(')').section(',', 0, 0); } return n; } void Plot::updateFunction() const { if ( !m_function ) return; // Update the plus-minus signature assert( pmSignature.size() <= m_function->eq.size() ); for ( int i = 0; i < pmSignature.size(); ++i ) m_function->eq[i]->setPMSignature( pmSignature[i] ); if ( parameter.type() != Parameter::Animated ) m_function->setParameter( parameterValue() ); } double Plot::parameterValue() const { switch ( parameter.type() ) { case Parameter::Unknown: return 0; case Parameter::Slider: { KSliderWindow * sw = View::self()->m_sliderWindow; if ( !sw ) { // Slider window isn't open. Ask View to open it View::self()->updateSliders(); // It should now be open sw = View::self()->m_sliderWindow; assert( sw ); } return sw->value( parameter.sliderID() ); } case Parameter::List: { if ( (parameter.listPos() >= 0) && (parameter.listPos() < m_function->m_parameters.list.size()) ) return m_function->m_parameters.list[ parameter.listPos() ].value(); return 0; } case Parameter::Animated: { qWarning() << "Shouldn't use this function for animated parameter!\n"; return 0; } } return 0; } void Plot::differentiate() { switch ( plotMode ) { case Function::Integral: plotMode = Function::Derivative0; break; case Function::Derivative0: plotMode = Function::Derivative1; break; case Function::Derivative1: plotMode = Function::Derivative2; break; case Function::Derivative2: qWarning() << "Can't handle this yet!\n"; break; } } void Plot::integrate() { switch ( plotMode ) { case Function::Integral: qWarning() << "Can't handle this yet!\n"; break; case Function::Derivative0: plotMode = Function::Integral; break; case Function::Derivative1: plotMode = Function::Derivative0; break; case Function::Derivative2: plotMode = Function::Derivative1; break; } } QColor Plot::color( ) const { Function * f = function(); assert(f); // Shouldn't call color without a function PlotAppearance appearance = f->plotAppearance( plotMode ); if ( (plotNumberCount <= 1) || !appearance.useGradient ) return appearance.color; // Is a gradient int x = plotNumber; int l = plotNumberCount; QLinearGradient lg( 0, 0, l-1, 0 ); lg.setStops( appearance.gradient.stops() ); QImage im( l, 1, QImage::Format_RGB32 ); QPainter p(&im); p.setPen( QPen( lg, 1 ) ); p.drawLine( 0, 0, l, 0 ); return im.pixel( x, 0 ); } int Plot::derivativeNumber( ) const { switch ( plotMode ) { case Function::Integral: return -1; case Function::Derivative0: return 0; case Function::Derivative1: return 1; case Function::Derivative2: return 2; } qWarning() << "Unknown derivative number.\n"; return 0; } DifferentialState * Plot::state( ) const { if ( !function() || (stateNumber < 0) ) return 0; if ( function()->eq[0]->differentialStates.size() <= stateNumber ) return 0; return & function()->eq[0]->differentialStates[stateNumber]; } //END class Plot diff --git a/kmplot/maindlg.h b/kmplot/maindlg.h index 7a484e5..1cf5a68 100644 --- a/kmplot/maindlg.h +++ b/kmplot/maindlg.h @@ -1,243 +1,243 @@ /* * KmPlot - a math. function plotter for the KDE-Desktop * * Copyright (C) 1998, 1999, 2000, 2002 Klaus-Dieter Möller * 2006 David Saxton * * This file is part of the KDE Project. * KmPlot is part of the KDE-EDU Project. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file maindlg.h * @brief Contains the main window class MainDlg. */ #ifndef MainDlg_included #define MainDlg_included // Qt includes #include #include #include #include // KDE includes #include #include #include #include #include #undef GrayScale // local includes #include "coordsconfigdialog.h" #include "view.h" #include "kmplotio.h" class BrowserExtension; class Calculator; class FunctionEditor; class FunctionTools; class KConfigDialog; class KConstantEditor; class QAction; class KRecentFilesAction; class QTimer; class SettingsPageColor; class SettingsPageFonts; class SettingsPageGeneral; class SettingsPageDiagram; /** * @short This is the main window of KmPlot. */ class MainDlg : public KParts::ReadWritePart { Q_OBJECT public: /** Constructor. * @param parentWidget parent widget for this part * @param parent parent object */ MainDlg(QWidget *parentWidget, QObject *parent, const QVariantList& = QVariantList() ); /// Initialized as a pointer to this MainDlg object on creation static MainDlg * self() { return m_self; } /// Cleaning up a bit. virtual ~MainDlg(); /// Is set to true if a file from an old file format was loaded static bool oldfileversion; /// The function editor FunctionEditor * functionEditor() const { return m_functionEditor; } /// The coords config dialog CoordsConfigDialog* coordsDialog(); /// Returns true if any changes are done bool isModified(){return m_modified;} bool queryClose() Q_DECL_OVERRIDE; /// For inserting the title in the function popup menu QAction * m_firstFunctionAction; /// Show the constants editor modal to a parent dialog void editConstantsModal(QWidget *parent); /// Check whether the url links to an existing file static bool fileExists(const QUrl &url); public Q_SLOTS: // DBus interface /// Asks the user and returns true if modified data shall be discarded. Q_SCRIPTABLE bool checkModified(); public slots: /// Implement the coordinate system edit dialog void editAxes(); /// Show the constants editor void editConstants(); /// Toggle whether the sliders window is shown void toggleShowSliders(); /// Revert to the previous document state (in m_undoStack). void undo(); /// Revert to the next document state (in m_redoStack). void redo(); /// Pushes the previous document state to the undo stack and records the current one void requestSaveCurrentState(); ///Save a plot i.e. save the function name and all the settings for the plot void slotSave(); ///Save a plot and choose a name for it void slotSaveas(); ///Print the current plot void slotPrint(); ///Export the current plot as a png, svg or bmp picture void slotExport(); ///Implement the Configure KmPlot dialog void slotSettings(); /// Calls the common function names dialog. void slotNames(); /// Resets the view void slotResetView(); /// Tools menu void calculator(); void findMinimumValue(); void findMaximumValue(); void graphArea(); private: /// Settings the standard and non standard actions of the application. void setupActions(); - /// Called when a file is opened. The filename is is m_url + /// Called when a file is opened. The filename is m_url bool openFile() Q_DECL_OVERRIDE; - - bool saveFile() Q_DECL_OVERRIDE; + /// Called when a file is saved. The filename is m_url + bool saveFile() Q_DECL_OVERRIDE; ///The Recent Files action KRecentFilesAction * m_recentFiles; /// true == modifications not saved bool m_modified; ///An instance of the application config file KSharedConfigPtr m_config; ///A Configure KmPlot dialog instance KConfigDialog* m_settingsDialog; ///The General page for the Configure KmPlot dialog SettingsPageGeneral * m_generalSettings; ///The Colors page for the Configure KmPlot constants SettingsPageColor * m_colorSettings; ///The Fonts page for the Configure KmPlot constants SettingsPageFonts * m_fontsSettings; /// The diagram config page SettingsPageDiagram* m_diagramSettings; /// A dialog used by many tools-menu-items FunctionTools *m_functionTools; /// The calculator dialog Calculator *m_calculator; /// the popup menu shown when cling with the right mouse button on a graph in the graph widget QMenu *m_popupmenu; /// the popup that shows when clicking on the new plot button in the function editor QMenu * m_newPlotMenu; /// Loads and saves the user's file. KmPlotIO *kmplotio; /// Set to true if the application is readonly bool m_readonly; /// MainDlg's parent widget QWidget *m_parent; /// Current file QUrl m_currentfile; /// The axes config dialogs CoordsConfigDialog* m_coordsDialog; /// The constants editor QPointer m_constantEditor; /// The function editor FunctionEditor * m_functionEditor; /// The undo stack QStack m_undoStack; /// The reod stack QStack m_redoStack; /** * The current document state - this is pushed to the undo stack when a new * document state is created. */ QDomDocument m_currentState; /// Timer to ensure saveCurrentState() is called only once for a set of simultaneous changes QTimer * m_saveCurrentStateTimer; /// The undo action QAction * m_undoAction; /// The redo action QAction * m_redoAction; /// A pointer to ourselves static MainDlg * m_self; protected slots: /** * When you click on a File->Open Recent file, it'll open * @param url name of the url to open */ void slotOpenRecent( const QUrl &url ); /// @see requestSaveCurrentState void saveCurrentState(); /// Used when opening a new file void resetUndoRedo(); void setReadOnlyStatusBarText(const QString &); }; class BrowserExtension : public KParts::BrowserExtension { Q_OBJECT public: explicit BrowserExtension(MainDlg*); public slots: // Automatically detected by the host. void print(); }; #endif // MainDlg_included