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
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
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
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
00287 KSpreadFunctionRepository::KSpreadFunctionRepository()
00288 {
00289 m_funcs.setAutoDelete( true );
00290 m_functions.setAutoDelete( true );
00291 }
00292
00293
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
00341 KSpreadFunctionDescription* KSpreadFunctionRepository::functionInfo( const QString& name )
00342 {
00343 return m_funcs[ name ];
00344 }
00345
00346
00347 KSpreadFunction* KSpreadFunctionRepository::function( const QString& name )
00348 {
00349 return m_functions[ name ];
00350 }
00351
00352
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
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
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
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 }
This file is part of the documentation for kspread Library Version 1.4.2.