You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
827 lines
21 KiB
C++
827 lines
21 KiB
C++
/*
|
|
* KmPlot - a math. function plotter for the KDE-Desktop
|
|
*
|
|
* Copyright (C) 1998, 1999 Klaus-Dieter Möller
|
|
* 2000, 2002 kd.moeller@t-online.de
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
// KDE includes
|
|
#include <dcopclient.h>
|
|
#include <kapplication.h>
|
|
#include <kglobal.h>
|
|
#include <kinputdialog.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
|
|
// local includes
|
|
#include "xparser.h"
|
|
|
|
XParser::XParser(bool &mo) : DCOPObject("Parser"), Parser(), m_modified(mo)
|
|
{
|
|
// setup slider support
|
|
setDecimalSymbol( KGlobal::locale()->decimalSymbol() );
|
|
}
|
|
|
|
XParser::~XParser()
|
|
{
|
|
}
|
|
|
|
bool XParser::getext( Ufkt *item, const TQString fstr )
|
|
{
|
|
bool errflg = false;
|
|
int p1, p2, p3, pe;
|
|
TQString tstr;
|
|
pe = fstr.length();
|
|
if ( fstr.find( 'N' ) != -1 )
|
|
item->f_mode = false;
|
|
else
|
|
{
|
|
if ( fstr.find( "A1" ) != -1 )
|
|
item->f1_mode = true;
|
|
if ( fstr.find( "A2" ) != -1 )
|
|
item->f2_mode = true;
|
|
}
|
|
switch ( fstr[0].latin1() )
|
|
{
|
|
case 'x':
|
|
case 'y':
|
|
case 'r':
|
|
item->f1_mode = item->f2_mode = false;
|
|
}
|
|
|
|
p1 = fstr.find( "D[" );
|
|
if ( p1 != -1 )
|
|
{
|
|
p1 += 2;
|
|
const TQString str = fstr.mid( p1, pe - p1);
|
|
p2 = str.find(',');
|
|
p3 = str.find(']');
|
|
if ( p2 > 0 && p2 < p3 )
|
|
{
|
|
tstr = str.left( p2 );
|
|
item->dmin = eval( tstr );
|
|
if ( parserError(false) )
|
|
errflg = true;
|
|
tstr = str.mid( p2 + 1, p3 - p2 - 1 );
|
|
item->dmax = eval( tstr );
|
|
if ( parserError(false) )
|
|
errflg = true;
|
|
if ( item->dmin > item->dmax )
|
|
errflg = true;
|
|
}
|
|
else
|
|
errflg = true;
|
|
}
|
|
p1 = fstr.find( "P[" );
|
|
if ( p1 != -1 )
|
|
{
|
|
int i = 0;
|
|
p1 += 2;
|
|
TQString str = fstr.mid( p1, 1000);
|
|
p3 = str.find( ']' );
|
|
do
|
|
{
|
|
p2 = str.find( ',' );
|
|
if ( p2 == -1 || p2 > p3 )
|
|
p2 = p3;
|
|
tstr = str.left( p2++ );
|
|
str = str.mid( p2, 1000 );
|
|
item->parameters.append( ParameterValueItem(tstr, eval( tstr )) );
|
|
if ( parserError(false) )
|
|
{
|
|
errflg = true;
|
|
break;
|
|
}
|
|
p3 -= p2;
|
|
}
|
|
while ( p3 > 0 && i < 10 );
|
|
}
|
|
|
|
if ( errflg )
|
|
{
|
|
KMessageBox::error( 0, i18n( "Error in extension." ) );
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
double XParser::a1fkt( Ufkt *u_item, double x, double h )
|
|
{
|
|
return ( fkt(u_item, x + h ) - fkt( u_item, x ) ) / h;
|
|
}
|
|
|
|
double XParser::a2fkt( Ufkt *u_item, double x, double h )
|
|
{
|
|
return ( fkt( u_item, x + h + h ) - 2 * fkt( u_item, x + h ) + fkt( u_item, x ) ) / h / h;
|
|
}
|
|
|
|
void XParser::findFunctionName(TQString &function_name, int const id, int const type)
|
|
{
|
|
char last_character;
|
|
int pos;
|
|
if ( function_name.length()==2/*type == XParser::Polar*/ || type == XParser::ParametricX || type == XParser::ParametricY)
|
|
pos=1;
|
|
else
|
|
pos=0;
|
|
for ( ; ; ++pos)
|
|
{
|
|
last_character = 'f';
|
|
for (bool ok=true; last_character<'x'; ++last_character)
|
|
{
|
|
if ( pos==0 && last_character == 'r') continue;
|
|
function_name.tqat(pos)=last_character;
|
|
for( TQValueVector<Ufkt>::iterator it = ufkt.begin(); it != ufkt.end(); ++it)
|
|
{
|
|
if (it == ufkt.begin() && it->fname.isEmpty() ) continue;
|
|
if ( it->fstr.startsWith(function_name+'(') && (int)it->id!=id) //check if the name is free
|
|
ok = false;
|
|
}
|
|
if ( ok) //a free name was found
|
|
{
|
|
//kdDebug() << "function_name:" << function_name << endl;
|
|
return;
|
|
}
|
|
ok = true;
|
|
}
|
|
function_name.tqat(pos)='f';
|
|
function_name.append('f');
|
|
}
|
|
function_name = "e"; //this should never happen
|
|
}
|
|
|
|
void XParser::fixFunctionName( TQString &str, int const type, int const id)
|
|
{
|
|
if ( str.startsWith( "y=" ) ) //we find a free function name
|
|
{
|
|
str.remove( 0, 2 );
|
|
str.prepend("(x)=");
|
|
TQString function_name;
|
|
findFunctionName(function_name, id, type);
|
|
str.prepend( function_name );
|
|
}
|
|
|
|
int p1=str.find('(');
|
|
int p2=str.find(')');
|
|
if( p1>=0 && str.at(p2+1)=='=')
|
|
{
|
|
if ( type == XParser::Polar && str.at(0)!='r' )
|
|
{
|
|
if (str.at(0)=='(')
|
|
{
|
|
str.prepend('f');
|
|
p1++;
|
|
p2++;
|
|
}
|
|
str.prepend('r');
|
|
p1++;
|
|
p2++;
|
|
}
|
|
TQString const fname = str.left(p1);
|
|
for ( TQValueVector<Ufkt>::iterator it = ufkt.begin(); it!=ufkt.end(); ++it )
|
|
{
|
|
if (it->fname == fname)
|
|
{
|
|
str = str.mid(p1,str.length()-1);
|
|
TQString function_name;
|
|
if ( type == XParser::Polar )
|
|
function_name = "rf";
|
|
else if ( type == XParser::ParametricX )
|
|
function_name = "x";
|
|
else if ( type == XParser::ParametricY )
|
|
function_name = "y";
|
|
else
|
|
function_name = "f";
|
|
findFunctionName(function_name, id, type);
|
|
str.prepend( function_name );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if ( p1==-1 || !str.at(p1+1).isLetter() || p2==-1 || str.at(p2+1 )!= '=')
|
|
{
|
|
TQString function_name;
|
|
if ( type == XParser::Polar )
|
|
function_name = "rf";
|
|
else if ( type == XParser::ParametricX )
|
|
function_name = "xf";
|
|
else if ( type == XParser::ParametricY )
|
|
function_name = "yf";
|
|
else
|
|
function_name = "f";
|
|
str.prepend("(x)=");
|
|
findFunctionName(function_name, id, type);
|
|
str.prepend( function_name );
|
|
}
|
|
}
|
|
|
|
double XParser::euler_method(const double x, const TQValueVector<Ufkt>::iterator it)
|
|
{
|
|
double const y = it->oldy + ((x-it->oldx) * it->oldyprim);
|
|
it->oldy = y;
|
|
it->oldx = x;
|
|
it->oldyprim = fkt( it, x ); //yprim;
|
|
return y;
|
|
}
|
|
|
|
TQRgb XParser::defaultColor(int function)
|
|
{
|
|
switch ( function%10 )
|
|
{
|
|
case 0:
|
|
return Settings::color0().rgb();
|
|
break;
|
|
case 1:
|
|
return Settings::color1().rgb();
|
|
break;
|
|
case 2:
|
|
return Settings::color2().rgb();
|
|
break;
|
|
case 3:
|
|
return Settings::color3().rgb();
|
|
break;
|
|
case 4:
|
|
return Settings::color4().rgb();
|
|
break;
|
|
case 5:
|
|
return Settings::color5().rgb();
|
|
break;
|
|
case 6:
|
|
return Settings::color6().rgb();
|
|
break;
|
|
case 7:
|
|
return Settings::color7().rgb();
|
|
break;
|
|
case 8:
|
|
return Settings::color8().rgb();
|
|
break;
|
|
case 9:
|
|
return Settings::color9().rgb();
|
|
break;
|
|
default:
|
|
return Settings::color0().rgb();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void XParser::prepareAddingFunction(Ufkt *temp)
|
|
{
|
|
temp->color = temp->f1_color = temp->f2_color = temp->integral_color = defaultColor(getNextIndex() );
|
|
temp->linewidth = temp->f1_linewidth = temp->f2_linewidth = temp->integral_linewidth = linewidth0;
|
|
temp->f_mode = true;
|
|
temp->f1_mode = false;
|
|
temp->f2_mode = false;
|
|
temp->integral_mode = false;
|
|
temp->integral_precision = Settings::stepWidth();
|
|
temp->usecustomxmin = false;
|
|
temp->usecustomxmax = false;
|
|
temp->use_slider = -1;
|
|
//TODO temp->slider_min = 0; temp->slider_max = 50;
|
|
|
|
}
|
|
int XParser::getNextIndex()
|
|
{
|
|
//return ufkt.count();
|
|
return getNewId();
|
|
}
|
|
|
|
TQStringList XParser::listFunctionNames()
|
|
{
|
|
TQStringList list;
|
|
for( TQValueVector<Ufkt>::iterator it = ufkt.begin(); it != ufkt.end(); ++it)
|
|
{
|
|
list.append(it->fname);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
bool XParser::functionFVisible(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
return ufkt[ix].f_mode;
|
|
}
|
|
bool XParser::functionF1Visible(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
return ufkt[ix].f1_mode;
|
|
}
|
|
bool XParser::functionF2Visible(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
return ufkt[ix].f2_mode;
|
|
}
|
|
bool XParser::functionIntVisible(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
return ufkt[ix].integral_mode;
|
|
}
|
|
|
|
bool XParser::setFunctionFVisible(bool visible, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].f_mode = visible;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionF1Visible(bool visible, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].f1_mode = visible;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionF2Visible(bool visible, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].f2_mode = visible;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionIntVisible(bool visible, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].integral_mode = visible;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
TQString XParser::functionStr(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return "";
|
|
return ufkt[ix].fstr;
|
|
}
|
|
|
|
TQColor XParser::functionFColor(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return TQColor();
|
|
return TQColor(ufkt[ix].color);
|
|
}
|
|
TQColor XParser::functionF1Color(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return TQColor();
|
|
return TQColor(ufkt[ix].f1_color);
|
|
}
|
|
TQColor XParser::functionF2Color(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return TQColor();
|
|
return TQColor(ufkt[ix].f2_color);
|
|
}
|
|
TQColor XParser::functionIntColor(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return TQColor();
|
|
return TQColor(ufkt[ix].integral_color);
|
|
}
|
|
bool XParser::setFunctionFColor(const TQColor &color, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].color = color.rgb();
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionF1Color(const TQColor &color, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].color = color.rgb();
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionF2Color(const TQColor &color, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].color = color.rgb();
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionIntColor(const TQColor &color, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].color = color.rgb();
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
int XParser::functionFLineWidth(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return 0;
|
|
return ufkt[ix].linewidth;
|
|
}
|
|
int XParser::functionF1LineWidth(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return int();
|
|
return ufkt[ix].f1_linewidth;
|
|
}
|
|
int XParser::functionF2LineWidth(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return int();
|
|
return ufkt[ix].f2_linewidth;
|
|
}
|
|
int XParser::functionIntLineWidth(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return int();
|
|
return ufkt[ix].integral_linewidth;
|
|
}
|
|
bool XParser::setFunctionFLineWidth(int linewidth, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].linewidth = linewidth;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionF1LineWidth(int linewidth, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].f1_linewidth = linewidth;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionF2LineWidth(int linewidth, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].f2_linewidth = linewidth;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::setFunctionIntLineWidth(int linewidth, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].integral_linewidth = linewidth;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
TQString XParser::functionMinValue(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return int();
|
|
return ufkt[ix].str_dmin;
|
|
}
|
|
|
|
bool XParser::setFunctionMinValue(const TQString &min, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].str_dmin = min;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
TQString XParser::functionMaxValue(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return int();
|
|
return ufkt[ix].str_dmax;
|
|
}
|
|
|
|
bool XParser::setFunctionMaxValue(const TQString &max, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].str_dmax = max;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
TQString XParser::functionStartXValue(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return int();
|
|
return ufkt[ix].str_startx;
|
|
}
|
|
|
|
bool XParser::setFunctionStartXValue(const TQString &x, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].str_startx = x;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
TQString XParser::functionStartYValue(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return int();
|
|
return ufkt[ix].str_starty;
|
|
}
|
|
|
|
bool XParser::setFunctionStartYValue(const TQString &y, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
ufkt[ix].str_starty = y;
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
TQStringList XParser::functionParameterList(uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return TQStringList();
|
|
Ufkt *item = &ufkt[ix];
|
|
TQStringList str_parameter;
|
|
for ( TQValueList<ParameterValueItem>::iterator it = item->parameters.begin(); it != item->parameters.end(); ++it)
|
|
str_parameter.append( (*it).expression);
|
|
return str_parameter;
|
|
}
|
|
bool XParser::functionAddParameter(const TQString &new_parameter, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
Ufkt *tmp_ufkt = &ufkt[ix];
|
|
for ( TQValueList<ParameterValueItem>::iterator it = tmp_ufkt->parameters.begin(); it != tmp_ufkt->parameters.end(); ++it)
|
|
if ( (*it).expression == new_parameter) //check if the parameter already exists
|
|
return false;
|
|
|
|
double const result = eval(new_parameter);
|
|
if ( parserError(false) != 0)
|
|
return false;
|
|
tmp_ufkt->parameters.append( ParameterValueItem(new_parameter,result) );
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
bool XParser::functionRemoveParameter(const TQString &remove_parameter, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
Ufkt *tmp_ufkt = &ufkt[ix];
|
|
|
|
bool found = false;
|
|
TQValueList<ParameterValueItem>::iterator it;
|
|
for ( it = tmp_ufkt->parameters.begin(); it != tmp_ufkt->parameters.end(); ++it)
|
|
if ( (*it).expression == remove_parameter) //check if the parameter already exists
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
if (!found)
|
|
return false;
|
|
tmp_ufkt->parameters.remove(it);
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
int XParser::addFunction(const TQString &f_str)
|
|
{
|
|
TQString added_function(f_str);
|
|
int const pos = added_function.find(';');
|
|
if (pos!=-1)
|
|
added_function = added_function.left(pos);
|
|
|
|
fixFunctionName(added_function);
|
|
if ( added_function.at(0)== 'x' || added_function.at(0)== 'y') //TODO: Make it possible to define parametric functions
|
|
return -1;
|
|
if ( added_function.contains('y') != 0)
|
|
return -1;
|
|
int const id = addfkt( added_function );
|
|
if (id==-1)
|
|
return -1;
|
|
Ufkt *tmp_ufkt = &ufkt.last();
|
|
prepareAddingFunction(tmp_ufkt);
|
|
if ( pos!=-1 && !getext( tmp_ufkt, f_str ) )
|
|
{
|
|
Parser::delfkt( tmp_ufkt );
|
|
return -1;
|
|
}
|
|
m_modified = true;
|
|
return id;
|
|
}
|
|
|
|
bool XParser::addFunction(const TQString &fstr_const, bool f_mode, bool f1_mode, bool f2_mode, bool integral_mode, bool integral_use_precision, int linewidth, int f1_linewidth, int f2_linewidth, int integral_linewidth, const TQString &str_dmin, const TQString &str_dmax, const TQString &str_startx, const TQString &str_starty, double integral_precision, TQRgb color, TQRgb f1_color, TQRgb f2_color, TQRgb integral_color, TQStringList str_parameter, int use_slider)
|
|
{
|
|
TQString fstr(fstr_const);
|
|
switch ( fstr.tqat(0).latin1() )
|
|
{
|
|
case 'r':
|
|
{
|
|
fixFunctionName(fstr, XParser::Polar);
|
|
break;
|
|
}
|
|
case 'x':
|
|
fixFunctionName(fstr, XParser::ParametricX);
|
|
break;
|
|
case 'y':
|
|
fixFunctionName(fstr, XParser::ParametricY);
|
|
break;
|
|
default:
|
|
fixFunctionName(fstr, XParser::Function);
|
|
break;
|
|
}
|
|
int const id = addfkt( fstr );
|
|
if ( id==-1 )
|
|
return false;
|
|
Ufkt *added_function = &ufkt.last();
|
|
added_function->f_mode = f_mode;
|
|
added_function->f1_mode = f1_mode;
|
|
added_function->f2_mode = f2_mode;
|
|
added_function->integral_mode = integral_mode;
|
|
added_function->integral_use_precision = integral_use_precision;
|
|
added_function->linewidth = linewidth;
|
|
added_function->f1_linewidth = f1_linewidth;
|
|
added_function->f2_linewidth = f2_linewidth;
|
|
added_function->integral_linewidth = integral_linewidth;
|
|
|
|
if ( str_dmin.isEmpty() )
|
|
added_function->usecustomxmin = false;
|
|
else //custom minimum range
|
|
{
|
|
added_function->usecustomxmin = true;
|
|
added_function->str_dmin = str_dmin;
|
|
added_function->dmin = eval(str_dmin);
|
|
}
|
|
if ( str_dmax.isEmpty() )
|
|
added_function->usecustomxmax = false;
|
|
else //custom maximum range
|
|
{
|
|
added_function->usecustomxmax = true;
|
|
added_function->str_dmax = str_dmax;
|
|
added_function->dmax = eval(str_dmax);
|
|
}
|
|
added_function->str_startx = str_startx;
|
|
added_function->str_starty = str_starty;
|
|
if ( !str_starty.isEmpty() )
|
|
added_function->starty = eval(str_starty);
|
|
if ( !str_startx.isEmpty() )
|
|
added_function->startx = eval(str_startx);
|
|
added_function->oldx = 0;
|
|
added_function->integral_precision = integral_precision;
|
|
added_function->color = color;
|
|
added_function->f1_color = f1_color;
|
|
added_function->f2_color = f2_color;
|
|
added_function->integral_color = integral_color;
|
|
added_function->use_slider = use_slider;
|
|
for( TQStringList::Iterator it = str_parameter.begin(); it != str_parameter.end(); ++it )
|
|
{
|
|
double result = eval(*it);
|
|
if ( parserError(false) != 0)
|
|
continue;
|
|
added_function->parameters.append( ParameterValueItem(*it, result ) );
|
|
}
|
|
m_modified = true;
|
|
return true;
|
|
}
|
|
|
|
bool XParser::setFunctionExpression(const TQString &f_str, uint id)
|
|
{
|
|
int const ix = ixValue(id);
|
|
if (ix==-1)
|
|
return false;
|
|
Ufkt *tmp_ufkt = &ufkt[ix];
|
|
TQString const old_fstr = tmp_ufkt->fstr;
|
|
TQString const fstr_begin = tmp_ufkt->fstr.left(tmp_ufkt->fstr.find('=')+1);
|
|
tmp_ufkt->fstr = fstr_begin+f_str;
|
|
reparse(tmp_ufkt);
|
|
if ( parserError(false) != 0)
|
|
{
|
|
tmp_ufkt->fstr = old_fstr;
|
|
reparse(tmp_ufkt);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool XParser::sendFunction(int id, const TQString &dcopclient_target)
|
|
{
|
|
QCStringList cstr_list = kapp->dcopClient()->registeredApplications();
|
|
TQStringList str_list;
|
|
for ( QCStringList::iterator it = cstr_list.begin(); it!=cstr_list.end();++it )
|
|
if ( TQString(*it).startsWith("kmplot") && *it!=kapp->dcopClient()->appId() )
|
|
str_list.append(*it);
|
|
if ( str_list.isEmpty() )
|
|
{
|
|
KMessageBox::error(0, i18n("There are no other Kmplot instances running"));
|
|
return false;
|
|
}
|
|
|
|
Ufkt *item = &ufkt[ixValue(id)];
|
|
kdDebug() << "Transferring " << item->fname.latin1() << endl;
|
|
TQString str_result;
|
|
if ( dcopclient_target.isEmpty() && item->fname.at(0) == 'y' )
|
|
return false;
|
|
else if ( dcopclient_target.isEmpty() )
|
|
{
|
|
bool ok;
|
|
str_result = KInputDialog::getItem(i18n("kmplot"), i18n("Choose which KmPlot instance\nyou want to copy the function to:"), str_list, 0, false, &ok);
|
|
if (!ok)
|
|
return false;
|
|
}
|
|
else
|
|
str_result = dcopclient_target;
|
|
|
|
TQByteArray parameters;
|
|
TQDataStream arg( parameters, IO_WriteOnly);
|
|
|
|
TQString str_dmin;
|
|
if (!item->usecustomxmin)
|
|
str_dmin = item->str_dmin;
|
|
TQString str_dmax;
|
|
if (!item->usecustomxmax)
|
|
str_dmax = item->str_dmax;
|
|
|
|
TQStringList str_parameters;
|
|
for ( TQValueList<ParameterValueItem>::Iterator it = item->parameters.begin(); it != item->parameters.end(); ++it )
|
|
str_parameters.append( (*it).expression);
|
|
arg << item->fstr << item->f_mode << item->f1_mode << item->f2_mode << item->integral_mode << item->integral_use_precision << item->linewidth << item->f1_linewidth << item->f2_linewidth << item->integral_linewidth << str_dmin << str_dmax << item->str_startx << item->str_starty << item->integral_precision << item->color << item->f1_color << item->f2_color << item->integral_color << str_parameters << item->use_slider;
|
|
TQByteArray replay_data;
|
|
TQCString replay_type;
|
|
bool ok = kapp->dcopClient()->call( str_result.utf8(), "Parser", "addFunction(TQString,bool,bool,bool,bool,bool,int,int,int,int,TQString,TQString,TQString,TQString,double,TQRgb,TQRgb,TQRgb,TQRgb,TQStringList,int)", parameters, replay_type, replay_data, false);
|
|
if (!ok)
|
|
{
|
|
KMessageBox::error(0, i18n("An error appeared during the transfer"));
|
|
return false;
|
|
}
|
|
|
|
TQDataStream replay_arg(replay_data, IO_ReadOnly);
|
|
bool result;
|
|
replay_arg >> result;
|
|
if (!result)
|
|
{
|
|
KMessageBox::error(0, i18n("An error appeared during the transfer"));
|
|
return false;
|
|
}
|
|
|
|
kapp->dcopClient()->send(str_result.utf8(), "View","drawPlot()",TQByteArray() ); //update the other window
|
|
|
|
if (item->fname.at(0) == 'x') // a parametric function
|
|
return sendFunction(id+1, str_result);
|
|
else
|
|
return true;
|
|
}
|