Source Code (Use browser search to find items of interest.)

Class Index

kspread'KSpreadInterpreter (./koffice/kspread/kspread_interpreter.h:14)

class KSpreadInterpreter : public KSInterpreter
{
public:
  typedef KSSharedPtr<KSpreadInterpreter> Ptr;

  KSpreadInterpreter( KSpreadDoc* );

  KSParseNode* parse( KSContext& context, KSpreadTable* table, const QString& formula, QList<KSpreadDepend>& );
  bool evaluate( KSContext& context, KSParseNode*, KSpreadTable* );

  KSNamespace* globalNamespace() { return m_global; }

  virtual bool processExtension( KSContext& context, KSParseNode* node );

  KSpreadDoc* document() { return m_doc; }
  KSpreadTable* table() { return m_table; }
    
private:
  KSpreadDoc* m_doc;
  KSpreadTable* m_table;
};

kspread'KSpreadInterpreter::KSpreadInterpreter() (./koffice/kspread/kspread_interpreter.cc:2007)

KSpreadInterpreter::KSpreadInterpreter( KSpreadDoc* doc ) : KSInterpreter()
{
  m_doc = doc;

  KSModule::Ptr m = kspreadCreateModule_KSpread( this );
  m_modules.insert( m->name(), m );

  // Integrate the KSpread module in the global namespace for convenience
  KSNamespace::Iterator it = m->nameSpace()->begin();
  KSNamespace::Iterator end = m->nameSpace()->end();
  for(; it != end; ++it )
    m_global->insert( it.key(), it.data() );
}


kspread'KSpreadInterpreter::processExtension() (./koffice/kspread/kspread_interpreter.cc:2021)

bool KSpreadInterpreter::processExtension( KSContext& context, KSParseNode* node )
{
  KSParseNodeExtra* extra = node->extra();
  if ( !extra )
  {
    if ( node->getType() == t_cell )
      extra = new KSParseNodeExtraPoint( node->getStringLiteral(), m_doc->map(), m_table );
    else if ( node->getType() == t_range )
      extra = new KSParseNodeExtraRange( node->getStringLiteral(), m_doc->map(), m_table );
    else
      return KSInterpreter::processExtension( context, node );
    node->setExtra( extra );
  }

  if ( node->getType() == t_cell )
  {
    KSParseNodeExtraPoint* p = (KSParseNodeExtraPoint*)extra;
    KSpreadPoint* point = p->point();

    if ( !point->isValid() )
    {
      QString tmp( i18n("The expression %1 is not valid") );
      tmp = tmp.arg( node->getStringLiteral() );
      context.setException( new KSException( "InvalidCellExpression", tmp ) );
      return false;
    }

    KSpreadCell* cell = point->cell();

    if ( cell->hasError() )
    {
      QString tmp( i18n("The cell %1 has an error:\n\n%2") );
      tmp = tmp.arg( util_cellName( cell->table(), cell->column(), cell->row() ) );
      tmp = tmp.arg( node->getStringLiteral() );
      context.setException( new KSException( "ErrorInCell", tmp ) );
      return false;
    }

    if ( cell->isDefault() )
      context.setValue( new KSValue( 0.0 ) );
    else if ( cell->isValue() )
      context.setValue( new KSValue( cell->valueDouble() ) );
    else if ( cell->isBool() )
      context.setValue( new KSValue( cell->valueBool() ) );
    else if ( cell->valueString().isEmpty() )
      context.setValue( new KSValue( 0.0 ) );
    else
      context.setValue( new KSValue( cell->valueString() ) );
    return true;
  }
  // Parse a range like "A1:B3"
  else if ( node->getType() == t_range )
  {
    KSParseNodeExtraRange* p = (KSParseNodeExtraRange*)extra;
    KSpreadRange* r = p->range();

    // Is it a valid range ?
    if ( !r->isValid() )
    {
      QString tmp( i18n("The expression %1 is not valid") );
      tmp = tmp.arg( node->getStringLiteral() );
      context.setException( new KSException( "InvalidRangeExpression", tmp ) );
      return false;
    }

    // The range is translated in a list or lists of integers
    KSValue* v = new KSValue( KSValue::ListType );
    for( int y = 0; y < r->range.height(); ++y )
    {
      KSValue* l = new KSValue( KSValue::ListType );

      for( int x = 0; x < r->range.width(); ++x )
      {
	KSValue* c;
	KSpreadCell* cell = r->table->cellAt( r->range.x() + x, r->range.y() + y );

	if ( cell->hasError() )
	{
	  QString tmp( i18n("The cell %1 has an error:\n\n%2") );
	  tmp = tmp.arg( util_cellName( cell->table(), cell->column(), cell->row() ) );
	  tmp = tmp.arg( node->getStringLiteral() );
	  context.setException( new KSException( "ErrorInCell", tmp ) );
	  return false;
	}

	if ( cell->isDefault() )
	  c = new KSValue( 0.0 );
	else if ( cell->isValue() )
	  c = new KSValue( cell->valueDouble() );
	else if ( cell->isBool() )
	  c = new KSValue( cell->valueBool() );
	else if ( cell->valueString().isEmpty() )
	  c = new KSValue( 0.0 );
	else
	  c = new KSValue( cell->valueString() );

	l->listValue().append( c );
      }
      v->listValue().append( l );
    }
    context.setValue( v );

    return true;
  }
  else
    ASSERT( 0 );

  // Never reached
  return false;
}


kspread'KSpreadInterpreter::parse() (./koffice/kspread/kspread_interpreter.cc:2132)

KSParseNode* KSpreadInterpreter::parse( KSContext& context, KSpreadTable* table, const QString& formula, QList<KSpreadDepend>& depends )
{
  // Create the parse tree.
  KSParser parser;
  if ( !parser.parse( formula, KSCRIPT_EXTENSION_KSPREAD ) )
  {
    context.setException( new KSException( "SyntaxError", parser.errorMessage() ) );
    return 0;
  }

  KSParseNode* n = parser.donateParseTree();
  makeDepends( context, n, table->map(), table, depends );

  return n;
}


kspread'KSpreadInterpreter::evaluate() (./koffice/kspread/kspread_interpreter.cc:2148)

bool KSpreadInterpreter::evaluate( KSContext& context, KSParseNode* node, KSpreadTable* table )
{
    // Save the current table to make this function reentrant.
    KSpreadTable* t = m_table;
    m_table = table;

    bool b = node->eval( context );

    m_table = t;

    return b;
}