2 * KmPlot - a math. function plotter for the KDE-Desktop
4 * Copyright (C) 2004 Fredrik Edemar
7 * This file is part of the KDE Project.
8 * KmPlot is part of the KDE-EDU Project.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include <kinputdialog.h>
27 #include <klineedit.h>
29 #include <kmessagebox.h>
30 #include <kpushbutton.h>
33 #include <qwhatsthis.h>
39 KMinMax::KMinMax(View
*v
, QWidget
*parent
, const char *name
)
40 : QMinMax(parent
, name
), m_view(v
)
43 connect( cmdClose
, SIGNAL( clicked() ), this, SLOT( close() ));
44 connect( cmdFind
, SIGNAL( clicked() ), this, SLOT( cmdFind_clicked() ));
45 connect( cmdParameter
, SIGNAL( clicked() ), this, SLOT( cmdParameter_clicked() ));
46 connect( list
, SIGNAL( highlighted(QListBoxItem
*) ), this, SLOT( list_highlighted(QListBoxItem
*) ));
47 connect( list
, SIGNAL( doubleClicked( QListBoxItem
* ) ), this, SLOT( list_doubleClicked(QListBoxItem
*) ));
52 void KMinMax::init(char m
)
56 if ( m_mode
== 2) //get y-value
63 if ( m_mode
< 2) //find minimum point
65 max
->setReadOnly(false);
67 range
.setNum(View::xmin
);
69 range
.setNum(View::xmax
);
71 lblMin
->setText(i18n("Search between the x-value:"));
72 lblMax
->setText(i18n("and:"));
73 cmdFind
->setText(i18n("&Find"));
74 QToolTip::add(min
,i18n("lower boundary of the plot range"));
75 QWhatsThis::add(min
,i18n("Enter the lower boundary of the plot range. Expressions like 2*pi are allowed, too."));
76 QToolTip::add(max
,i18n("upper boundary of the plot range"));
77 QWhatsThis::add(max
,i18n("Enter the upper boundary of the plot range. Expressions like 2*pi are allowed, too."));
79 if ( m_mode
== 1) //find maximum point
81 setCaption(i18n("Find Maximum Point"));
82 QToolTip::add( cmdFind
, i18n( "Search for the maximum point in the range you specified" ) );
83 QWhatsThis::add(cmdFind
,i18n("Search for the highest y-value in the x-range you specified and show the result in a message box."));
87 setCaption(i18n("Find Minimum Point"));
88 QToolTip::add( cmdFind
, i18n( "Search for the minimum point in the range you specified" ) );
89 QWhatsThis::add(cmdFind
,i18n("Search for the lowest y-value in the x-range you specified and show the result in a message box."));
92 else if ( m_mode
== 2) //get y-value
94 setCaption(i18n("Get y-Value"));
95 lblMin
->setText(i18n("X:"));
96 lblMax
->setText(i18n("Y:"));
97 max
->setReadOnly(true);
100 QToolTip::add(min
,i18n("lower boundary of the plot range"));
101 QWhatsThis::add(min
,i18n("Enter the lower boundary of the plot range. Expressions like 2*pi are allowed, too."));
102 QToolTip::add(max
,i18n("No returned y-value yet"));
103 QWhatsThis::add(max
,i18n("Here you will see the y-value which you got from the x-value in the textbox above. To calculate the y-value, press the Calculate button."));
105 cmdFind
->setText(i18n("&Calculate"));
106 QToolTip::add( cmdFind
, i18n( "Get the y-value from the x-value you typed" ) );
107 QWhatsThis::add(cmdFind
,i18n("Get the y-value from the x-value you typed and show it in the y-value box."));
110 else if ( m_mode
== 3) //area under a graph
112 max
->setReadOnly(false);
114 range
.setNum(View::xmin
);
115 min
->setText( range
);
116 range
.setNum(View::xmax
);
118 QToolTip::add(min
,i18n("lower boundary of the plot range"));
119 QWhatsThis::add(min
,i18n("Enter the lower boundary of the plot range. Expressions like 2*pi are allowed, too."));
120 QToolTip::add(max
,i18n("upper boundary of the plot range"));
121 QWhatsThis::add(max
,i18n("Enter the upper boundary of the plot range. Expressions like 2*pi are allowed, too."));
123 setCaption(i18n("Area Under Graph"));
124 lblMin
->setText(i18n("Draw the area between the x-values:"));
125 lblMax
->setText(i18n("and:"));
126 cmdFind
->setText(i18n("&Draw"));
127 QToolTip::add( cmdFind
, i18n( "Draw the area between the function and the y-axis" ) );
128 QWhatsThis::add(cmdFind
,i18n("Draw the area between the function and the y-axis and show the area in a message box."));
136 void KMinMax::updateFunctions()
138 QString
const selected_item(list
->currentText() );
141 for( QValueVector
<Ufkt
>::iterator it
= m_view
->parser()->ufkt
.begin(); it
!= m_view
->parser()->ufkt
.end(); ++it
)
143 if( it
->fname
[0] != 'x' && it
->fname
[0] != 'y' && it
->fname
[0] != 'r' && !it
->fname
.isEmpty())
146 list
->insertItem(it
->fstr
);
148 if ( it
->f1_mode
) //1st derivative
150 QString
function (it
->fstr
);
151 int i
= function
.find('(');
152 function
.truncate(i
);
154 list
->insertItem(function
);
156 if ( it
->f2_mode
)//2nd derivative
158 QString
function (it
->fstr
);
159 int i
= function
.find('(');
160 function
.truncate(i
);
162 list
->insertItem(function
);
164 if ( it
->integral_mode
)//integral
166 QString
function (it
->fstr
);
167 int i
= function
.find('(');
168 function
.truncate(i
);
169 function
= function
.upper();
170 list
->insertItem(function
);
175 if (list
->count()==0) //empty list
176 cmdFind
->setEnabled(false);
178 cmdFind
->setEnabled(true);
180 QListBoxItem
*found_item
= list
->findItem(selected_item
,Qt::ExactMatch
);
181 if ( found_item
&& m_view
->csmode
< 0)
182 list
->setSelected(found_item
,true);
185 void KMinMax::selectItem()
187 cmdParameter
->hide();
188 if ( m_view
->csmode
< 0)
190 //kdDebug() << "cstype: " << (int)m_view->cstype << endl;
191 Ufkt
*ufkt
= &m_view
->parser()->ufkt
[m_view
->parser()->ixValue(m_view
->csmode
)];
192 QString function
= ufkt
->fstr
;
193 if ( m_view
->cstype
== 2)
195 int i
= function
.find('(');
196 function
.truncate(i
);
199 else if ( m_view
->cstype
== 1)
201 int i
= function
.find('(');
202 function
.truncate(i
);
205 //kdDebug() << "function: " << function << endl;
206 QListBoxItem
*item
= list
->findItem(function
,Qt::ExactMatch
);
207 list
->setSelected(item
,true);
209 if ( !ufkt
->parameters
.isEmpty() )
210 parameter
= ufkt
->parameters
[m_view
->csparam
].expression
;
217 void KMinMax::cmdFind_clicked()
219 if ( list
->currentItem() == -1)
221 KMessageBox::error(this, i18n("Please choose a function"));
225 dmin
= m_view
->parser()->eval(min
->text() );
226 if ( m_view
->parser()->parserError()!=0 )
234 dmax
= m_view
->parser()->eval(max
->text() );
235 if ( m_view
->parser()->parserError()!=0 )
243 KMessageBox::error(this,i18n("The minimum range value must be lower than the maximum range value"));
249 if ( dmin
<View::xmin
|| dmax
>View::xmax
)
251 KMessageBox::error(this,i18n("Please insert a minimum and maximum range between %1 and %2").arg(View::xmin
).arg(View::xmax
) );
259 QString
function( list
->currentText() );
261 if ( function
.contains('\'') == 1)
264 int pos
= function
.find('\'');
265 function
.remove(pos
,1);
267 else if ( function
.contains('\'') == 2)
270 int pos
= function
.find('\'');
271 function
.remove(pos
,2);
273 else if ( function
.at(0).category() == QChar::Letter_Uppercase
)
276 function
.at(0) = function
.at(0).lower();
281 QString sec_function
= function
.section('(',0,0);
283 for( QValueVector
<Ufkt
>::iterator it
= m_view
->parser()->ufkt
.begin(); it
!= m_view
->parser()->ufkt
.end(); ++it
)
285 if ( it
->fstr
.section('(',0,0) == sec_function
)
293 KMessageBox::error(this,i18n("Function could not be found"));
297 if ( ufkt
->parameters
.isEmpty() )
299 else if ( parameter
.isEmpty())
301 KMessageBox::error(this,i18n("You must choose a parameter for that function"));
302 list_highlighted(list
->selectedItem() );
309 m_view
->findMinMaxValue(ufkt
,p_mode
,true,dmin
,dmax
,parameter
);
310 if ( !m_view
->isCalculationStopped() )
311 KMessageBox::information(this,i18n("Minimum value:\nx: %1\ny: %2").arg(dmin
).arg(dmax
) );
313 else if ( m_mode
== 1)
315 m_view
->findMinMaxValue(ufkt
,p_mode
,false,dmin
,dmax
,parameter
);
316 if ( !m_view
->isCalculationStopped() )
317 KMessageBox::information(this,i18n("Maximum value:\nx: %1\ny: %2").arg(dmin
).arg(dmax
));
319 else if ( m_mode
== 2)
321 m_view
->getYValue(ufkt
,p_mode
,dmin
,dmax
,parameter
);
322 if ( !m_view
->isCalculationStopped() )
328 QToolTip::add(max
,i18n("The returned y-value"));
329 QWhatsThis::add(max
,i18n("Here you see the result of the calculation: the returned y-value you got from the x-value in the textbox above"));
331 else if ( m_mode
== 3)
333 double dmin_tmp
= dmin
;
334 m_view
->areaUnderGraph(ufkt
,p_mode
,dmin
,dmax
,parameter
, 0);
335 if ( !m_view
->isCalculationStopped() )
339 KMessageBox::information(this,i18n("The area between %1 and %2\nis: %3").arg(dmin_tmp
).arg(dmax
).arg(dmin
));
343 if ( m_view
->isCalculationStopped() )
344 KMessageBox::error(this,i18n("The operation was cancelled by the user."));
346 void KMinMax::list_highlighted(QListBoxItem
* item
)
350 cmdParameter
->hide();
353 QString
function( list
->currentText() );
355 if ( function
.contains('\'') == 1)
358 int pos
= function
.find('\'');
359 function
.remove(pos
,1);
361 else if ( function
.contains('\'') == 2)
364 int pos
= function
.find('\'');
365 function
.remove(pos
,2);
367 else if ( function
.at(0).category() == QChar::Letter_Uppercase
)
370 function
.at(0) = function
.at(0).lower();
372 QString
const sec_function
= function
.section('(',0,0);
373 for(QValueVector
<Ufkt
>::iterator it
= m_view
->parser()->ufkt
.begin(); it
!=m_view
->parser()->ufkt
.end(); ++it
)
375 if ( it
->fstr
.section('(',0,0) == sec_function
)
377 if ( it
->parameters
.count() == 0)
378 cmdParameter
->hide();
380 cmdParameter
->show();
381 if (parameter
.isEmpty() )
382 parameter
= it
->parameters
.first().expression
;
387 void KMinMax::cmdParameter_clicked()
389 QString
function( list
->currentText() );
391 if ( function
.contains('\'') == 1)
394 int pos
= function
.find('\'');
395 function
.remove(pos
,1);
397 else if ( function
.contains('\'') == 2)
400 int pos
= function
.find('\'');
401 function
.remove(pos
,2);
403 else if ( function
.at(0).category() == QChar::Letter_Uppercase
)
406 function
.at(0) = function
.at(0).lower();
409 QString
const sec_function
= function
.section('(',0,0);
410 for(QValueVector
<Ufkt
>::iterator it
= m_view
->parser()->ufkt
.begin() ; it
!=m_view
->parser()->ufkt
.end(); ++it
)
412 if ( it
->fstr
.section('(',0,0) == sec_function
)
414 QStringList str_parameters
;
415 for ( QValueList
<ParameterValueItem
>::Iterator k
= it
->parameters
.begin(); k
!= it
->parameters
.end(); ++k
)
416 str_parameters
.append( (*k
).expression
);
418 QStringList result
= KInputDialog::getItemList( i18n("Choose Parameter"), i18n("Choose a parameter to use:"), str_parameters
, QStringList(parameter
),false,&ok
,this );
420 parameter
= result
.first();
426 void KMinMax::list_doubleClicked(QListBoxItem
*)
428 if ( list
->currentItem() == -1)
430 else if( cmdParameter
->isShown() )
431 cmdParameter_clicked();
433 #include "kminmax.moc"