kspread Library API Documentation

kspread_functions_reference.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2002 The KSpread Team
00003                            www.koffice.org/kspread
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 // built-in reference functions
00022 
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <float.h>
00026 
00027 #include <kdebug.h>
00028 
00029 #include <koscript_parser.h>
00030 #include <koscript_util.h>
00031 #include <koscript_func.h>
00032 #include <koscript_synext.h>
00033 
00034 #include "kspread_doc.h"
00035 #include "kspread_functions.h"
00036 #include "kspread_interpreter.h"
00037 #include "kspread_sheet.h"
00038 #include "kspread_util.h"
00039 #include "kspread_value.h"
00040 
00041 // prototypes (sorted alphabetically)
00042 bool kspreadfunc_address( KSContext & context );
00043 bool kspreadfunc_areas( KSContext & context );
00044 bool kspreadfunc_choose( KSContext & context );
00045 bool kspreadfunc_column( KSContext & context );
00046 bool kspreadfunc_columns( KSContext & context );
00047 bool kspreadfunc_indirect( KSContext & context );
00048 bool kspreadfunc_lookup( KSContext & context );
00049 bool kspreadfunc_row( KSContext & context );
00050 bool kspreadfunc_rows( KSContext & context );
00051 
00052 // registers all reference functions
00053 void KSpreadRegisterReferenceFunctions()
00054 {
00055   KSpreadFunctionRepository * repo = KSpreadFunctionRepository::self();
00056   repo->registerFunction( "ADDRESS",  kspreadfunc_address );
00057   repo->registerFunction( "AREAS",    kspreadfunc_areas );
00058   repo->registerFunction( "CHOOSE",   kspreadfunc_choose );
00059   repo->registerFunction( "COLUMN",   kspreadfunc_column );
00060   repo->registerFunction( "COLUMNS",  kspreadfunc_columns );
00061   repo->registerFunction( "INDIRECT", kspreadfunc_indirect );
00062   repo->registerFunction( "LOOKUP",   kspreadfunc_lookup );
00063   repo->registerFunction( "ROW",      kspreadfunc_row );
00064   repo->registerFunction( "ROWS",     kspreadfunc_rows );
00065 }
00066 
00067 // Function: ADDRESS
00068 bool kspreadfunc_address( KSContext & context )
00069 {
00070   QValueList<KSValue::Ptr> & args = context.value()->listValue();
00071   bool r1c1 = false;
00072   QString sheetName;
00073   int absNum = 1;
00074 
00075   if ( !KSUtil::checkArgumentsCount( context, 5, "ADDRESS", false ) )
00076   {
00077     if ( !KSUtil::checkArgumentsCount( context, 4, "ADDRESS", false ) )
00078     {
00079       r1c1 = false;
00080 
00081       if ( !KSUtil::checkArgumentsCount( context, 3, "ADDRESS", false ) )
00082       {
00083         absNum = 1;
00084 
00085         if ( !KSUtil::checkArgumentsCount( context, 2, "ADDRESS", true ) )
00086           return false;
00087       }
00088       else
00089       {
00090         if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
00091           return false;
00092 
00093         absNum = args[2]->intValue();
00094       }
00095     }
00096     else
00097     {
00098       if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
00099         return false;
00100 
00101       if ( !KSUtil::checkType( context, args[3], KSValue::BoolType, true ) )
00102         return false;
00103 
00104       absNum = args[2]->intValue();
00105       r1c1   = !args[3]->boolValue();
00106     }
00107   }
00108   else
00109   {
00110     if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
00111       return false;
00112 
00113     if ( !KSUtil::checkType( context, args[3], KSValue::BoolType, true ) )
00114       return false;
00115 
00116     if ( !KSUtil::checkType( context, args[4], KSValue::StringType, true ) )
00117       return false;
00118 
00119     absNum    = args[2]->intValue();
00120     r1c1      = !args[3]->boolValue();
00121     sheetName = args[4]->stringValue();
00122   }
00123 
00124   if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00125     return false;
00126   if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00127     return false;
00128 
00129   QString result;
00130   int row = args[0]->intValue();
00131   int col = args[1]->intValue();
00132 
00133   if ( !sheetName.isEmpty() )
00134   {
00135     result += sheetName;
00136     result += "!";
00137   }
00138 
00139   if ( r1c1 )
00140   {
00141     // row first
00142     bool abs = false;
00143     if ( absNum == 1 || absNum == 2 )
00144       abs = true;
00145 
00146     result += 'R';
00147     if ( !abs )
00148       result += '[';
00149     result += QString::number( row );
00150 
00151     if ( !abs )
00152       result += ']';
00153 
00154     // column
00155     abs = false;
00156     if ( absNum == 1 || absNum == 3 )
00157       abs = true;
00158 
00159     result += 'C';
00160     if ( !abs )
00161       result += '[';
00162     result += QString::number( col );
00163 
00164     if ( !abs )
00165       result += ']';
00166   }
00167   else
00168   {
00169     bool abs = false;
00170     if ( absNum == 1 || absNum == 3 )
00171       abs = true;
00172 
00173     if ( abs )
00174       result += '$';
00175 
00176     result += KSpreadCell::columnName( col );
00177 
00178     abs = false;
00179     if ( absNum == 1 || absNum == 2 )
00180       abs = true;
00181 
00182     if ( abs )
00183       result += '$';
00184 
00185     result += QString::number( row );
00186   }
00187 
00188   context.setValue( new KSValue( result ) );
00189 
00190   return true;
00191 }
00192 
00193 bool checkRef( QString const & ref )
00194 {
00195   KSpreadRange r( ref );
00196   if ( !r.isValid() )
00197   {
00198     KSpreadPoint p( ref );
00199     if ( !p.isValid() )
00200       return false;
00201   }
00202   return true;
00203 }
00204 
00205 // Function: AREAS
00206 bool kspreadfunc_areas( KSContext & context )
00207 {
00208   QValueList<KSValue::Ptr> & args  = context.value()->listValue();
00209   QValueList<KSValue::Ptr> & extra = context.extraData()->listValue();
00210 
00211   if ( extra.count() > 0 )
00212   {
00213     context.setValue( new KSValue( (int) extra.count() ) );
00214     return true;
00215   }
00216 
00217   if ( !KSUtil::checkArgumentsCount( context, 1, "AREAS", true ) )
00218     return false;
00219 
00220   QString s = args[0]->stringValue();
00221   if ( s[0] != '(' || s[s.length() - 1] != ')' )
00222     return false;
00223 
00224   int l = s.length();
00225 
00226   int num = 0;
00227   QString ref;
00228   for ( int i = 1; i < l; ++i )
00229   {
00230     if ( s[i] == ',' || s[i] == ')' )
00231     {
00232       if ( !checkRef( ref ) )
00233         return false;
00234       else
00235       {
00236         ++num;
00237         ref = "";
00238       }
00239     }
00240     else
00241       ref += s[i];
00242   }
00243 
00244   context.setValue( new KSValue( num ) );
00245   return true;
00246 }
00247 
00248 // Function: CHOOSE
00249 bool kspreadfunc_choose( KSContext & context )
00250 {
00251   QValueList<KSValue::Ptr> & args = context.value()->listValue();
00252 
00253   QValueList<KSValue::Ptr>::Iterator it  = args.begin();
00254   QValueList<KSValue::Ptr>::Iterator end = args.end();
00255 
00256   int index = -1;
00257   int count = 0;
00258 
00259   for( ; it != end; ++it )
00260   {
00261     if ( index == -1 )
00262     {
00263       if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00264         return false;
00265 
00266       index = args[0]->intValue();
00267 
00268       if ( index < 1 )
00269         return false;
00270     }
00271     else
00272     {
00273       if ( KSUtil::checkType( context, *it, KSValue::ListType, true ) )
00274       {
00275         QValueList<KSValue::Ptr> list( (*it)->listValue() );
00276 
00277         QValueList<KSValue::Ptr>::Iterator listIter = list.begin();
00278         QValueList<KSValue::Ptr>::Iterator listEnd  = list.end();
00279 
00280         if ( KSUtil::checkType( context, *listIter, KSValue::ListType, true ) )
00281         {
00282           list = (*listIter)->listValue();
00283 
00284           listIter = list.begin();
00285           listEnd  = list.end();
00286         }
00287 
00288         while ( listIter != listEnd )
00289         {
00290           if ( count == index )
00291           {
00292             if ( KSUtil::checkType( context, *listIter, KSValue::StringType, true ) )
00293               context.setValue( new KSValue( (*listIter)->stringValue()  ) );
00294             else if ( KSUtil::checkType( context, *listIter, KSValue::DoubleType, true ) )
00295               context.setValue( new KSValue( (*listIter)->doubleValue()  ) );
00296             else if ( KSUtil::checkType( context, *listIter, KSValue::BoolType, true ) )
00297               context.setValue( new KSValue( (*listIter)->boolValue()  ) );
00298             else if ( KSUtil::checkType( context, *listIter, KSValue::IntType, true ) )
00299               context.setValue( new KSValue( (*listIter)->intValue()  ) );
00300             else if ( KSUtil::checkType( context, *listIter, KSValue::DateType, true ) )
00301               context.setValue( new KSValue( (*listIter)->dateValue()  ) );
00302             else if ( KSUtil::checkType( context, *listIter, KSValue::TimeType, true ) )
00303               context.setValue( new KSValue( (*listIter)->timeValue()  ) );
00304             else
00305             {
00306               kdDebug() << "Unkown type" << endl;
00307               return false;
00308             }
00309 
00310             return true;
00311           }
00312           ++count;
00313           ++listIter;
00314         }
00315       }
00316       else if ( count == index )
00317       {
00318         if ( KSUtil::checkType( context, *it, KSValue::StringType, true ) )
00319           context.setValue( new KSValue( (*it)->stringValue()  ) );
00320         else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00321           context.setValue( new KSValue( (*it)->doubleValue()  ) );
00322         else if ( KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00323           context.setValue( new KSValue( (*it)->boolValue()  ) );
00324         else if ( KSUtil::checkType( context, *it, KSValue::IntType, true ) )
00325           context.setValue( new KSValue( (*it)->intValue()  ) );
00326         else if ( KSUtil::checkType( context, *it, KSValue::DateType, true ) )
00327           context.setValue( new KSValue( (*it)->dateValue()  ) );
00328         else if ( KSUtil::checkType( context, *it, KSValue::TimeType, true ) )
00329           context.setValue( new KSValue( (*it)->timeValue()  ) );
00330         else
00331           return false;
00332         return true;
00333       }
00334     }
00335     ++count;
00336   }
00337 
00338   return false;
00339 }
00340 
00341 // Function: COLUMN
00342 bool kspreadfunc_column( KSContext & context )
00343 {
00344   QValueList<KSValue::Ptr> & extra = context.extraData()->listValue();
00345 
00346   KSpreadCell *  cell  = ((KSpreadInterpreter *) context.interpreter() )->cell();
00347 
00348   if ( !KSUtil::checkArgumentsCount( context, 1, "COLUMN", false ) )
00349   {
00350     if ( cell )
00351     {
00352       context.setValue( new KSValue( (int) cell->column() ) );
00353       return true;
00354     }
00355     else
00356       return false;
00357   }
00358   else
00359   {
00360     if ( extra.count() > 0 )
00361     {
00362       QString s( extra[0]->stringValue() );
00363 
00364       KSpreadRange ra( s );
00365       if ( ra.range.left() <= 0 || ra.range.right() <= 0 )
00366       {
00367         KSpreadPoint p( s );
00368         if ( p.pos.x() <= 0 || p.pos.y() <= 0 )
00369           return false;
00370 
00371         context.setValue( new KSValue( p.pos.x() ) );
00372         return true;
00373       }
00374       else //if ( ra.range.width() <= 1 )
00375       {
00376         context.setValue( new KSValue( ra.range.left() ) );
00377         return true;
00378       }
00379       /*
00380       else
00381       {
00382         QString result( "{" );
00383         int r = ra.range.right();
00384         for ( int i = ra.range.left(); i <= r; ++i )
00385         {
00386           if ( result.length() > 1 )
00387             result += ", ";
00388           result += QString::number( i );
00389         }
00390         result += "}";
00391 
00392         context.setValue( new KSValue( result ) );
00393         return true;
00394       }
00395       */
00396     }
00397   }
00398 
00399   return false;
00400 }
00401 
00402 // Function: COLUMNS
00403 bool kspreadfunc_columns( KSContext & context )
00404 {
00405   QValueList<KSValue::Ptr> & args = context.value()->listValue();
00406   QValueList<KSValue::Ptr> & extra = context.extraData()->listValue();
00407 
00408   if ( !KSUtil::checkArgumentsCount( context, 1, "COLUMNS", true ) )
00409     return false;
00410 
00411   if ( extra.count() > 0 )
00412   {
00413     QString s( extra[0]->stringValue() );
00414 
00415     KSpreadRange r( s );
00416     if ( r.range.left() <= 0 || r.range.right() <= 0 )
00417     {
00418       KSpreadPoint p( s );
00419       if ( p.pos.x() <= 0 || p.pos.y() <= 0 )
00420         return false;
00421 
00422       context.setValue( new KSValue( (int) 1 ) );
00423       return true;
00424     }
00425 
00426     context.setValue( new KSValue( r.range.width() ) );
00427     return true;
00428   }
00429   return false;
00430   if ( args.count() > 0 )
00431   {
00432     if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
00433       return false;
00434 
00435     QString s( args[0]->stringValue() );
00436 
00437     int l = s.length();
00438     int n = s.find( '[' );
00439     if ( n == -1 )
00440       return false;
00441     int n2 = s.find( '[', n + 1 );
00442     if ( n2 != -1 )
00443       n = n2;
00444     int count = 0;
00445     for ( int i = n; i < l; ++i )
00446     {
00447       if ( s[i] == ',' )
00448         ++count;
00449       else if ( s[i] == ']' )
00450       {
00451         ++count;
00452         break;
00453       }
00454     }
00455 
00456     context.setValue( new KSValue( count ) );
00457     return true;
00458   }
00459 
00460   return false;
00461 }
00462 
00463 
00464 // Function: INDIRECT
00465 bool kspreadfunc_indirect( KSContext & context )
00466 {
00467   QValueList<KSValue::Ptr> & args  = context.value()->listValue();
00468   QValueList<KSValue::Ptr> & extra = context.extraData()->listValue();
00469 
00470   if ( !KSUtil::checkArgumentsCount( context, 1, "INDIRECT", true ) )
00471     return false;
00472 
00473   bool r1c1 = false;
00474   if ( !KSUtil::checkArgumentsCount( context, 2, "INDIRECT", false ) )
00475     r1c1 = false;
00476   else
00477   {
00478     if ( !KSUtil::checkType( context, args[1], KSValue::BoolType, true ) )
00479       return false;
00480 
00481     r1c1 = !args[1]->boolValue();
00482   }
00483 
00484   QString ref;
00485 
00486   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
00487   {
00488     if ( !KSUtil::checkType( context, extra[0], KSValue::StringType, true ) )
00489       return false;
00490     ref = extra[0]->stringValue();
00491   }
00492   else
00493     ref = args[0]->stringValue();
00494 
00495   if ( ref.isEmpty() )
00496     return false;
00497 
00498   if ( r1c1 )
00499   {
00500     // TODO: translate the r1c1 style to a1 style
00501     ref = ref;
00502   }
00503 
00504   KSpreadMap *   map   = ((KSpreadInterpreter *) context.interpreter() )->document()->map();
00505   KSpreadSheet * sheet = ((KSpreadInterpreter *) context.interpreter() )->sheet();
00506 
00507   KSpreadPoint p( ref, map, sheet );
00508 
00509   if ( !p.isValid() )
00510     return false;
00511 
00512   KSpreadCell * cell = p.cell();
00513   if ( cell )
00514   {
00515     if ( cell->value().isString() )
00516       context.setValue( new KSValue( cell->value().asString() ) );
00517     else if ( cell->value().isNumber() )
00518       context.setValue( new KSValue( cell->value().asFloat() ) );
00519     else if ( cell->value().isBoolean() )
00520       context.setValue( new KSValue( cell->value().asBoolean() ) );
00521     else if ( cell->isDate() )
00522       context.setValue( new KSValue( cell->value().asDate() ) );
00523     else if ( cell->isTime() )
00524       context.setValue( new KSValue( cell->value().asTime() ) );
00525     else if ( cell->value().isEmpty() || cell->isEmpty() || cell->isDefault() )
00526       context.setValue( new KSValue( (int) 0 ) );
00527     else
00528       context.setValue( new KSValue( cell->strOutText() ) );
00529 
00530     return true;
00531   }
00532 
00533   return false;
00534 }
00535 
00536 static bool isEqualLess( KSContext & context, KSpreadValue::Type type, KSValue::Ptr const & value,
00537                          double dValue, QString const & sValue, bool bValue )
00538 {
00539   if ( ( type == KSpreadValue::Float )
00540        && ( KSUtil::checkType( context, value, KSValue::DoubleType, true ) ) )
00541   {
00542     if ( dValue <= value->doubleValue() )
00543       return true;
00544 
00545     return false;
00546   }
00547 
00548   else if ( type == KSpreadValue::Integer || type == KSpreadValue::Float )
00549     return true;
00550 
00551   else if ( ( type == KSpreadValue::String )
00552             && ( KSUtil::checkType( context, value, KSValue::StringType, true ) ) )
00553   {
00554     if ( sValue.lower() <= value->stringValue().lower() )
00555       return true;
00556 
00557     return false;
00558   }
00559 
00560   else if ( type == KSpreadValue::String )
00561     return true;
00562 
00563   else if ( ( type == KSpreadValue::Boolean )
00564             && ( KSUtil::checkType( context, value, KSValue::BoolType, true ) ) )
00565   {
00566     if ( (int) bValue <= (int) value->boolValue() )
00567       return true;
00568   }
00569 
00570   return false;
00571 }
00572 
00573 bool kspreadfunc_lookup( KSContext & context )
00574 {
00575   /* As soon as it works correctly: here is the doc
00576     <Function>
00577       <Name>LOOKUP</Name>
00578       <Parameter>
00579         <Comment>Lookup Value</Comment>
00580         <Type>String/Numeric</Type>
00581       </Parameter>
00582       <Parameter>
00583         <Comment>Lookup Vector</Comment>
00584         <Type>String/Numeric</Type>
00585       </Parameter>
00586       <Parameter>
00587         <Comment>Result Vector</Comment>
00588         <Type>String/Numeric</Type>
00589       </Parameter>
00590       <Help>
00591     <Text>The LOOKUP function looks up the first parameter in the lookup vector. It returns a value in the result Vector with the same index as the matching value in the lookup vector. If value is not in the lookup vector it takes the next lower one. If no value in the lookup vector matches an error is returned. The lookup vector must be in ascending order and lookup and result vector must have the same size. Numeric values, string and boolean values are recognized. Comparison between strings is case-insensitive.</Text>
00592     <Syntax>LOOKUP(value, lookup vector, result vector)</Syntax>
00593     <Example>LOOKUP(1.232; A1:A6; B1:B6) for A1 = 1, A2 = 2 returns the value of B1.</Example>
00594       </Help>
00595     </Function>
00596 */
00597   QValueList<KSValue::Ptr> & args  = context.value()->listValue();
00598 
00599   if ( !KSUtil::checkArgumentsCount( context, 3, "LOOKUP", true ) )
00600     return false;
00601 
00602   KSpreadValue::Type type;
00603 
00604   if ( KSUtil::checkType( context, args[0], KSValue::BoolType, true ) )
00605     type = KSpreadValue::Boolean;
00606   else if ( KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00607     type = KSpreadValue::Float;
00608   else
00609     return false;
00610 
00611   int index = -1;
00612 
00613   double dValue = 0.0;
00614   QString sValue;
00615   bool bValue = false;
00616 
00617   if ( type == KSpreadValue::Float || type == KSpreadValue::Integer )
00618     dValue = args[0]->doubleValue();
00619   if ( type == KSpreadValue::String )
00620     sValue = args[0]->stringValue();
00621   if ( type == KSpreadValue::Boolean )
00622     bValue = args[0]->boolValue();
00623 
00624   // single value / no list
00625   if ( !KSUtil::checkType( context, args[1], KSValue::ListType, true ) )
00626   {
00627     if ( KSUtil::checkType( context, args[2], KSValue::ListType, true ) )
00628       return false;
00629 
00630     if ( ( type == KSpreadValue::Float || type == KSpreadValue::Integer )
00631          && ( KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) ) )
00632     {
00633       if ( dValue <= args[1]->doubleValue() )
00634       {
00635         context.setValue( new KSValue( args[2] ) );
00636         return true;
00637       }
00638       return false;
00639     }
00640     else
00641     if ( type == KSpreadValue::Float || type == KSpreadValue::Integer )
00642     {
00643       context.setValue( new KSValue( args[2] ) );
00644       return true;
00645     }
00646     else if ( ( type == KSpreadValue::String )
00647               && ( KSUtil::checkType( context, args[1], KSValue::StringType, true ) ) )
00648     {
00649       if ( sValue.lower() <= args[1]->stringValue().lower() )
00650       {
00651         context.setValue( new KSValue( args[2] ) );
00652         return true;
00653       }
00654       return false;
00655     }
00656     else if ( type == KSpreadValue::String )
00657     {
00658       context.setValue( new KSValue( args[2] ) );
00659       return true;
00660     }
00661     else if ( ( type == KSpreadValue::Boolean )
00662               && ( KSUtil::checkType( context, args[1], KSValue::BoolType, true ) ) )
00663     {
00664       if ( bValue <= args[1]->boolValue() )
00665       {
00666         context.setValue( new KSValue( args[2] ) );
00667         return true;
00668       }
00669     }
00670 
00671     return false;
00672   }
00673 
00674   QValueList<KSValue::Ptr> lookup( args[1]->listValue() );
00675   QValueList<KSValue::Ptr> & result = args[2]->listValue();
00676 
00677   if ( lookup.count() != result.count() )
00678     return false;
00679 
00680   index = -1;
00681   int l = lookup.count();
00682   for ( int i = 0; i < l; ++i ) // ( ; it != end; ++it )
00683   {
00684     if ( KSUtil::checkType( context, lookup[i], KSValue::DoubleType, true ) )
00685       kdDebug() << "Double" << endl;
00686     if ( KSUtil::checkType( context, lookup[i], KSValue::ListType, true ) )
00687       kdDebug() << "List" << endl;
00688     if ( KSUtil::checkType( context, lookup[i], KSValue::IntType, true ) )
00689       kdDebug() << "Int" << endl;
00690     if ( KSUtil::checkType( context, lookup[i], KSValue::StringType, true ) )
00691       kdDebug() << "String" << endl;
00692     kdDebug() << "index: " << index << ", " << dValue << endl;
00693     if ( !isEqualLess( context, type, lookup[i], dValue, sValue, bValue ) )
00694     {
00695       if ( index < 0 )
00696         return false;
00697       context.setValue( new KSValue( result[index] ) );
00698       return true;
00699     }
00700 
00701     ++index;
00702   }
00703 
00704   return false;
00705 }
00706 
00707 // Function: ROW
00708 bool kspreadfunc_row( KSContext & context )
00709 {
00710   QValueList<KSValue::Ptr> & extra = context.extraData()->listValue();
00711 
00712   KSpreadCell *  cell  = ((KSpreadInterpreter *) context.interpreter() )->cell();
00713 
00714   if ( !KSUtil::checkArgumentsCount( context, 1, "ROW", false ) )
00715   {
00716     if ( cell )
00717     {
00718       context.setValue( new KSValue( (int) cell->row() ) );
00719       return true;
00720     }
00721     else
00722       return false;
00723   }
00724   else
00725   {
00726     if ( extra.count() > 0 )
00727     {
00728       QString s( extra[0]->stringValue() );
00729 
00730       KSpreadRange r( s );
00731       if ( r.range.left() <= 0 || r.range.right() <= 0 )
00732       {
00733         KSpreadPoint p( s );
00734         if ( p.pos.y() <= 0 || p.pos.x() <= 0 )
00735           return false;
00736 
00737         context.setValue( new KSValue( p.pos.y() ) );
00738         return true;
00739       }
00740       else
00741       {
00742         /*
00743         QString result( "{" );
00744         int b = r.range.bottom();
00745         for ( int i = r.range.top(); i < b; ++i )
00746         {
00747           if ( result.length() > 1 )
00748             result += ", ";
00749           result += QString::number( i );
00750         }
00751         result += "}";
00752         */
00753         context.setValue( new KSValue( r.range.top() ) );
00754         return true;
00755       }
00756 
00757     }
00758   }
00759 
00760   return false;
00761 }
00762 
00763 // Function: ROWS
00764 bool kspreadfunc_rows( KSContext & context )
00765 {
00766   QValueList<KSValue::Ptr> & args = context.value()->listValue();
00767   QValueList<KSValue::Ptr> & extra = context.extraData()->listValue();
00768 
00769   if ( !KSUtil::checkArgumentsCount( context, 1, "ROWS", true ) )
00770     return false;
00771 
00772   if ( extra.count() > 0 )
00773   {
00774     QString s( extra[0]->stringValue() );
00775     KSpreadRange r( s );
00776     if ( r.range.left() <= 0 || r.range.right() <= 0 )
00777     {
00778       KSpreadPoint p( s );
00779       if ( p.pos.y() <= 0 || p.pos.x() <= 0 )
00780         return false;
00781 
00782       context.setValue( new KSValue( (int) 1 ) );
00783       return true;
00784     }
00785 
00786     context.setValue( new KSValue( r.range.height() ) );
00787     return true;
00788   }
00789   else if ( args.count() > 0 )
00790   {
00791     if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
00792       return false;
00793 
00794     QString s( args[0]->stringValue() );
00795     int l = s.length();
00796     int n = s.find( '[' );
00797     if ( n == -1 )
00798       return false;
00799     int n2 = s.find( '[', n + 1 );
00800     if ( n2 != -1 )
00801       n = n2;
00802     int count = 0;
00803     for ( int i = n; i < l; ++i )
00804     {
00805       if ( s[i] == '[' )
00806         ++count;
00807     }
00808 
00809     context.setValue( new KSValue( count ) );
00810     return true;
00811   }
00812 
00813   return false;
00814 }
00815 
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:11 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003