excel/sidewinder/cell.cpp
1/* Swinder - Portable library for spreadsheet
2 Copyright (C) 2003 Ariya Hidayat <ariya@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA
18*/
19
20#include "cell.h"
21
22#include "ustring.h"
23#include "format.h"
24#include "value.h"
25
26#include <iostream>
27
28namespace Swinder
29{
30
31class CellPrivate
32{
33public:
34 Sheet* sheet;
35 unsigned column;
36 unsigned row;
37 UString formula;
38 Value value;
39 Format* format;
40 int formatIndex;
41 unsigned columnSpan;
42 unsigned rowSpan;
43
44 static UString columnNames[256];
45
46 CellPrivate(Sheet* s, unsigned column, unsigned row);
47 ~CellPrivate() { delete format; }
48};
49
50}
51
52using namespace Swinder;
53
54UString CellPrivate::columnNames[256];
55
56
57CellPrivate::CellPrivate(Sheet* s, unsigned c, unsigned r):
58sheet(s), column(c), row(r), format(0), formatIndex(-1), columnSpan(0), rowSpan(0)
59{
60}
61
62Cell::Cell( Sheet* sheet, unsigned column, unsigned row )
63{
64 d = new CellPrivate(sheet, column, row);
65}
66
67Cell::~Cell()
68{
69 delete d;
70}
71
72Sheet* Cell::sheet()
73{
74 return d->sheet;
75}
76
77unsigned Cell::column() const
78{
79 return d->column;
80}
81
82unsigned Cell::row() const
83{
84 return d->row;
85}
86
87UString Cell::name() const
88{
89 return name( column(), row() );
90}
91
92UString Cell::name( unsigned column, unsigned row )
93{
94 // column=0, row=0 is "A1"
95 return columnLabel( column ) + UString::number( row + 1 );
96}
97
98UString Cell::columnLabel() const
99{
100 return columnLabel( column() );
101}
102
103
104UString Cell::columnLabel( unsigned column )
105{
106 UString label;
107
108 // Excel has only up to 256 columns, so we cache those
109 if(column < 256 )
110 {
111 label = CellPrivate::columnNames[column];
112
113 // cache is not ready, so construct it first
114 if(label.isEmpty())
115 {
116 for(unsigned c = 0; c < 26; c++)
117 CellPrivate::columnNames[c] = UString(UChar((char)'A'+c));
118 for(unsigned d = 0; d < 256-26; d++)
119 {
120 char buf[3] = { (char)('A'+(d / 26)), (char)('A'+(d % 26)), 0};
121 CellPrivate::columnNames[d+26] = UString(buf);
122 }
123
124 label = CellPrivate::columnNames[column];
125 }
126 }
127 else
128 {
129 // otherwise, find with slower method
130
131 // how many characters for the column name?
132 unsigned digits = 1;
133 unsigned offset = 0;
134 for( unsigned limit = 26; column-offset >= limit; limit *= 26, digits++ )
135 offset += limit;
136
137 // extreme case e.g. column 4294967295 is "AATYHWUR" (8 characters)
138 if(digits < 9)
139 {
140 char ref[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
141
142 // from the last character
143 char* colp = ref + 9 - 1;
144 for( unsigned c = column - offset; digits; --digits, c/=26, colp-- )
145 *colp = char('A' + (c%26));
146
147 label = UString((const char*)(colp+1));
148 }
149 }
150
151 return label;
152}
153
154const Value& Cell::value() const
155{
156 return d->value;
157}
158
159void Cell::setValue( const Value& value )
160{
161 d->value = value;
162}
163
164const UString& Cell::formula() const
165{
166 return d->formula;
167}
168
169void Cell::setFormula( const UString& formula )
170{
171 d->formula = formula;
172}
173
174int Cell::formatIndex() const
175{
176 return d->formatIndex;
177}
178
179void Cell::setFormatIndex( int index )
180{
181 d->formatIndex = index;
182}
183
184Format Cell::format() const
185{
186 if(!d->format)
187 d->format = new Format();
188
189 return Format(*d->format);
190}
191
192void Cell::setFormat( const Format& format )
193{
194 if(!d->format)
195 d->format = new Format();
196
197 (*d->format) = format;
198}
199
200unsigned Cell::columnSpan() const
201{
202 return d->columnSpan;
203}
204
205void Cell::setColumnSpan( unsigned span )
206{
207 if( span < 1 ) return;
208 d->columnSpan = span;
209}
210
211unsigned Cell::rowSpan() const
212{
213 return d->rowSpan;
214}
215
216void Cell::setRowSpan( unsigned span )
217{
218 if( span < 1 ) return;
219 d->rowSpan = span;
220}
static UString number(int i)
Constructs a string from an int.
Provides a wrapper for cell value.
Definition value.h:43