summaryrefslogtreecommitdiffstats
path: root/kspread/kspread_util.h
blob: ad5227f8be033f0cde00a8f7abbd733ff282ac7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
/* This file is part of the KDE project
   Copyright (C) 2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
   Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#ifndef __kspread_util_h__
#define __kspread_util_h__

#include <tqstring.h>
#include <tqrect.h>
#include <tqdatetime.h>

#include <koffice_export.h>

#include "kspread_global.h"
#include "kspread_value.h"

class TQFont;
class TQPen;
class TQDomElement;
class TQDomDocument;

class TDELocale;

bool util_isPointValid(TQPoint point);
bool util_isRectValid(TQRect rect);

namespace KSpread
{
class Cell;
class Map;
class Sheet;

/**
* Represents the position of a single cell in a workbook.  Each position has a row, column and optionally an associated Sheet.
* Columns and rows can be marked as fixed.  This is for handling absolute coordinates in formulae (eg. in the
* formula "=$C$1" both the column (C) and row (1) are fixed.
*/
class KSPREAD_EXPORT Point
{
public:
  Point() { _pos.setX( -1 ); _sheet = 0; _columnFixed = false; _rowFixed = false; }
  Point( const TQString& );
  Point( const TQString&, Map*, Sheet* default_sheet = 0 );
  Point( const Point& c ) {
    _pos = c._pos;
    _sheet = c._sheet;
    _sheetName = c._sheetName;
    _columnFixed = c._columnFixed;
    _rowFixed = c._rowFixed;
  }

  bool isValid() const { return ( util_isPointValid(pos()) && ( _sheet != 0 || _sheetName.isEmpty() ) ); }
  bool isSheetKnown() const { return ( ! _sheetName.isEmpty() && _sheet != 0 ); }

  Cell* cell() const;

  bool operator== (const Point &cell) const;
  bool operator< (const Point &cell) const;

  int row () const { return _pos.y(); };
  int column () const { return _pos.x(); };
  void setRow (int r) { _pos.setY (r); };
  void setColumn (int c) { _pos.setX (c); };

  /**
  * Sets the sheet which this point lies on.
  */
  void      setSheet(Sheet* sheet);
  Sheet*    sheet() const;

  /**
  * Sets the name of the sheet which this point lies on.
  */
  void      setSheetName(TQString name);
  TQString   sheetName() const;

  /**
  * Sets the position of this point (in rows and columns)
  */
  void      setPos(TQPoint pos);
  TQPoint    pos() const;

  /**
  * Sets whether or not the column (x coordinate) of this point is fixed (ie. it represents an absolute
  * coordinate - eg. the column letter B in the formula "=$B30" is fixed)
  */
  void      setColumnFixed(bool colFixed);
  bool      columnFixed() const;

  /**
  * Sets whether or not the row (y coordinate) of this point is fixed (ie. it represents an absolute coordinate - eg. the row number 30 in the formula "=A$30" is fixed)
  */
  void      setRowFixed(bool rowFixed);
  bool      rowFixed() const;


private:
  Sheet* _sheet;
  TQString _sheetName;
  TQPoint _pos;
  bool _columnFixed;
  bool _rowFixed;

private:
  void init( const TQString& );
};

/**
* Represents a region within a workbook.  The region has an area (the columns and rows that it includes) and
* optionally an associated @ref KSpread::Sheet
* A range is defined by four coordinates: Its left column, top row, right column and bottom row.  Each
* of these coordinates may be set as fixed, to represent absolute coordinates in formulae.
*/
class KSPREAD_EXPORT Range
{
public:
  Range();

  Range( const TQString& );
  Range( const TQString&, Map*, Sheet* default_sheet = 0 );
  Range( const Range& r );
  Range( const Point& ul, const Point& lr );

  /**
  * Returns true if this Range represents a valid region of a spreadsheet.
  * A range is valid if:
  * - It has an associated Sheet
  * - The area is non-negative (ie.
  * - The left-most column is non-negative
  * - The top-most row is non-negative
  */
  bool isValid() const;

  /** Returns true if this range has an associated Sheet or false otherwise */
  bool isSheetKnown() const { return ( !sheetName().isEmpty() && sheet() != 0 ); }

  /** Fills a Point with info (row,column,sheet) about the first point in the range */
  void getStartPoint(Point* pt);
  /** Fills a Point with info (row,column,sheet) about the last point the range */
  void getEndPoint(Point* pt);

  int startRow () const { return range().top(); };
  int startCol () const { return range().left(); };
  int endRow () const { return range().bottom(); };
  int endCol () const { return range().right(); };

  /**
  * Changes the area on the spreadsheet represented by this range
  * @param newRange The new area for this range.
  */
  virtual void setRange(const TQRect& newRange) {_range=newRange;}

  void setRange(int newStartCol, int newStartRow, int newEndCol, int newEndRow)
  { _range=TQRect(newStartCol,newStartRow,newEndCol-newStartCol,newEndRow-newStartRow); }

  /** Returns the area on the spreadsheet occupied by this range. */
  TQRect range() const;

  /** Returns true if this range includes the specified cell */
  bool contains (const Point &cell) const;
  /**
  * Returns true if this range intersects Range @p r  (ie. there is at least one cell
  * which is common to both Ranges )
  */
  bool intersects (const Range &r) const;

  /**
  * Returns a string representation of this range as it would appear in a formula.
  * ie. In the format " SheetName! [StartCell] : [EndCell] "
  * The string representation uses $ characters to mark fixed parts of the range, eg. Sheet1!$A1:$A20
  */
  TQString toString() const;

  /** Sets whether or not the left column is fixed . */
  void setLeftFixed(bool fixed);
  bool leftFixed() const;

  /** Sets whether or not the right column is fixed. */
  void setRightFixed(bool fixed);
  bool rightFixed() const;

  /** Sets whether or not the top row is fixed. */
  void setTopFixed(bool fixed);
  bool topFixed() const;

  /** Sets whether or not the bottom row is fixed. */
  void setBottomFixed(bool fixed);
  bool bottomFixed() const;

  /** Sets the Sheet object associated with this range.  The range can only span a single sheet. */
  void setSheet(Sheet* sheet);
  Sheet* sheet() const;

  /** Sets the name of the sheet associated with this range. */
  void setSheetName(TQString sheetName);
  TQString sheetName() const;

  /**
  * Returns the named area represented by this range or an empty string otherwise.
  * This is the name of the area which was passed as a TQString to the Range constructor
  */
  TQString namedArea() const;

  /**
  * Returns true if the other range occupies the same area on the same sheet as this range.
  */
  bool operator==(const Range& range) const;


private:
  Sheet* _sheet;
  TQString _sheetName;
  TQString _namedArea;
  TQRect _range;
  bool _leftFixed;
  bool _rightFixed;
  bool _topFixed;
  bool _bottomFixed;
};

/**
range-list and cell-list
TODO: move to a separate file, improve structure, add iterators and all that
TODO: use this class instead of other means of range-walking all over KSpread
TODO: use this as selection
TODO: anything I forgot ;)
*/
struct RangeList {
  TQValueList<Point> cells;
  TQValueList<Range> ranges;
};


/**
 * RangeIterator
 *
 * Class to simplify the process of iterating through each cell in a
 * range that has already been allocated
 */
class RangeIterator
{
public:
  /**
   * Contstruct the iterator with the rectangular cell area and which
   * sheet the area is on
   */
  RangeIterator(TQRect _range, Sheet* _sheet);
  ~RangeIterator();

  /**
   * @return the first allocated cell in the area
   */
  Cell* first();

  /**
   * @return the next allocated cell in the area after the previous one
   * retrieved, or NULL if it was the last one.
   */
  Cell* next();
private:

  TQRect range;
  Sheet* sheet;
  TQPoint current;
};

//helper functions for the formatting
bool formatIsDate (FormatType fmt);
bool formatIsTime (FormatType fmt);
bool formatIsFraction (FormatType fmt);



KSPREAD_EXPORT TQString util_rangeName( const TQRect &_area );
KSPREAD_EXPORT TQString util_rangeName( Sheet *_sheet, const TQRect &_area );
TQString util_rangeColumnName( const TQRect &_area);
TQString util_rangeRowName( const TQRect &_area);

/**
* Call this function to decode the text of a column label to an integer
* i.e. AA->27
*/
KSPREAD_EXPORT int util_decodeColumnLabelText( const TQString &_col );
/**
* Call this function to encode an integer to the text of the column label
* i.e. 27->AA
*/
KSPREAD_EXPORT TQString util_encodeColumnLabelText( int column );

bool util_isAllSelected(const TQRect &selection);
bool util_isColumnSelected(const TQRect &selection);
bool util_isRowSelected(const TQRect &selection);
bool util_isRowOrColumnSelected( const TQRect &selection );



bool util_validateSheetName(const TQString &name);

TQDomElement util_createElement( const TQString & tagName, const TQFont & font, TQDomDocument & doc );
TQDomElement util_createElement( const TQString & tagname, const TQPen & pen, TQDomDocument & doc );
TQFont       util_toFont( TQDomElement & element );
TQPen        util_toPen( TQDomElement & element );
int         util_penCompare( TQPen const & pen1, TQPen const & pen2 );

TQString convertRefToRange( const TQString & sheet, const TQRect & rect );
TQString convertRefToBase( const TQString & sheet, const TQRect & rect );
TQString convertRangeToRef( const TQString & sheetName, const TQRect & _area );

void insertBracket( TQString & s );
TQString convertOasisPenToString( const TQPen & pen );
TQPen convertOasisStringToPen( const TQString &str );

//Return true when it's a reference to cell from sheet.
KSPREAD_EXPORT bool localReferenceAnchor( const TQString &_ref );



namespace Oasis
{
  /**
   * Converts an OpenDocument representation of a formula/cell reference to a
   * localized formula/cell reference.
   * @param expr The expression to convert from OpenDocument format.
   * @param locale The locale to which the expression should be converted.
   */
  // TODO check visibility
  KSPREAD_EXPORT TQString decodeFormula(const TQString& expr, const TDELocale* locale = 0);
  /**
   * Converts a localized formula/cell reference to an OpenDocument
   * representation of a formula/cell reference.
   * @param expr The expression to convert to OpenDocument format.
   * @param locale The locale from which the expression should be converted.
   */
  KSPREAD_EXPORT TQString encodeFormula(const TQString& expr, const TDELocale* locale = 0);
}

} // namespace KSpread

#endif