kspread Library API Documentation

kspread_functions.cc

00001 #include "kspread_functions.h"
00002 #include "kspread_factory.h"
00003 
00004 #include <qdom.h>
00005 #include <qfile.h>
00006 
00007 #include <kdebug.h>
00008 #include <klocale.h>
00009 #include <kstandarddirs.h>
00010 #include <kstaticdeleter.h>
00011 #include <kinstance.h>
00012 
00013 // these are defined in kspread_function_*.cc
00014 void KSpreadRegisterConversionFunctions();
00015 void KSpreadRegisterDatabaseFunctions();
00016 void KSpreadRegisterDateTimeFunctions();
00017 void KSpreadRegisterEngineeringFunctions();
00018 void KSpreadRegisterFinancialFunctions();
00019 void KSpreadRegisterInformationFunctions();
00020 void KSpreadRegisterLogicFunctions();
00021 void KSpreadRegisterMathFunctions();
00022 void KSpreadRegisterReferenceFunctions();
00023 void KSpreadRegisterStatisticalFunctions();
00024 void KSpreadRegisterTextFunctions();
00025 void KSpreadRegisterTrigFunctions();
00026 
00027 static KSpreadParameterType toType( const QString& type )
00028 {
00029     if ( type == "Boolean" )
00030     return KSpread_Boolean;
00031     if ( type == "Int" )
00032     return KSpread_Int;
00033     if ( type == "String" )
00034     return KSpread_String;
00035     if ( type == "Any" )
00036     return KSpread_Any;
00037 
00038     return KSpread_Float;
00039 }
00040 
00041 static QString toString( KSpreadParameterType type, bool range = FALSE )
00042 {
00043     if ( !range )
00044     {
00045     switch( type )
00046     {
00047     case KSpread_String:
00048         return i18n("Text");
00049     case KSpread_Int:
00050         return i18n("Whole number (like 1, 132, 2344)");
00051     case KSpread_Boolean:
00052         return i18n("A truth value (TRUE or FALSE)" );
00053     case KSpread_Float:
00054         return i18n("A floating point value (like 1.3, 0.343, 253 )" );
00055     case KSpread_Any:
00056         return i18n("Any kind of value");
00057     }
00058     }
00059     else
00060     {
00061     switch( type )
00062     {
00063     case KSpread_String:
00064         return i18n("A range of strings");
00065     case KSpread_Int:
00066         return i18n("A range of whole numbers (like 1, 132, 2344)");
00067     case KSpread_Boolean:
00068         return i18n("A range of truth values (TRUE or FALSE)" );
00069     case KSpread_Float:
00070         return i18n("A range of floating point values (like 1.3, 0.343, 253 )" );
00071     case KSpread_Any:
00072         return i18n("A range of any kind of values");
00073     }
00074     }
00075 
00076     return QString::null;
00077 }
00078 
00079 KSpreadFunctionParameter::KSpreadFunctionParameter()
00080 {
00081     m_type = KSpread_Float;
00082     m_range = FALSE;
00083 }
00084 
00085 KSpreadFunctionParameter::KSpreadFunctionParameter( const KSpreadFunctionParameter& param )
00086 {
00087     m_help = param.m_help;
00088     m_type = param.m_type;
00089     m_range = param.m_range;
00090 }
00091 
00092 KSpreadFunctionParameter::KSpreadFunctionParameter( const QDomElement& element )
00093 {
00094     m_type  = KSpread_Float;
00095     m_range = FALSE;
00096 
00097     QDomNode n = element.firstChild();
00098     for( ; !n.isNull(); n = n.nextSibling() )
00099     {
00100     if ( n.isElement() )
00101     {
00102         QDomElement e = n.toElement();
00103         if ( e.tagName() == "Comment" )
00104         m_help = i18n( e.text().utf8() );
00105         else if ( e.tagName() == "Type" )
00106         {
00107         m_type = toType( e.text() );
00108         if ( e.hasAttribute( "range" ))
00109         {
00110           if (e.attribute("range").lower() == "true")
00111             m_range = TRUE;
00112         }
00113         }
00114     }
00115     }
00116 }
00117 
00118 KSpreadFunctionDescription::KSpreadFunctionDescription()
00119 {
00120     m_type = KSpread_Float;
00121 }
00122 
00123 KSpreadFunctionDescription::KSpreadFunctionDescription( const QDomElement& element )
00124 {
00125     QDomNode n = element.firstChild();
00126     for( ; !n.isNull(); n = n.nextSibling() )
00127     {
00128     if ( n.isElement() )
00129     {
00130         QDomElement e = n.toElement();
00131         if ( e.tagName() == "Name" )
00132         m_name = e.text();
00133         else if ( e.tagName() == "Type" )
00134         {
00135         m_type = toType( e.text() );
00136         }
00137         else if ( e.tagName() == "Parameter" )
00138         {
00139         m_params.append( KSpreadFunctionParameter( e ) );
00140         }
00141         else if ( e.tagName() == "Help" )
00142         {
00143         QDomNode n2 = e.firstChild();
00144         for( ; !n2.isNull(); n2 = n2.nextSibling() )
00145         {
00146             if ( n2.isElement() )
00147             {
00148             QDomElement e2 = n2.toElement();
00149             if ( e2.tagName() == "Text" )
00150                 m_help.append ( i18n( e2.text().utf8() ) );
00151             else if ( e2.tagName() == "Syntax" )
00152                 m_syntax.append( i18n( e2.text().utf8() ) );
00153             else if ( e2.tagName() == "Example" )
00154                 m_examples.append( i18n( e2.text().utf8() ) );
00155             else if ( e2.tagName() == "Related" )
00156                 m_related.append( i18n( e2.text().utf8() ) );
00157             }
00158         }
00159         }
00160     }
00161     }
00162 }
00163 
00164 KSpreadFunctionDescription::KSpreadFunctionDescription( const KSpreadFunctionDescription& desc )
00165 {
00166     m_examples = desc.m_examples;
00167     m_related = desc.m_related;
00168     m_syntax = desc.m_syntax;
00169     m_help = desc.m_help;
00170     m_name = desc.m_name;
00171     m_type = desc.m_type;
00172 }
00173 
00174 QString KSpreadFunctionDescription::toQML() const
00175 {
00176     QString text( "<qt><h1>" );
00177     text += name();
00178     text += "</h1>";
00179 
00180     if( !m_help.isEmpty() )
00181     {
00182     text += i18n("<p>");
00183     QStringList::ConstIterator it = m_help.begin();
00184     for( ; it != m_help.end(); ++it )
00185     {
00186         text += *it;
00187         text += "<p>";
00188     }
00189     text += "</p>";
00190     }
00191 
00192     text += i18n("<p><b>Return type: </b>");
00193     text += toString( type() );
00194     text += "</p>";
00195 
00196     if ( !m_syntax.isEmpty() )
00197     {
00198     text += i18n("<h2>Syntax</h2><ul>");
00199     QStringList::ConstIterator it = m_syntax.begin();
00200     for( ; it != m_syntax.end(); ++it )
00201     {
00202         text += "<li>";
00203         text += *it;
00204     }
00205     text += "</ul>";
00206     }
00207 
00208     if ( !m_params.isEmpty() )
00209     {
00210     text += i18n("<h2>Parameters</h2><ul>");
00211     QValueList<KSpreadFunctionParameter>::ConstIterator it = m_params.begin();
00212     for( ; it != m_params.end(); ++it )
00213     {
00214         text += i18n("<li><b>Comment:</b> ");
00215         text += (*it).helpText();
00216         text += i18n("<br><b>Type:</b> ");
00217         text += toString( (*it).type(), (*it).hasRange() );
00218     }
00219     text += "</ul>";
00220     }
00221 
00222     if ( !m_examples.isEmpty() )
00223     {
00224     text += i18n("<h2>Examples</h2><ul>");
00225     QStringList::ConstIterator it = m_examples.begin();
00226     for( ; it != m_examples.end(); ++it )
00227     {
00228         text += "<li>";
00229         text += *it;
00230     }
00231     text += "</ul>";
00232     }
00233 
00234     if ( !m_related.isEmpty() )
00235     {
00236     text += i18n("<h2>Related Functions</h2><ul>");
00237     QStringList::ConstIterator it = m_related.begin();
00238     for( ; it != m_related.end(); ++it )
00239     {
00240         text += "<li>";
00241         text += "<a href=\"" + *it + "\">";
00242         text += *it;
00243         text += "</a>";
00244     }
00245     text += "</ul>";
00246     }
00247 
00248     text += "</qt>";
00249 
00250     return text;
00251 }
00252 
00253 static KStaticDeleter<KSpreadFunctionRepository> ksfr_sd;
00254 KSpreadFunctionRepository* KSpreadFunctionRepository::s_self = 0;
00255 
00256 KSpreadFunctionRepository* KSpreadFunctionRepository::self()
00257 {
00258     if( !s_self )
00259     {
00260         ksfr_sd.setObject( s_self, new KSpreadFunctionRepository() );
00261 
00262         // register all built-in functions
00263         KSpreadRegisterConversionFunctions();
00264         KSpreadRegisterDatabaseFunctions();
00265         KSpreadRegisterDateTimeFunctions();
00266         KSpreadRegisterEngineeringFunctions();
00267         KSpreadRegisterFinancialFunctions();
00268         KSpreadRegisterInformationFunctions();
00269         KSpreadRegisterLogicFunctions();
00270         KSpreadRegisterMathFunctions();
00271         KSpreadRegisterReferenceFunctions();
00272         KSpreadRegisterStatisticalFunctions();
00273         KSpreadRegisterTextFunctions();
00274         KSpreadRegisterTrigFunctions();
00275 
00276         // find all XML description files
00277         QStringList files =
00278            KSpreadFactory::global()->dirs()->findAllResources( "extensions", "*.xml", TRUE );
00279         for( QStringList::Iterator it = files.begin(); it != files.end(); ++it )
00280         s_self->loadFile( *it );
00281 
00282     }
00283     return s_self;
00284 }
00285 
00286 // class constructor
00287 KSpreadFunctionRepository::KSpreadFunctionRepository()
00288 {
00289     m_funcs.setAutoDelete( true );
00290     m_functions.setAutoDelete( true );
00291 }
00292 
00293 // loads functions description from XML file
00294 void KSpreadFunctionRepository::loadFile( const QString& filename )
00295 {
00296     QFile file( filename );
00297     if ( !file.open( IO_ReadOnly ) )
00298     return;
00299 
00300     QDomDocument doc;
00301     doc.setContent( &file );
00302     file.close();
00303 
00304     QString group = "";
00305 
00306     QDomNode n = doc.documentElement().firstChild();
00307     for( ; !n.isNull(); n = n.nextSibling() )
00308     {
00309     if ( n.isElement() )
00310     {
00311         QDomElement e = n.toElement();
00312         if ( e.tagName() == "Group" )
00313         {
00314         group = i18n( e.namedItem( "GroupName" ).toElement().text().utf8() );
00315         m_groups.append( group );
00316         m_groups.sort();
00317 
00318         QDomNode n2 = e.firstChild();
00319         for( ; !n2.isNull(); n2 = n2.nextSibling() )
00320         {
00321             if ( n2.isElement() )
00322             {
00323             QDomElement e2 = n2.toElement();
00324             if ( e2.tagName() == "Function" )
00325             {
00326                 KSpreadFunctionDescription* desc = new KSpreadFunctionDescription( e2 );
00327                 desc->setGroup( group );
00328                             if( m_functions.find( desc->name() ) )
00329                     m_funcs.insert( desc->name(), desc );
00330             }
00331             }
00332         }
00333 
00334         group = "";
00335         }
00336     }
00337     }
00338 }
00339 
00340 // returns description of specified function name
00341 KSpreadFunctionDescription* KSpreadFunctionRepository::functionInfo( const QString& name )
00342 {
00343     return m_funcs[ name ];
00344 }
00345 
00346 // returns function (KSpreadFunction) of specified function name
00347 KSpreadFunction* KSpreadFunctionRepository::function( const QString& name )
00348 {
00349     return m_functions[ name ];
00350 }
00351 
00352 // returns names of function in certain group
00353 QStringList KSpreadFunctionRepository::functionNames( const QString& group )
00354 {
00355     QStringList lst;
00356 
00357     QDictIterator<KSpreadFunctionDescription> it( m_funcs );
00358     for( ; it.current(); ++it )
00359     {
00360     if ( it.current()->group() == group )
00361         lst.append( it.current()->name() );
00362     }
00363 
00364     lst.sort();
00365 
00366     return lst;
00367 }
00368 
00369 // returns names of all available functions
00370 QStringList KSpreadFunctionRepository::functionNames()
00371 {
00372     QStringList lst;
00373 
00374     QDictIterator<KSpreadFunctionDescription> it( m_funcs );
00375     for( ; it.current(); ++it )
00376     {
00377     lst.append( it.current()->name() );
00378     }
00379 
00380     lst.sort();
00381 
00382     return lst;
00383 }
00384 
00385 // returns names of all registered functions (might be more)
00386 QStringList KSpreadFunctionRepository::regFunctionNames()
00387 {
00388     QStringList lst;
00389 
00390     QDictIterator<KSpreadFunction> it( m_functions );
00391     for( ; it.current(); ++it )
00392     {
00393     lst.append( it.current()->name );
00394     }
00395 
00396     lst.sort();
00397 
00398     return lst;
00399 }
00400 
00401 // registers a new function
00402 void KSpreadFunctionRepository::registerFunction( const QString& _name, KSpreadFunctionPtr _func )
00403 {
00404     QString name = _name.upper();
00405     KSpreadFunction* function;
00406 
00407     function = new KSpreadFunction();
00408     function->name = name;
00409     function->functionPtr  = _func;
00410 
00411     m_functions.replace( name, function );
00412 }
KDE Logo
This file is part of the documentation for kspread Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:43:09 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003