Coverage Report

Created: 2026-06-13 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwps/src/lib/WPSCell.h
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
/* libwps
3
 * Version: MPL 2.0 / LGPLv2.1+
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * Major Contributor(s):
10
 * Copyright (C) 2009, 2011 Alonso Laurent (alonso@loria.fr)
11
 * Copyright (C) 2006, 2007 Andrew Ziem
12
 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
13
 * Copyright (C) 2004 Marc Maurer (uwog@uwog.net)
14
 * Copyright (C) 2003-2005 William Lachance (william.lachance@sympatico.ca)
15
 *
16
 * For minor contributions see the git repository.
17
 *
18
 * Alternatively, the contents of this file may be used under the terms
19
 * of the GNU Lesser General Public License Version 2.1 or later
20
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
21
 * applicable instead of those above.
22
 *
23
 * For further information visit http://libwps.sourceforge.net
24
 */
25
26
/* Define some classes used to store a Cell
27
 */
28
29
#ifndef WPS_CELL_H
30
#  define WPS_CELL_H
31
32
#include <iostream>
33
#include <vector>
34
35
#include "libwps_internal.h"
36
37
#include "WPSFont.h"
38
39
/** a structure used to defined the cell format */
40
class WPSCellFormat
41
{
42
public:
43
  /** the default horizontal alignement.
44
45
  \note actually mainly used for table/spreadsheet cell, FULL is not yet implemented */
46
  enum HorizontalAlignment { HALIGN_LEFT, HALIGN_RIGHT, HALIGN_CENTER,
47
                             HALIGN_FULL, HALIGN_DEFAULT
48
                           };
49
  /** the default vertical alignement. */
50
  enum VerticalAlignment { VALIGN_TOP, VALIGN_CENTER, VALIGN_BOTTOM, VALIGN_DEFAULT };
51
  /** the wrapping */
52
  enum Wrapping { WRAP_WRAP, WRAP_NO_WRAP, WRAP_DEFAULT };
53
  /** the different types of cell's field */
54
  enum FormatType { F_TEXT, F_BOOLEAN, F_NUMBER, F_DATE, F_TIME, F_UNKNOWN };
55
56
  /*   subformat:
57
            NUMBER             DATE                 TIME               TEXT
58
    0 :    default           default[3/2/2000]  default[10:03:00]    default
59
    1 :    decimal
60
    2 :    exponential
61
    3 :    percent
62
    4 :    money
63
    5 :    thousand
64
    6 :    fixed
65
    7 :    fraction
66
   */
67
68
  //! constructor
69
  WPSCellFormat()
70
16.5M
    : m_font()
71
16.5M
    , m_hAlign(HALIGN_DEFAULT)
72
16.5M
    , m_vAlign(VALIGN_DEFAULT)
73
16.5M
    , m_wrapping(WRAP_DEFAULT)
74
16.5M
    , m_rotation(0)
75
16.5M
    , m_bordersList()
76
16.5M
    , m_format(F_UNKNOWN)
77
16.5M
    , m_subFormat(0)
78
16.5M
    , m_DTFormat("")
79
16.5M
    , m_digits(-1000)
80
16.5M
    , m_protected(false)
81
16.5M
    , m_backgroundColor(WPSColor::white()) { }
82
13.3M
  WPSCellFormat(WPSCellFormat const &)=default;
83
2.78M
  WPSCellFormat &operator=(WPSCellFormat const &)=default;
84
  //! destructor
85
  virtual ~WPSCellFormat();
86
  //! returns true if this is a basic format style
87
  bool hasBasicFormat() const
88
8.45M
  {
89
8.45M
    return m_format==F_TEXT || m_format==F_UNKNOWN;
90
8.45M
  }
91
  //! returns a value type
92
  std::string getValueType() const;
93
  //! add to the propList
94
  void addTo(librevenge::RVNGPropertyList &propList) const;
95
  //! get the number style
96
  bool getNumberingProperties(librevenge::RVNGPropertyList &propList) const;
97
98
  //! returns the font
99
  WPSFont const &getFont() const
100
10.6M
  {
101
10.6M
    return m_font;
102
10.6M
  }
103
  //! sets the font
104
  void setFont(WPSFont const &font)
105
5.53M
  {
106
5.53M
    m_font=font;
107
5.53M
  }
108
  //! returns the horizontal alignement
109
  HorizontalAlignment hAlignment() const
110
0
  {
111
0
    return m_hAlign;
112
0
  }
113
  //! sets the horizontal alignement
114
  void setHAlignment(HorizontalAlignment align)
115
659k
  {
116
659k
    m_hAlign = align;
117
659k
  }
118
119
  //! returns the vertical alignement
120
  VerticalAlignment vAlignment() const
121
8.55M
  {
122
8.55M
    return m_vAlign;
123
8.55M
  }
124
  //! sets the vertical alignement
125
  void setVAlignment(VerticalAlignment align)
126
1.86M
  {
127
1.86M
    m_vAlign = align;
128
1.86M
  }
129
  //! returns the wrapping
130
  Wrapping wrapping() const
131
8.55M
  {
132
8.55M
    return m_wrapping;
133
8.55M
  }
134
  //! sets the wrapping
135
  void setWrapping(Wrapping align)
136
77.5k
  {
137
77.5k
    m_wrapping = align;
138
77.5k
  }
139
140
  //! returns the text rotation angle
141
  int getTextRotation() const
142
0
  {
143
0
    return m_rotation;
144
0
  }
145
  //! sets the text rotation angle
146
  void setTextRotation(int rotation)
147
244k
  {
148
244k
    m_rotation = rotation;
149
244k
  }
150
151
  //! returns the format type
152
  FormatType getFormat() const
153
7.08M
  {
154
7.08M
    return m_format;
155
7.08M
  }
156
  //! returns the subformat type
157
  int getSubFormat() const
158
641k
  {
159
641k
    return m_subFormat;
160
641k
  }
161
  //! returns the date/time format ( if set)
162
  std::string getDTFormat() const
163
605k
  {
164
605k
    return m_DTFormat;
165
605k
  }
166
  //! sets the format type
167
  void setFormat(FormatType form, int subForm=0)
168
2.44M
  {
169
2.44M
    m_format = form;
170
2.44M
    m_subFormat = subForm;
171
2.44M
  }
172
  //! sets the format type
173
  void setDTFormat(FormatType form, std::string const &dtFormat="")
174
790k
  {
175
790k
    m_format = form;
176
790k
    m_subFormat = 0;
177
790k
    m_DTFormat = dtFormat;
178
790k
  }
179
180
  //! returns the number of digits ( for a number)
181
  int digits() const
182
605k
  {
183
605k
    return m_digits;
184
605k
  }
185
  //! set the number of digits ( for a number)
186
  void setDigits(int newDigit)
187
1.91M
  {
188
1.91M
    m_digits = newDigit;
189
1.91M
  }
190
191
  //! returns true if the cell is protected
192
  bool isProtected() const
193
0
  {
194
0
    return m_protected;
195
0
  }
196
197
  //! returns true if the cell is protected
198
  void setProtected(bool fl)
199
250k
  {
200
250k
    m_protected = fl;
201
250k
  }
202
203
  //! return true if the cell has some border
204
  bool hasBorders() const
205
2.77k
  {
206
2.77k
    return m_bordersList.size() != 0;
207
2.77k
  }
208
209
  //! return the cell border: libwps::LeftBit | ...
210
  std::vector<WPSBorder> const &borders() const
211
13.9k
  {
212
13.9k
    return m_bordersList;
213
13.9k
  }
214
215
  //! reset the border
216
  void resetBorders()
217
0
  {
218
0
    m_bordersList.resize(0);
219
0
  }
220
221
  //! sets the cell border: wh=WPSBorder::LeftBit|...
222
  void setBorders(int wh, WPSBorder const &border);
223
  //! sets the cell borders
224
  void setBorders(std::vector<WPSBorder> const &newBorders)
225
1.78k
  {
226
1.78k
    m_bordersList=newBorders;
227
1.78k
  }
228
229
  //! returns the background color
230
  WPSColor backgroundColor() const
231
8.72M
  {
232
8.72M
    return m_backgroundColor;
233
8.72M
  }
234
  //! set the background color
235
  void setBackgroundColor(WPSColor const &color)
236
660k
  {
237
660k
    m_backgroundColor = color;
238
660k
  }
239
240
  //! a comparison  function
241
  int compare(WPSCellFormat const &cell, bool onlyNumbering=false) const;
242
243
  //! operator<<
244
  friend std::ostream &operator<<(std::ostream &o, WPSCellFormat const &cell);
245
246
  //! a comparaison structure used to store data
247
  struct CompareFormat
248
  {
249
    //! constructor
250
65.5k
    CompareFormat() {}
251
    //! comparaison function
252
    bool operator()(WPSCellFormat const &c1, WPSCellFormat const &c2) const
253
11.7M
    {
254
11.7M
      return c1.compare(c2, true) < 0;
255
11.7M
    }
256
  };
257
258
protected:
259
  //! convert a DTFormat in a propertyList
260
  static bool convertDTFormat(std::string const &dtFormat, librevenge::RVNGPropertyListVector &propListVector);
261
  //! the cell font ( used in spreadsheet code )
262
  WPSFont m_font;
263
  //! the cell alignement : by default nothing
264
  HorizontalAlignment m_hAlign;
265
  //! the cell vertical alignement : by default nothing
266
  VerticalAlignment m_vAlign;
267
  //! the wrapping : by default nothing
268
  Wrapping m_wrapping;
269
  //! the text rotation
270
  int m_rotation;
271
  //! the cell border WPSBorder::Pos
272
  std::vector<WPSBorder> m_bordersList;
273
  //! the cell format : by default unknown
274
  FormatType m_format;
275
  //! the sub format
276
  int m_subFormat;
277
  //! a date/time format ( using a subset of strftime format )
278
  std::string m_DTFormat;
279
  //! the number of digits
280
  int m_digits;
281
  //! cell protected
282
  bool m_protected;
283
  //! the backgroung color
284
  WPSColor m_backgroundColor;
285
};
286
287
class WPSTable;
288
289
/** a structure used to defined the cell position, and a format */
290
class WPSCell : public WPSCellFormat
291
{
292
  friend class WPSTable;
293
public:
294
  //! constructor
295
  WPSCell()
296
11.0M
    : WPSCellFormat()
297
11.0M
    , m_box()
298
11.0M
    , m_verticalSet(true)
299
11.0M
    , m_position(0,0)
300
11.0M
    , m_numberCellSpanned(1,1) {}
301
2.71M
  WPSCell(WPSCell const &)=default;
302
275k
  WPSCell &operator=(WPSCell const &)=default;
303
  //! destructor
304
  ~WPSCell() override;
305
306
  //! add to the propList
307
  void addTo(librevenge::RVNGPropertyList &propList) const;
308
309
  //! set the bounding box (units in point)
310
  void setBox(WPSBox2f const &b)
311
556k
  {
312
556k
    m_box = b;
313
556k
  }
314
  //! return the bounding box
315
  WPSBox2f const &box() const
316
592k
  {
317
592k
    return m_box;
318
592k
  }
319
  //! returns true if the vertical is fixed
320
  bool isVerticalSet() const
321
668
  {
322
668
    return m_verticalSet;
323
668
  }
324
  //! fixes or not the vertical size
325
  void setVerticalSet(bool verticalSet)
326
1.04k
  {
327
1.04k
    m_verticalSet = verticalSet;
328
1.04k
  }
329
  //! position  accessor
330
  Vec2i &position()
331
208k
  {
332
208k
    return m_position;
333
208k
  }
334
  //! position  accessor
335
  Vec2i const &position() const
336
17.1M
  {
337
17.1M
    return m_position;
338
17.1M
  }
339
  //! set the cell positions :  0,0 -> A1, 0,1 -> A2
340
  void setPosition(Vec2i posi)
341
10.0M
  {
342
10.0M
    m_position = posi;
343
10.0M
  }
344
345
  //! returns the number of spanned cells
346
  Vec2i const &numSpannedCells() const
347
17.1M
  {
348
17.1M
    return m_numberCellSpanned;
349
17.1M
  }
350
  //! sets the number of spanned cells : Vec2i(1,1) means 1 cellule
351
  void setNumSpannedCells(Vec2i numSpanned)
352
6.10M
  {
353
6.10M
    m_numberCellSpanned=numSpanned;
354
6.10M
  }
355
356
  //! call when a cell must be send
357
  virtual bool send(WPSListenerPtr &listener) = 0;
358
359
  //! call when the content of a cell must be send
360
  virtual bool sendContent(WPSListenerPtr &listener) = 0;
361
362
  //! operator<<
363
  friend std::ostream &operator<<(std::ostream &o, WPSCell const &cell);
364
365
protected:
366
  //! a comparaison structure used retrieve the rows and the columns
367
  struct Compare
368
  {
369
    explicit Compare(int dim)
370
594
      : m_coord(dim) {}
371
    //! small structure to define a cell point
372
    struct Point
373
    {
374
      Point(int wh, WPSCell const *cell)
375
3.73k
        : m_which(wh)
376
3.73k
        , m_cell(cell) {}
377
      float getPos(int coord) const
378
27.9k
      {
379
27.9k
        if (m_which)
380
12.9k
          return m_cell->box().max()[coord];
381
15.0k
        return m_cell->box().min()[coord];
382
27.9k
      }
383
      float getSize(int coord) const
384
0
      {
385
0
        return m_cell->box().size()[coord];
386
0
      }
387
      int m_which;
388
      WPSCell const *m_cell;
389
    };
390
391
    //! comparaison function
392
    bool operator()(Point const &c1, Point const &c2) const
393
11.1k
    {
394
11.1k
      float diffF = c1.getPos(m_coord)-c2.getPos(m_coord);
395
11.1k
      if (diffF < 0) return true;
396
6.01k
      if (diffF > 0) return false;
397
2.22k
      int diff = c2.m_which - c1.m_which;
398
2.22k
      if (diff) return (diff < 0);
399
1.82k
      diffF = c1.m_cell->box().size()[m_coord]
400
1.82k
              - c2.m_cell->box().size()[m_coord];
401
1.82k
      if (diffF < 0) return true;
402
1.56k
      if (diffF > 0) return false;
403
1.46k
      if (c1.m_cell->m_verticalSet != c2.m_cell->m_verticalSet) return c1.m_cell->m_verticalSet;
404
#ifdef _WIN64
405
      return ((__int64)c1.m_cell < (__int64)c2.m_cell);
406
#else
407
1.03k
      return long(c1.m_cell) < long(c2.m_cell);
408
1.46k
#endif
409
1.46k
    }
410
411
    //! the coord to compare
412
    int m_coord;
413
  };
414
415
  /** the cell bounding box (unit in point)*/
416
  WPSBox2f m_box;
417
  /** true if y size is fixed */
418
  bool m_verticalSet;
419
  //! the cell row and column : 0,0 -> A1, 0,1 -> A2
420
  Vec2i m_position;
421
  //! the cell spanned : by default (1,1)
422
  Vec2i m_numberCellSpanned;
423
};
424
425
#endif
426
/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */