Commit 1f29b77f authored by David Saxton's avatar David Saxton

- Renamed *minmax.* to functiontools.* (since it performs more than just

  finding the minimum/maximum of a function).
- Tidied up code for function tools dialog (use widget stack with separate
  widgets for each task, instead of changing the text of the labels, etc).

svn path=/trunk/KDE/kdeedu/kmplot/; revision=560981
parent 4af73fbd
......@@ -17,7 +17,7 @@ set(kmplotpart_PART_SRCS
kprinterdlg.cpp
kconstanteditor.cpp
kparametereditor.cpp
kminmax.cpp
functiontools.cpp
kmplotio.cpp
ksliderwindow.cpp
parameterswidget.cpp
......@@ -38,7 +38,7 @@ kde4_add_ui_files(kmplotpart_PART_SRCS
functioneditorwidget.ui
editcoords.ui
editscaling.ui
qminmax.ui
functiontools.ui
qparametereditor.ui
settingspagecolor.ui
settingspageconstants.ui
......
/*
* KmPlot - a math. function plotter for the KDE-Desktop
*
* Copyright (C) 2004 Fredrik Edemar <f_edemar@linux.se>
* 2006 David Saxton <david@bluehaze.org>
*
* 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 "functiontools.h"
#include "ui_functiontools.h"
#include "view.h"
#include "xparser.h"
class FunctionToolsWidget : public QWidget, public Ui::FunctionTools
{
public:
FunctionToolsWidget( QWidget * parent = 0 ) : QWidget( parent )
{ setupUi(this); }
};
//BEGIN class FunctionTools
FunctionTools::FunctionTools(QWidget *parent )
: KDialog( parent )
{
m_widget = new FunctionToolsWidget( this );
setMainWidget( m_widget );
setButtons( Close );
// Adjust margins
m_widget->layout()->setMargin( 0 );
for ( int i = 0; i < 2; ++ i )
m_widget->stack->widget( i )->layout()->setMargin( 0 );
init( CalculateY );
connect( m_widget->xValue, SIGNAL(textChanged(const QString &)), this, SLOT(xChanged()) );
connect( m_widget->min, SIGNAL(editingFinished()), this, SLOT(rangeEdited()) );
connect( m_widget->max, SIGNAL(editingFinished()), this, SLOT(rangeEdited()) );
connect( m_widget->list, SIGNAL(currentRowChanged(int)), this, SLOT(plotSelected(int)) );
}
FunctionTools::~FunctionTools()
{
}
void FunctionTools::init( Mode m )
{
m_mode = m;
switch ( m_mode )
{
case FindMinimum:
{
m_widget->rangeTitle->setText( i18n("Search between:") );
setCaption(i18n("Find Minimum Point"));
break;
}
case FindMaximum:
{
m_widget->rangeTitle->setText( i18n("Search between:") );
setCaption(i18n("Find Maximum Point"));
break;
}
case CalculateArea:
{
m_widget->rangeTitle->setText( i18n("Calculate the area between:") );
setCaption(i18n("Area Under Graph"));
break;
}
case CalculateY:
{
setCaption(i18n("Get y-Value"));
break;
}
}
if ( m_mode == CalculateY )
{
m_widget->xValue->setFocus();
m_widget->stack->setCurrentIndex( 0 );
}
else
{
m_widget->min->setText( XParser::self()->number( View::self()->m_xmin ) );
m_widget->max->setText( XParser::self()->number( View::self()->m_xmax ) );
m_widget->min->setFocus();
m_widget->stack->setCurrentIndex( 1 );
}
updateEquationList();
setEquation( EquationPair( View::self()->m_currentPlot, 0 ) );
}
void FunctionTools::updateEquationList()
{
EquationPair previousEquation = equation();
m_widget->list->clear();
m_equations.clear();
foreach ( Function * function, XParser::self()->m_ufkt )
{
QList<Plot> plots = function->plots();
for ( int i = 0; i < function->eq.size(); ++i )
{
foreach ( Plot plot, plots )
m_equations << EquationPair( plot, i );
}
}
foreach ( EquationPair eq, m_equations )
{
Equation * equation = eq.first.function()->eq[ eq.second ];
QListWidgetItem * item = new QListWidgetItem( equation->fstr(), m_widget->list );
item->setTextColor( eq.first.color() );
}
setEquation( previousEquation );
}
EquationPair FunctionTools::equation( ) const
{
int row = m_widget->list->currentRow();
if ( row < 0 || row >= m_equations.size() )
return EquationPair();
else
return m_equations[ row ];
}
void FunctionTools::setEquation( const EquationPair & equation )
{
int row = m_equations.indexOf( equation);
if ( row < 0 )
row = 0;
m_widget->list->setCurrentRow( row );
equationSelected( row );
}
void FunctionTools::equationSelected( int equation )
{
if ( equation < 0 || equation >= m_equations.size() )
return;
EquationPair current = m_equations[ equation ];
switch ( m_mode )
{
case FindMinimum:
findMinimum( current );
break;
case FindMaximum:
findMaximum( current );
break;
case CalculateY:
calculateY( current );
break;
case CalculateArea:
calculateArea( current );
break;
}
}
void FunctionTools::xChanged()
{
calculateY( equation() );
}
void FunctionTools::rangeEdited()
{
switch ( m_mode )
{
case FindMinimum:
findMinimum( equation() );
break;
case FindMaximum:
findMaximum( equation() );
break;
case CalculateArea:
calculateArea( equation() );
break;
case CalculateY:
return;
}
}
void FunctionTools::calculateY( const EquationPair & equation )
{
if ( !equation.first.function() )
return;
equation.first.updateFunction();
Equation * eq = equation.first.function()->eq[ equation.second ];
double result = XParser::self()->fkt( eq, m_widget->xValue->value() );
m_widget->yResult->setText( QString( "%1(%2) = %3" )
.arg( eq->name() )
.arg( m_widget->xValue->text() )
.arg( XParser::self()->number( result ) ) );
}
void FunctionTools::findMinimum( const EquationPair & equation )
{
if ( !equation.first.function() )
return;
QPointF extremum = View::self()->findMinMaxValue( equation.first, View::Minimum, m_widget->min->value(), m_widget->max->value() );
m_widget->rangeResult->setText( i18n("Minimum is at x = %1, %2(x) = %3",
extremum.x(),
equation.first.function()->eq[0]->name(),
extremum.y() ) );
}
void FunctionTools::findMaximum( const EquationPair & equation )
{
if ( !equation.first.function() )
return;
QPointF extremum = View::self()->findMinMaxValue( equation.first, View::Maximum, m_widget->min->value(), m_widget->max->value() );
m_widget->rangeResult->setText( i18n("Maximum is at x = %1, %2(x) = %3",
extremum.x(),
equation.first.function()->eq[0]->name(),
extremum.y() ) );
}
void FunctionTools::calculateArea( const EquationPair & equation )
{
IntegralDrawSettings s;
s.plot = equation.first;
s.dmin = m_widget->min->value();
s.dmax = m_widget->max->value();
double area = View::self()->areaUnderGraph( s );
m_widget->rangeResult->setText( i18n("Area is %1", area ) );
}
//END class FunctionTools
#include "functiontools.moc"
......@@ -23,30 +23,28 @@
*
*/
#ifndef KMINMAX_H
#define KMINMAX_H
#ifndef FUNCTIONTOOLS_H
#define FUNCTIONTOOLS_H
#include <kdialog.h>
#include <QListWidget>
#include "view.h"
#include "function.h"
namespace Ui{
class QMinMax;
}
#include <kdialog.h>
#include <QList>
#include <QPair>
class QMinMax;
class QListWidgetItem;
class FunctionToolsWidget;
typedef QPair< Plot, int > EquationPair;
/**
@author Fredrik Edemar
@author Fredrik Edemar, David Saxton
*/
/// KMinMax handles all the dialogs for the items in the tool-menu.
class KMinMax : public KDialog
/// FunctionTools handles all the dialogs for the items in the tool-menu.
class FunctionTools : public KDialog
{
Q_OBJECT
public:
KMinMax(QWidget *parent = 0 );
FunctionTools( QWidget *parent = 0 );
~FunctionTools();
enum Mode
{
......@@ -55,30 +53,68 @@ class KMinMax : public KDialog
CalculateY,
CalculateArea
};
/// called every time the dialog is opened
/**
* Select the right widget to use in the dialog and initalize the plot
* list.
*/
void init( Mode mode );
/**
* Sets the currently selected equation.
*/
void setEquation( const EquationPair & equation );
/**
* \return the currently selected equation.
*/
EquationPair equation() const;
/// update the list with functions
void updateFunctions();
/// select the right function when using the popup menu to show the dialog
void selectItem();
~KMinMax();
public slots:
/// the user has pressen the find/caluclate/draw button
void cmdFind_clicked();
/// the selecting a function that uses parameter function from a list the user can choose which paramater value he/she wants to use
void cmdParameter_clicked();
/// the button for changing the selected parameter value
void list_currentChanged(QListWidgetItem*);
/// call cmdParameter_clicked() if parameter values is enabled for that function
void list_doubleClicked(QListWidgetItem *);
protected Q_SLOTS:
/**
* The user selected a different row in the list of plots. Note that
* \p equation corresponds to the plot in m_equations.
*/
void equationSelected( int equation );
/**
* Called when the min or max range changes.
*/
void rangeEdited();
/**
* Called when the x value in the widget changes.
*/
void xChanged();
protected:
/**
* Updates the list of equation. This creates the list of equation in
* the equations list view and updates m_equations to reflect the
* contents of the list view.
*/
void updateEquationList();
/**
* Find the minimum in the current range.
*/
void findMinimum( const EquationPair & equation );
/**
* Find the maximum in the current range.
*/
void findMaximum( const EquationPair & equation );
/**
* Find the area under the graph
*/
void calculateArea( const EquationPair & equation );
/**
* Calculates the value of the selected function for the currently
* entered x value.
*/
void calculateY( const EquationPair & equation );
private:
Mode m_mode;
Parameter parameter;
QMinMax * m_mainWidget;
FunctionToolsWidget * m_widget;
/**
* List of plots and equations.
*/
QVector<EquationPair> m_equations;
};
#endif
<ui version="4.0" >
<class>FunctionTools</class>
<widget class="QWidget" name="FunctionTools" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>301</width>
<height>396</height>
</rect>
</property>
<property name="windowTitle" >
<string>Function Tools</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QStackedWidget" name="stack" >
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="page" >
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="2" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2" >
<widget class="QLabel" name="yResult" >
<property name="text" >
<string>&lt;></string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
<property name="textInteractionFlags" >
<enum>Qt::TextSelectableByMouse</enum>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="EquationEdit" name="xValue" >
<property name="text" >
<string>0</string>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>x:</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2" >
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="0" colspan="2" >
<widget class="QLabel" name="rangeTitle" >
<property name="text" >
<string>&lt;>:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QLabel" name="rangeResult" >
<property name="text" >
<string>&lt;></string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
<property name="textInteractionFlags" >
<enum>Qt::TextSelectableByMouse</enum>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="EquationEdit" name="max" >
<property name="toolTip" >
<string>Upper boundary of the plot range</string>
</property>
<property name="whatsThis" >
<string>Enter the upper boundary of the plot range. Expressions like 2*pi are allowed, too.</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="EquationEdit" name="min" >
<property name="toolTip" >
<string>Lower boundary of the plot range</string>
</property>
<property name="whatsThis" >
<string>Enter the lower boundary of the plot range. Expressions like 2*pi are allowed, too.</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_4" >
<property name="text" >
<string>Min:</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_5" >
<property name="text" >
<string>Max:</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QListWidget" name="list" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>7</vsizetype>
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>EquationEdit</class>
<extends>KLineEdit</extends>
<header>equationedit.h</header>
</customwidget>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
/*
* KmPlot - a math. function plotter for the KDE-Desktop
*
* Copyright (C) 2004 Fredrik Edemar <f_edemar@linux.se>
* 2006 David Saxton <david@bluehaze.org>
*
* 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 <kinputdialog.h>
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kpushbutton.h>
#include <qlabel.h>