/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: */ |