summaryrefslogtreecommitdiffstats
path: root/kspread/functions.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kspread/functions.cc')
-rw-r--r--kspread/functions.cc526
1 files changed, 0 insertions, 526 deletions
diff --git a/kspread/functions.cc b/kspread/functions.cc
deleted file mode 100644
index f6bc16e2f..000000000
--- a/kspread/functions.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2003,2004 Ariya Hidayat <ariya@kde.org>
- Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
-*/
-
-#include "formula.h"
-#include "functions.h"
-#include "valuecalc.h"
-
-#include <tqdict.h>
-#include <tqdom.h>
-#include <tqfile.h>
-#include <tqvaluevector.h>
-
-#include <kdebug.h>
-#include <tdelocale.h>
-#include <kstandarddirs.h>
-#include <kstaticdeleter.h>
-
-#include "kspread_factory.h"
-
-namespace KSpread
-{
-
-class Function::Private
-{
-public:
- TQString name;
- FunctionPtr ptr;
- int paramMin, paramMax;
- bool acceptArray;
- bool ne; // need FunctionExtra* when called ?
-};
-
-class FunctionRepository::Private
-{
-public:
- TQDict<Function> functions;
- TQDict<FunctionDescription> funcs;
-};
-
-} // namespace KSpread
-
-
-using namespace KSpread;
-
-Function::Function( const TQString& name, FunctionPtr ptr )
-{
- d = new Private;
- d->name = name;
- d->ptr = ptr;
- d->acceptArray = false;
- d->paramMin = 1;
- d->paramMax = 1;
- d->ne = false;
-}
-
-Function::~Function()
-{
- delete d;
-}
-
-TQString Function::name() const
-{
- return d->name;
-}
-
-void Function::setParamCount (int min, int max)
-{
- d->paramMin = min;
- d->paramMax = (max == 0) ? min : max;
-}
-
-bool Function::paramCountOkay (int count)
-{
- // less than needed
- if (count < d->paramMin) return false;
- // no upper limit
- if (d->paramMax == -1) return true;
- // more than needed
- if (count > d->paramMax) return false;
- // okay otherwise
- return true;
-}
-
-void Function::setAcceptArray (bool accept) {
- d->acceptArray = accept;
-}
-
-bool Function::needsExtra () {
- return d->ne;
-}
-void Function::setNeedsExtra (bool extra) {
- d->ne = extra;
-}
-
-Value Function::exec (valVector args, ValueCalc *calc, FuncExtra *extra)
-{
- // check number of parameters
- if (!paramCountOkay (args.count()))
- return Value::errorVALUE();
-
- // do we need to perform array expansion ?
- bool mustExpandArray = false;
- if (!d->acceptArray)
- for (unsigned int i = 0; i < args.count(); ++i) {
- if (args[i].isArray())
- mustExpandArray = true;
- }
-
- if( !d->ptr ) return Value::errorVALUE();
-
- // perform the actual array expansion if need be
-
- if (mustExpandArray) {
- // compute number of rows/cols of the result
- int rows = 0;
- int cols = 0;
- for (unsigned int i = 0; i < args.count(); ++i) {
- int x = (args[i].type() == Value::Array) ? args[i].rows() : 1;
- if (x > rows) rows = x;
- x = (args[i].type() == Value::Array) ? args[i].columns() : 1;
- if (x > cols) cols = x;
- }
- // allocate the resulting array
- Value res (cols, rows);
- // perform the actual computation for each element of the array
- for (int row = 0; row < rows; ++row)
- for (int col = 0; col < cols; ++col) {
- // fill in the parameter vector
- valVector vals (args.count());
- for (unsigned int i = 0; i < args.count(); ++i) {
- int r = args[i].rows();
- int c = args[i].columns();
- vals[i] = args[i].isArray() ?
- args[i].element (col % c, row % r): args[i];
- }
-
- // execute the function on each element
- res.setElement (col, row, exec (vals, calc, extra));
- }
- return res;
- }
- else
- // call the function
- return (*d->ptr) (args, calc, extra);
-}
-
-
-// these are defined in kspread_function_*.cc
-void RegisterConversionFunctions();
-void RegisterDatabaseFunctions();
-void RegisterDateTimeFunctions();
-void RegisterEngineeringFunctions();
-void RegisterFinancialFunctions();
-void RegisterInformationFunctions();
-void RegisterLogicFunctions();
-void RegisterMathFunctions();
-void RegisterReferenceFunctions();
-void RegisterStatisticalFunctions();
-void RegisterTextFunctions();
-void RegisterTrigFunctions();
-
-
-static KStaticDeleter<FunctionRepository> fr_sd;
-FunctionRepository* FunctionRepository::s_self = 0;
-
-FunctionRepository* FunctionRepository::self()
-{
- if( !s_self )
- {
- kdDebug() << "Creating function repository" << endl;
-
- fr_sd.setObject( s_self, new FunctionRepository() );
-
- kdDebug() << "Registering functions" << endl;
-
- // register all existing functions
- RegisterConversionFunctions();
- RegisterDatabaseFunctions();
- RegisterDateTimeFunctions();
- RegisterEngineeringFunctions();
- RegisterFinancialFunctions();
- RegisterInformationFunctions();
- RegisterLogicFunctions();
- RegisterMathFunctions();
- RegisterReferenceFunctions();
- RegisterStatisticalFunctions();
- RegisterTextFunctions();
- RegisterTrigFunctions();
-
- kdDebug() << "Functions registered, loading descriptions" << endl;
-
- // find all XML description files
- TQStringList files = Factory::global()->dirs()->findAllResources
- ("extensions", "*.xml", TRUE);
-
- // load desc/help from XML file
- for( TQStringList::Iterator it = files.begin(); it != files.end(); ++it )
- s_self->loadFile (*it);
-
- kdDebug() << "All ok, repository ready" << endl;
-
- }
- return s_self;
-}
-
-FunctionRepository::FunctionRepository()
-{
- d = new Private;
-
- d->functions.setAutoDelete( true );
- d->funcs.setAutoDelete( true );
-}
-
-FunctionRepository::~FunctionRepository()
-{
- delete d;
- s_self = 0;
-}
-
-void FunctionRepository::add( Function* function )
-{
- if( !function ) return;
- d->functions.insert( function->name().upper(), function );
-}
-
-Function *FunctionRepository::function (const TQString& name)
-{
- return d->functions.find (name.upper());
-}
-
-FunctionDescription *FunctionRepository::functionInfo (const TQString& name)
-{
- return d->funcs.find (name.upper());
-}
-
-// returns names of function in certain group
-TQStringList FunctionRepository::functionNames( const TQString& group )
-{
- TQStringList lst;
-
- TQDictIterator<FunctionDescription> it (d->funcs);
- for(; it.current(); ++it) {
- if (group.isNull() || (it.current()->group() == group))
- lst.append (it.current()->name());
- }
-
- lst.sort();
- return lst;
-}
-
-void FunctionRepository::loadFile (const TQString& filename)
-{
- TQFile file (filename);
- if (!file.open (IO_ReadOnly))
- return;
-
- TQDomDocument doc;
- doc.setContent( &file );
- file.close();
-
- TQString group = "";
-
- TQDomNode n = doc.documentElement().firstChild();
- for (; !n.isNull(); n = n.nextSibling())
- {
- if (!n.isElement())
- continue;
- TQDomElement e = n.toElement();
- if (e.tagName() == "Group")
- {
- group = i18n (e.namedItem ("GroupName").toElement().text().utf8());
- m_groups.append( group );
- m_groups.sort();
-
- TQDomNode n2 = e.firstChild();
- for (; !n2.isNull(); n2 = n2.nextSibling())
- {
- if (!n2.isElement())
- continue;
- TQDomElement e2 = n2.toElement();
- if (e2.tagName() == "Function")
- {
- FunctionDescription* desc = new FunctionDescription( e2 );
- desc->setGroup (group);
- if (d->functions.find (desc->name()))
- d->funcs.insert (desc->name(), desc);
- }
- }
- group = "";
- }
- }
-}
-
-// ------------------------------------------------------------
-
-static ParameterType toType( const TQString& type )
-{
- if ( type == "Boolean" )
- return KSpread_Boolean;
- if ( type == "Int" )
- return KSpread_Int;
- if ( type == "String" )
- return KSpread_String;
- if ( type == "Any" )
- return KSpread_Any;
-
- return KSpread_Float;
-}
-
-static TQString toString (ParameterType type, bool range = FALSE)
-{
- if ( !range )
- {
- switch(type) {
- case KSpread_String:
- return i18n("Text");
- case KSpread_Int:
- return i18n("Whole number (like 1, 132, 2344)");
- case KSpread_Boolean:
- return i18n("A truth value (TRUE or FALSE)" );
- case KSpread_Float:
- return i18n("A floating point value (like 1.3, 0.343, 253 )" );
- case KSpread_Any:
- return i18n("Any kind of value");
- }
- }
- else
- {
- switch(type) {
- case KSpread_String:
- return i18n("A range of strings");
- case KSpread_Int:
- return i18n("A range of whole numbers (like 1, 132, 2344)");
- case KSpread_Boolean:
- return i18n("A range of truth values (TRUE or FALSE)" );
- case KSpread_Float:
- return i18n("A range of floating point values (like 1.3, 0.343, 253 )" );
- case KSpread_Any:
- return i18n("A range of any kind of values");
- }
- }
-
- return TQString();
-}
-
-FunctionParameter::FunctionParameter()
-{
- m_type = KSpread_Float;
- m_range = FALSE;
-}
-
-FunctionParameter::FunctionParameter (const FunctionParameter& param)
-{
- m_help = param.m_help;
- m_type = param.m_type;
- m_range = param.m_range;
-}
-
-FunctionParameter::FunctionParameter (const TQDomElement& element)
-{
- m_type = KSpread_Float;
- m_range = FALSE;
-
- TQDomNode n = element.firstChild();
- for( ; !n.isNull(); n = n.nextSibling() )
- if ( n.isElement() )
- {
- TQDomElement e = n.toElement();
- if ( e.tagName() == "Comment" )
- m_help = i18n( e.text().utf8() );
- else if ( e.tagName() == "Type" )
- {
- m_type = toType( e.text() );
- if ( e.hasAttribute( "range" ))
- {
- if (e.attribute("range").lower() == "true")
- m_range = TRUE;
- }
- }
- }
-}
-
-FunctionDescription::FunctionDescription()
-{
- m_type = KSpread_Float;
-}
-
-FunctionDescription::FunctionDescription (const TQDomElement& element)
-{
- TQDomNode n = element.firstChild();
- for( ; !n.isNull(); n = n.nextSibling() )
- {
- if (!n.isElement())
- continue;
- TQDomElement e = n.toElement();
- if ( e.tagName() == "Name" )
- m_name = e.text();
- else if ( e.tagName() == "Type" )
- m_type = toType( e.text() );
- else if ( e.tagName() == "Parameter" )
- m_params.append (FunctionParameter (e));
- else if ( e.tagName() == "Help" )
- {
- TQDomNode n2 = e.firstChild();
- for( ; !n2.isNull(); n2 = n2.nextSibling() )
- {
- if (!n2.isElement())
- continue;
- TQDomElement e2 = n2.toElement();
- if ( e2.tagName() == "Text" )
- m_help.append ( i18n( e2.text().utf8() ) );
- else if ( e2.tagName() == "Syntax" )
- m_syntax.append( i18n( e2.text().utf8() ) );
- else if ( e2.tagName() == "Example" )
- m_examples.append( i18n( e2.text().utf8() ) );
- else if ( e2.tagName() == "Related" )
- m_related.append( i18n( e2.text().utf8() ) );
- }
- }
- }
-}
-
-FunctionDescription::FunctionDescription( const FunctionDescription& desc )
-{
- m_examples = desc.m_examples;
- m_related = desc.m_related;
- m_syntax = desc.m_syntax;
- m_help = desc.m_help;
- m_name = desc.m_name;
- m_type = desc.m_type;
-}
-
-TQString FunctionDescription::toTQML() const
-{
- TQString text( "<qt><h1>" );
- text += name();
- text += "</h1>";
-
- if( !m_help.isEmpty() )
- {
- text += i18n("<p>");
- TQStringList::ConstIterator it = m_help.begin();
- for( ; it != m_help.end(); ++it )
- {
- text += *it;
- text += "<p>";
- }
- text += "</p>";
- }
-
- text += i18n("<p><b>Return type: </b>");
- text += toString( type() );
- text += "</p>";
-
- if ( !m_syntax.isEmpty() )
- {
- text += i18n("<h2>Syntax</h2><ul>");
- TQStringList::ConstIterator it = m_syntax.begin();
- for( ; it != m_syntax.end(); ++it )
- {
- text += "<li>";
- text += *it;
- }
- text += "</ul>";
- }
-
- if ( !m_params.isEmpty() )
- {
- text += i18n("<h2>Parameters</h2><ul>");
- TQValueList<FunctionParameter>::ConstIterator it = m_params.begin();
- for( ; it != m_params.end(); ++it )
- {
- text += i18n("<li><b>Comment:</b> ");
- text += (*it).helpText();
- text += i18n("<br><b>Type:</b> ");
- text += toString( (*it).type(), (*it).hasRange() );
- }
- text += "</ul>";
- }
-
- if ( !m_examples.isEmpty() )
- {
- text += i18n("<h2>Examples</h2><ul>");
- TQStringList::ConstIterator it = m_examples.begin();
- for( ; it != m_examples.end(); ++it )
- {
- text += "<li>";
- text += *it;
- }
- text += "</ul>";
- }
-
- if ( !m_related.isEmpty() )
- {
- text += i18n("<h2>Related Functions</h2><ul>");
- TQStringList::ConstIterator it = m_related.begin();
- for( ; it != m_related.end(); ++it )
- {
- text += "<li>";
- text += "<a href=\"" + *it + "\">";
- text += *it;
- text += "</a>";
- }
- text += "</ul>";
- }
-
- text += "</qt>";
- return text;
-}