Changeset 92ea4f2 in tol


Ignore:
Timestamp:
Mar 17, 2011, 7:51:04 PM (16 years ago)
Author:
Jorge Pérez <josp.jorge@…>
Branches:
1941-docker-image-to-test, devel, master
Children:
ca0fb9d
Parents:
f9cf245
Message:

By default the first sheet is active.

Excel.Destroy is renamed to Excel.Close

refs #884

  • When Excel.Open is invoked for an empty name "" then a new excel workbook is created in memory.
  • Excel.Save save to a file the current changes.
  • Excel.SaveAs save to another file.
  • Excel.WriteCell write a tol object to an excel cell.

fixes #1128

It is implemented a container keeping the handlers opened.

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@3330 be4846ae-f051-483a-831f-b64e7d08527f

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tol/contrib/excel/tolExcel.cpp

    rf9cf245 r92ea4f2  
    2727#include <win_tolinc.h>
    2828#endif
     29
     30#include <stdint.h>
    2931
    3032#include <tol/tol_tree.h>
    … …  
    3739#include <tol/tol_btsrgra.h>
    3840
     41#include <google/dense_hash_map>
     42#include <ext/hash_set>
     43
     44#ifdef __GNUC__
     45#define HASH __gnu_cxx::hash
     46#else
     47#define HASH ext::hash
     48#endif
     49
     50using google::dense_hash_map;
     51
     52class HandlerMap
     53{
     54public:
     55  typedef intptr_t handler_t;
     56  typedef dense_hash_map<handler_t, int, HASH<handler_t> > hash_t;
     57 
     58  HandlerMap()
     59  {
     60    this->m_hashHandlers.set_empty_key( 0 );
     61    this->m_hashHandlers.set_deleted_key( -1 );
     62  }
     63
     64  ~HandlerMap() {}
     65 
     66  handler_t insertHandler( handler_t h )
     67  {
     68    if ( h ) {
     69      this->m_hashHandlers[h] = 1;
     70    }
     71    return h;
     72  }
     73
     74  handler_t insertPointer( void* p )
     75  {
     76    if ( p ) {
     77      handler_t h = (handler_t)p;
     78      this->m_hashHandlers[h] = 1;
     79      return h;
     80    }
     81    return 0;
     82  }
     83
     84  bool removeHandler( handler_t p )
     85  {
     86    hash_t::iterator iter = this->m_hashHandlers.find( p );
     87    if ( iter == this->m_hashHandlers.end() ) {
     88      return false;
     89    } else {
     90      this->m_hashHandlers.erase( iter );
     91      return true;
     92    }
     93  }
     94 
     95  bool removePointer( void *p )
     96  {
     97    return this->removeHandler( (handler_t)p );
     98  }
     99
     100  bool isValidHandler( handler_t h )
     101  {
     102    return ( this->m_hashHandlers.find( h ) != this->m_hashHandlers.end() );
     103  }
     104 
     105  bool isValidPointer( void *p )
     106  {
     107    return this->isValidHandler( (handler_t)p );
     108  }
     109   
     110protected:
     111  hash_t m_hashHandlers;
     112};
     113
    39114class TolExcel {
    40115public:
    … …  
    43118  ~TolExcel();
    44119
     120  bool Save()
     121  {
     122    return m_ptrXLS ? m_ptrXLS->Save() : false;
     123  }
     124 
     125  bool SaveAs( const char*path )
     126  {
     127    return m_ptrXLS ? m_ptrXLS->SaveAs( path ) : false;
     128  }
     129 
    45130  bool IsValid()
    46131  {
    … …  
    76161  }
    77162 
     163  bool SetCellAnything( const BText &err_name,
     164                         size_t row, size_t col,
     165                         BSyntaxObject *value);
     166
    78167  BSyntaxObject *GetCellAnything( const BText &err_name,
    79168                                  size_t row, size_t col );
    … …  
    168257    return false;
    169258  }
    170  
    171   static double code_addr( TolExcel* ptr )
    172   {
    173     double addr = 0.0;
    174     *((TolExcel**)(&addr)) = ptr;
    175     return addr;
     259
     260  static HandlerMap::handler_t code_addr( TolExcel *ptr )
     261  {
     262    HandlerMap::handler_t h = TolExcel::HandlerPool.insertPointer( ptr );
     263    return h;
    176264  }
    177265 
    178266  static TolExcel* decode_addr( double addr )
    179267  {
    180     return *((TolExcel**)(&addr));
    181   }
    182 
     268    HandlerMap::handler_t h = addr;
     269    return ( TolExcel::HandlerPool.isValidHandler( h ) ) ? (TolExcel*)h : NULL;
     270  }
     271
     272  static void removePointer( TolExcel *ptr )
     273  {
     274    TolExcel::HandlerPool.removePointer( ptr );
     275  }
     276 
    183277  static double ExcelSerialDateToDMY( double SerialDate, int &nDay,
    184278                                      int &nMonth, int &nYear);
    … …  
    213307
    214308protected:
     309
     310  static HandlerMap HandlerPool; 
    215311
    216312  BasicExcelCell *GetCell( const BText &err_name,
    … …  
    252348  BasicExcelWorksheet *m_ptrActiveWS;
    253349};
     350
     351HandlerMap TolExcel::HandlerPool; 
    254352
    255353size_t TolExcel::decodeColumn( char * cellName, size_t length )
    … …  
    350448{
    351449  m_ptrXLS = new BasicExcel;
    352   m_ptrActiveWS = NULL;
     450  m_ptrActiveWS = m_ptrXLS->AddWorksheet( );
    353451  m_isOpen = false;
    354452}
    … …  
    365463    m_ptrXLS = NULL;
    366464  } else {
     465    m_ptrActiveWS = m_ptrXLS->GetWorksheet( 0 );
    367466  }
    368467  if ( m_ptrXLS ) {
    … …  
    384483  m_isOpen = false;
    385484  m_ptrXLS = NULL;
     485}
     486
     487bool TolExcel::SetCellAnything( const BText &err_name,
     488                                 size_t row, size_t col,
     489                                 BSyntaxObject *value)
     490{
     491  BasicExcelCell *cell = GetCell( err_name, row, col  );
     492  if ( !cell ) {
     493    return false;
     494  }
     495  if ( value->Grammar() == GraReal() ) {
     496    BDat &dat = Dat( value );
     497    cell->SetDouble( dat.Value() );
     498  } else if ( value->Grammar() == GraDate() ) {
     499    BDate &date = Date( value );
     500    int serialDate = TolExcel::DMYToExcelSerialDate( date.Day(),
     501                                                     date.Month(),
     502                                                     date.Year() );
     503    cell->SetDouble( double( serialDate ) );
     504  } else if ( value->Grammar() == GraText() ) {
     505    BText &txt = Text( value );
     506    cell->SetString( txt.Buffer() );
     507  } else {
     508    const BText &txt = value->Description();
     509    cell->SetString( (const_cast<BText&>(txt)).Buffer() );
     510  }
     511  return true;
    386512}
    387513
    … …  
    565691{
    566692  BText &path = Text( Arg( 1 ) );
    567   TolExcel *aux = new TolExcel( path.Buffer() );
     693  TolExcel *aux =
     694    path.Length() ? new TolExcel( path.Buffer() ) : new TolExcel();
    568695  if ( !aux->IsValid() ) {
    569696    delete aux;
    570697    aux = NULL;
    571698  }
    572   contens_ = BDat( TolExcel::code_addr( aux ) );
     699  HandlerMap::handler_t handler = TolExcel::code_addr( aux );
     700  if ( !handler ) {
     701    Error( BText( "Excel.Open: " ) +
     702           I2("could not create excel handler",
     703              "no se pudo crear el handler para excel") );
     704    delete aux;
     705  }
     706  // contens_ = BDat( TolExcel::code_addr( aux ) );
     707  contens_ = BDat( handler );
    573708}
    574709
    575710//---------------------------------------------------------------------------
    576 DeclareContensClass(BDat, BDatTemporary, BDatExcelDestroy);
    577 DefIntOpr(1, BDatExcelDestroy, "Excel.Destroy", 1, 1,
     711DeclareContensClass(BDat, BDatTemporary, BDatExcelClose);
     712DefIntOpr(1, BDatExcelClose, "Excel.Close", 1, 1,
    578713          "(Real ExcelHandler)",
    579           I2("Destroy a previously created excel handler. See also "
     714          I2("Close a previously created excel handler. See also "
    580715             "Excel.Open, Excel.Create",
    581716             ""),
    582717          BOperClassify::System_);
    583718//----------------------------------------------------------------------------
    584 void BDatExcelDestroy::CalcContens()
     719void BDatExcelClose::CalcContens()
    585720{
    586721  double addr = Dat( Arg( 1 ) ).Value();
    587722  TolExcel *aux = TolExcel::decode_addr( addr );
     723 
     724  if ( aux ) {
     725    TolExcel::removePointer( aux );
     726    delete aux;
     727    contens_ = BDat( 1.0 );
     728  } else {
     729    Error( BText( "Excel.Destroy: " ) +
     730           I2("invalid excel handler",
     731              "identificador de objeto excel invalido") );
     732    contens_ = BDat( 0.0 );
     733  }
     734}
     735
     736//---------------------------------------------------------------------------
     737DeclareContensClass(BDat, BDatTemporary, BDatExcelSave);
     738DefIntOpr(1, BDatExcelSave, "Excel.Save", 1, 1,
     739          "(Real ExcelHandler)",
     740          I2("Save changes to the current excel file. See also "
     741             "Excel.Open, Excel.Create, Excel.SaveAs",
     742             ""),
     743          BOperClassify::System_);
     744//----------------------------------------------------------------------------
     745void BDatExcelSave::CalcContens()
     746{
     747  double addr = Dat( Arg( 1 ) ).Value();
     748  TolExcel *xls = TolExcel::decode_addr( addr );
    588749  /* debemos tener un hash de las direccion creadas con Open de forma
    589750     tal que podamos verificar si la direccion es valida antes de
    590751     hacer delete */
    591   if ( aux ) {
    592     delete aux;
    593     contens_ = BDat( 1.0 );
    594   } else {
    595     Error( BText( "Excel.Destroy: " ) +
     752  if ( xls ) {
     753    contens_ = BDat( xls->Save() );
     754  } else {
     755    Error( BText( "Excel.Save: " ) +
     756           I2("invalid excel handler",
     757              "identificador de objeto excel invalido") );
     758    contens_ = BDat( 0.0 );
     759  }
     760}
     761
     762//---------------------------------------------------------------------------
     763DeclareContensClass(BDat, BDatTemporary, BDatExcelSaveAs);
     764DefExtOpr(1, BDatExcelSaveAs, "Excel.SaveAs", 2, 2,
     765          "Real Text",
     766          "(Real ExcelHandler, Text FileName)",
     767          I2("Save changes to another excel file. See also "
     768             "Excel.Open, Excel.Create, Excel.Save",
     769             ""),
     770          BOperClassify::System_);
     771//----------------------------------------------------------------------------
     772void BDatExcelSaveAs::CalcContens()
     773{
     774  double addr = Dat( Arg( 1 ) ).Value();
     775  TolExcel *xls = TolExcel::decode_addr( addr );
     776  /* debemos tener un hash de las direccion creadas con Open de forma
     777     tal que podamos verificar si la direccion es valida antes de
     778     hacer delete */
     779  if ( xls ) {
     780    BText &path = Text( Arg( 2 ) );
     781    contens_ = BDat( xls->SaveAs( path.Buffer() ) );
     782  } else {
     783    Error( BText( "Excel.SaveAs: " ) +
    596784           I2("invalid excel handler",
    597785              "identificador de objeto excel invalido") );
    … …  
    674862              "Excel.ActivateWS : indice de hoja invalido, debe ser conocido") );
    675863    contens_ = BDat( 0.0 );
     864  }
     865}
     866
     867//---------------------------------------------------------------------------
     868DeclareContensClass(BDat, BDatTemporary, BDatExcelWriteCell);
     869DefExtOpr(1, BDatExcelWriteCell, "Excel.WriteCell", 3, 3,
     870          "Real Anything Anything",
     871          "(Real ExcelHandler, Anything Cell, Anything Value)",
     872          I2("Write a TOL object into a given cell on the active sheet. The "
     873             "cell coordinates can be given as Text or Set. For instance you "
     874             "can use either \"A1\" or [[1,1]]. Objects distinct than Real "
     875             "Text or Date are only written as their description.\n"
     876             "It returns 1 if the TOL object value can be written correctly "
     877             "or 0 in other case.",
     878             "Escribe un objeto TOL en una celda de la hoja activa. Las "
     879             "coordenadas de la celda pueden especificarse como "
     880             "Text o Set. Por ejemplo se puede usar indistintamente "
     881             "\"A1\" o [[1,1]]. Los objetos distintos de Real, Text o Date se "
     882             "escriben segun su descripción\n"
     883             "Retorna 1 si el valor pudo escribirse correctamente o 0 en caso "
     884             "contrario."),
     885          BOperClassify::System_);
     886//----------------------------------------------------------------------------
     887void BDatExcelWriteCell::CalcContens()
     888{
     889  static BText _name_( "Excel.WriteCell" );
     890  double addr = Dat( Arg( 1 ) ).Value();
     891  size_t r, c;
     892 
     893  if ( TolExcel::getCellCoordinates( _name_, Arg(2), r, c ) ) {
     894    TolExcel *xls = TolExcel::decode_addr( addr );
     895    if ( xls ) {
     896      xls->SetCellAnything( _name_, r, c, Arg( 3 ) );
     897    } else {
     898      Error( _name_ +
     899             I2(": invalid excel handler",
     900                ": identificador de objeto excel invalido") );
     901      contens_ = BDat::Unknown( );
     902    }
     903  } else {
     904    contens_ = BDat::Unknown( );
    676905  }
    677906}
    … …  
    9911220static BSyntaxObject*
    9921221EvExcelReadCell( BGrammar* gra, const List* tre, BBool left )
    993 /*! Evaluate Copy expressions
     1222/*! Evaluate Exce.ReadCell expressions
    9941223*/
    9951224//--------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.