filters

cell.cpp

00001 /* Swinder - Portable library for spreadsheet 
00002    Copyright (C) 2003 Ariya Hidayat <ariya@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008    
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA
00018 */
00019 
00020 #include "cell.h"
00021 
00022 #include "ustring.h"
00023 #include "format.h"
00024 #include "value.h"
00025 
00026 #include <iostream>
00027 
00028 namespace Swinder
00029 {
00030 
00031 class CellPrivate
00032 {
00033 public:
00034   Sheet* sheet;
00035   unsigned column;  
00036   unsigned row;     
00037   UString formula;
00038   Value value;
00039   Format* format;
00040   int formatIndex;
00041   unsigned columnSpan;
00042   unsigned rowSpan;
00043 
00044   static UString columnNames[256];
00045 
00046   CellPrivate(Sheet* s, unsigned column, unsigned row);  
00047   ~CellPrivate() { delete format; }
00048 };
00049 
00050 }
00051 
00052 using namespace Swinder;
00053 
00054 UString CellPrivate::columnNames[256];
00055 
00056   
00057 CellPrivate::CellPrivate(Sheet* s, unsigned c, unsigned r):
00058 sheet(s), column(c), row(r), format(0), formatIndex(-1), columnSpan(0), rowSpan(0)
00059 {
00060 }
00061 
00062 Cell::Cell( Sheet* sheet, unsigned column, unsigned row )
00063 {
00064   d = new CellPrivate(sheet, column, row);
00065 }
00066 
00067 Cell::~Cell()
00068 {
00069   delete d;
00070 }
00071 
00072 Sheet* Cell::sheet()
00073 {
00074   return d->sheet;
00075 }
00076 
00077 unsigned Cell::column() const
00078 {
00079   return d->column;
00080 }
00081 
00082 unsigned Cell::row() const
00083 {
00084   return d->row;
00085 }
00086 
00087 UString Cell::name() const
00088 {
00089   return name( column(), row() ); 
00090 }
00091 
00092 UString Cell::name( unsigned column, unsigned row )
00093 {
00094     // column=0, row=0 is "A1"
00095   return columnLabel( column ) + UString::number( row + 1 );  
00096 }
00097 
00098 UString Cell::columnLabel() const
00099 {
00100   return columnLabel( column() );
00101 }
00102 
00103 
00104 UString Cell::columnLabel( unsigned column )
00105 {
00106   UString label;
00107   
00108   // Excel has only up to 256 columns, so we cache those
00109   if(column < 256 )
00110   {
00111     label = CellPrivate::columnNames[column];
00112 
00113     // cache is not ready, so construct it first
00114     if(label.isEmpty())
00115     {
00116       for(unsigned c = 0; c < 26; c++)
00117         CellPrivate::columnNames[c] = UString(UChar((char)'A'+c));
00118       for(unsigned d = 0; d < 256-26; d++)
00119       {
00120         char buf[3] = { 'A'+(d/26), 'A'+(d%26), 0};
00121         CellPrivate::columnNames[d+26] = UString(buf);
00122       }
00123       
00124       label = CellPrivate::columnNames[column];
00125     }
00126   }
00127   else
00128   {
00129     // otherwise, find with slower method
00130       
00131     // how many characters for the column name?  
00132     unsigned digits = 1;
00133     unsigned offset = 0;
00134     for( unsigned limit = 26; column-offset >= limit; limit *= 26, digits++ )
00135         offset += limit;
00136 
00137     // extreme case e.g. column 4294967295 is "AATYHWUR" (8 characters)
00138     if(digits < 9)
00139     {
00140       char ref[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00141       
00142       // from the last character
00143       char* colp = ref + 9 - 1;
00144       for( unsigned c = column - offset; digits; --digits, c/=26, colp-- )
00145         *colp = char('A' + (c%26));
00146       
00147       label = UString((const char*)(colp+1));
00148     }
00149   }
00150   
00151   return label;
00152 }
00153 
00154 const Value& Cell::value() const
00155 {
00156   return d->value;
00157 }
00158 
00159 void Cell::setValue( const Value& value )
00160 {
00161   d->value = value;
00162 }
00163 
00164 const UString& Cell::formula() const
00165 {
00166   return d->formula;
00167 }
00168 
00169 void Cell::setFormula( const UString& formula )
00170 {
00171   d->formula = formula;
00172 }
00173 
00174 int Cell::formatIndex() const
00175 {
00176   return d->formatIndex;
00177 }
00178 
00179 void Cell::setFormatIndex( int index )
00180 {
00181   d->formatIndex = index;
00182 }
00183 
00184 Format Cell::format() const
00185 {
00186   if(!d->format)
00187     d->format = new Format();
00188     
00189   return Format(*d->format);
00190 }
00191 
00192 void Cell::setFormat( const Format& format )
00193 {
00194   if(!d->format)
00195     d->format = new Format();
00196     
00197   (*d->format) = format;
00198 }
00199 
00200 unsigned Cell::columnSpan() const
00201 {
00202   return d->columnSpan;
00203 }
00204 
00205 void Cell::setColumnSpan( unsigned span )
00206 {
00207   if( span < 1 ) return;
00208   d->columnSpan = span;
00209 }
00210 
00211 unsigned Cell::rowSpan() const
00212 {
00213   return d->rowSpan;
00214 }
00215 
00216 void Cell::setRowSpan( unsigned span )
00217 {
00218   if( span < 1 ) return;
00219   d->rowSpan = span;
00220 }
KDE Home | KDE Accessibility Home | Description of Access Keys