/src/libstaroffice/src/lib/STOFFCell.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */ |
2 | | |
3 | | /* libstaroffice |
4 | | * Version: MPL 2.0 / LGPLv2+ |
5 | | * |
6 | | * The contents of this file are subject to the Mozilla Public License Version |
7 | | * 2.0 (the "License"); you may not use this file except in compliance with |
8 | | * the License or as specified alternatively below. You may obtain a copy of |
9 | | * the License at http://www.mozilla.org/MPL/ |
10 | | * |
11 | | * Software distributed under the License is distributed on an "AS IS" basis, |
12 | | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
13 | | * for the specific language governing rights and limitations under the |
14 | | * License. |
15 | | * |
16 | | * Major Contributor(s): |
17 | | * Copyright (C) 2002 William Lachance (wrlach@gmail.com) |
18 | | * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net) |
19 | | * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch) |
20 | | * Copyright (C) 2006, 2007 Andrew Ziem |
21 | | * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr) |
22 | | * |
23 | | * |
24 | | * All Rights Reserved. |
25 | | * |
26 | | * For minor contributions see the git repository. |
27 | | * |
28 | | * Alternatively, the contents of this file may be used under the terms of |
29 | | * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"), |
30 | | * in which case the provisions of the LGPLv2+ are applicable |
31 | | * instead of those above. |
32 | | */ |
33 | | |
34 | | /** \file STOFFCell.cxx |
35 | | * Implements STOFFCell (cell content and format) |
36 | | */ |
37 | | #include <time.h> |
38 | | |
39 | | #include <cmath> |
40 | | #include <iomanip> |
41 | | #include <iostream> |
42 | | #include <sstream> |
43 | | |
44 | | #include <librevenge/librevenge.h> |
45 | | |
46 | | #include "STOFFFont.hxx" |
47 | | #include "STOFFListener.hxx" |
48 | | |
49 | | #include "STOFFCell.hxx" |
50 | | |
51 | | //////////////////////////////////////////////////////////// |
52 | | // STOFFCell::Format |
53 | | //////////////////////////////////////////////////////////// |
54 | | STOFFCell::Format::~Format() |
55 | 1.93M | { |
56 | 1.93M | } |
57 | | |
58 | | std::string STOFFCell::Format::getValueType() const |
59 | 388k | { |
60 | 388k | switch (m_format) { |
61 | 387k | case F_NUMBER: |
62 | 387k | if (m_numberFormat==F_NUMBER_CURRENCY) return "currency"; |
63 | 385k | if (m_numberFormat==F_NUMBER_PERCENT) return "percent"; |
64 | 384k | if (m_numberFormat==F_NUMBER_SCIENTIFIC) return "scientific"; |
65 | 384k | return "float"; |
66 | 0 | case F_BOOLEAN: |
67 | 0 | return "boolean"; |
68 | 0 | case F_DATE: |
69 | 0 | case F_DATETIME: |
70 | 0 | return "date"; |
71 | 0 | case F_TIME: |
72 | 0 | return "time"; |
73 | 263 | case F_TEXT: |
74 | 263 | case F_UNKNOWN: |
75 | 263 | default: |
76 | 263 | break; |
77 | 388k | } |
78 | 263 | return "float"; |
79 | 388k | } |
80 | | |
81 | | bool STOFFCell::Format::convertDTFormat(std::string const &dtFormat, librevenge::RVNGPropertyListVector &propVect) |
82 | 19.4k | { |
83 | 19.4k | propVect.clear(); |
84 | 19.4k | size_t len=dtFormat.size(); |
85 | 19.4k | std::string text(""); |
86 | 19.4k | librevenge::RVNGPropertyList list; |
87 | 123k | for (size_t c=0; c < len; ++c) { |
88 | 103k | if (dtFormat[c]!='%' || c+1==len) { |
89 | 42.1k | text+=dtFormat[c]; |
90 | 42.1k | continue; |
91 | 42.1k | } |
92 | 61.6k | char ch=dtFormat[++c]; |
93 | 61.6k | if (ch=='%') { |
94 | 0 | text += '%'; |
95 | 0 | continue; |
96 | 0 | } |
97 | 61.6k | if (!text.empty()) { |
98 | 42.1k | list.clear(); |
99 | 42.1k | list.insert("librevenge:value-type", "text"); |
100 | 42.1k | list.insert("librevenge:text", text.c_str()); |
101 | 42.1k | propVect.append(list); |
102 | 42.1k | text.clear(); |
103 | 42.1k | } |
104 | 61.6k | list.clear(); |
105 | 61.6k | switch (ch) { |
106 | 7.60k | case 'Y': |
107 | 7.60k | list.insert("number:style", "long"); |
108 | 7.60k | STOFF_FALLTHROUGH; |
109 | 11.7k | case 'y': |
110 | 11.7k | list.insert("librevenge:value-type", "year"); |
111 | 11.7k | propVect.append(list); |
112 | 11.7k | break; |
113 | 461 | case 'B': |
114 | 461 | list.insert("number:style", "long"); |
115 | 461 | STOFF_FALLTHROUGH; |
116 | 488 | case 'b': |
117 | 488 | case 'h': |
118 | 488 | list.insert("librevenge:value-type", "month"); |
119 | 488 | list.insert("number:textual", true); |
120 | 488 | propVect.append(list); |
121 | 488 | break; |
122 | 11.7k | case 'm': |
123 | 11.7k | list.insert("librevenge:value-type", "month"); |
124 | 11.7k | propVect.append(list); |
125 | 11.7k | break; |
126 | 0 | case 'e': |
127 | 0 | list.insert("number:style", "long"); |
128 | 0 | STOFF_FALLTHROUGH; |
129 | 11.7k | case 'd': |
130 | 11.7k | list.insert("librevenge:value-type", "day"); |
131 | 11.7k | propVect.append(list); |
132 | 11.7k | break; |
133 | 0 | case 'A': |
134 | 0 | list.insert("number:style", "long"); |
135 | 0 | STOFF_FALLTHROUGH; |
136 | 0 | case 'a': |
137 | 0 | list.insert("librevenge:value-type", "day-of-week"); |
138 | 0 | propVect.append(list); |
139 | 0 | break; |
140 | | |
141 | 3.63k | case 'H': |
142 | 3.63k | list.insert("number:style", "long"); |
143 | 3.63k | STOFF_FALLTHROUGH; |
144 | 7.44k | case 'I': |
145 | 7.44k | list.insert("librevenge:value-type", "hours"); |
146 | 7.44k | propVect.append(list); |
147 | 7.44k | break; |
148 | 7.76k | case 'M': |
149 | 7.76k | list.insert("librevenge:value-type", "minutes"); |
150 | 7.76k | list.insert("number:style", "long"); |
151 | 7.76k | propVect.append(list); |
152 | 7.76k | break; |
153 | 6.55k | case 'S': |
154 | 6.55k | list.insert("librevenge:value-type", "seconds"); |
155 | 6.55k | list.insert("number:style", "long"); |
156 | 6.55k | propVect.append(list); |
157 | 6.55k | break; |
158 | 322 | case 's': // extension for second + milli second... |
159 | 322 | list.insert("librevenge:value-type", "seconds"); |
160 | 322 | list.insert("number:decimal-places", 2); |
161 | 322 | list.insert("number:style", "long"); |
162 | 322 | propVect.append(list); |
163 | 322 | break; |
164 | 3.80k | case 'p': |
165 | 3.80k | list.insert("librevenge:value-type", "text"); |
166 | 3.80k | list.insert("librevenge:text", " "); |
167 | 3.80k | propVect.append(list); |
168 | 3.80k | list.clear(); |
169 | 3.80k | list.insert("librevenge:value-type", "am-pm"); |
170 | 3.80k | propVect.append(list); |
171 | 3.80k | break; |
172 | 0 | case 'Q': // extension for quarter |
173 | 0 | list.insert("librevenge:value-type", "quarter"); |
174 | 0 | propVect.append(list); |
175 | 0 | break; |
176 | 0 | default: |
177 | 0 | STOFF_DEBUG_MSG(("STOFFCell::Format::convertDTFormat: find unimplement command %c(ignored)\n", ch)); |
178 | 61.6k | } |
179 | 61.6k | } |
180 | 19.4k | if (!text.empty()) { |
181 | 0 | list.clear(); |
182 | 0 | list.insert("librevenge:value-type", "text"); |
183 | 0 | list.insert("librevenge:text", text.c_str()); |
184 | 0 | propVect.append(list); |
185 | 0 | } |
186 | 19.4k | return propVect.count()!=0; |
187 | 19.4k | } |
188 | | |
189 | | std::ostream &operator<<(std::ostream &o, STOFFCell::Format const &format) |
190 | 0 | { |
191 | 0 | switch (format.m_format) { |
192 | 0 | case STOFFCell::F_BOOLEAN: |
193 | 0 | o << "boolean"; |
194 | 0 | break; |
195 | 0 | case STOFFCell::F_TEXT: |
196 | 0 | o << "text"; |
197 | 0 | break; |
198 | 0 | case STOFFCell::F_NUMBER: |
199 | 0 | o << "number"; |
200 | 0 | switch (format.m_numberFormat) { |
201 | 0 | case STOFFCell::F_NUMBER_GENERIC: |
202 | 0 | break; |
203 | 0 | case STOFFCell::F_NUMBER_DECIMAL: |
204 | 0 | o << "[decimal]"; |
205 | 0 | break; |
206 | 0 | case STOFFCell::F_NUMBER_SCIENTIFIC: |
207 | 0 | o << "[exp]"; |
208 | 0 | break; |
209 | 0 | case STOFFCell::F_NUMBER_PERCENT: |
210 | 0 | o << "[percent]"; |
211 | 0 | break; |
212 | 0 | case STOFFCell::F_NUMBER_CURRENCY: |
213 | 0 | o << "[money]"; |
214 | 0 | break; |
215 | 0 | case STOFFCell::F_NUMBER_FRACTION: |
216 | 0 | o << "[fraction]"; |
217 | 0 | break; |
218 | 0 | case STOFFCell::F_NUMBER_UNKNOWN: |
219 | 0 | default: |
220 | 0 | STOFF_DEBUG_MSG(("STOFFCell::operator<<(Format): find unexpected type\n")); |
221 | 0 | o << "###format,"; |
222 | 0 | break; |
223 | 0 | } |
224 | 0 | break; |
225 | 0 | case STOFFCell::F_DATE: |
226 | 0 | o << "date"; |
227 | 0 | break; |
228 | 0 | case STOFFCell::F_DATETIME: |
229 | 0 | o << "date+time"; |
230 | 0 | break; |
231 | 0 | case STOFFCell::F_TIME: |
232 | 0 | o << "time"; |
233 | 0 | break; |
234 | 0 | case STOFFCell::F_UNKNOWN: |
235 | 0 | default: |
236 | 0 | break; // default |
237 | 0 | } |
238 | 0 | o << ","; |
239 | |
|
240 | 0 | return o; |
241 | 0 | } |
242 | | |
243 | | //////////////////////////////////////////////////////////// |
244 | | // STOFFCell |
245 | | //////////////////////////////////////////////////////////// |
246 | | void STOFFCell::addTo(librevenge::RVNGPropertyList &propList) const |
247 | 817k | { |
248 | 817k | propList.insert("librevenge:column", position()[0]); |
249 | 817k | propList.insert("librevenge:row", position()[1]); |
250 | | |
251 | 817k | m_font.addTo(propList); |
252 | 817k | m_cellStyle.addTo(propList); |
253 | 817k | } |
254 | | |
255 | | std::string STOFFCell::getColumnName(int col) |
256 | 0 | { |
257 | 0 | std::stringstream f; |
258 | 0 | f << "[."; |
259 | 0 | if (col > 26) f << char('A'+col/26); |
260 | 0 | f << char('A'+(col%26)); |
261 | 0 | f << "]"; |
262 | 0 | return f.str(); |
263 | 0 | } |
264 | | |
265 | | std::string STOFFCell::getCellName(STOFFVec2i const &pos, STOFFVec2b const &absolute) |
266 | 0 | { |
267 | 0 | std::stringstream f; |
268 | 0 | f << "[." << libstoff::getCellName(pos, absolute) << ']'; |
269 | 0 | return f.str(); |
270 | 0 | } |
271 | | |
272 | | std::ostream &operator<<(std::ostream &o, STOFFCell const &cell) |
273 | 0 | { |
274 | 0 | o << STOFFCell::getCellName(cell.m_position, STOFFVec2b(false,false)) << ":"; |
275 | 0 | if (cell.m_bdBox.size()[0]>0 || cell.m_bdBox.size()[1]>0) |
276 | 0 | o << "bdBox=" << cell.m_bdBox << ","; |
277 | 0 | if (cell.m_bdSize[0]>0 || cell.m_bdSize[1]>0) |
278 | 0 | o << "bdSize=" << cell.m_bdSize << ","; |
279 | 0 | o << cell.m_format; |
280 | 0 | return o; |
281 | 0 | } |
282 | | |
283 | | // send data to listener |
284 | | bool STOFFCell::send(STOFFListenerPtr listener, STOFFTable &table) |
285 | 0 | { |
286 | 0 | if (!listener) return true; |
287 | 0 | listener->openTableCell(*this); |
288 | 0 | bool ok=sendContent(listener, table); |
289 | 0 | listener->closeTableCell(); |
290 | 0 | return ok; |
291 | 0 | } |
292 | | |
293 | | bool STOFFCell::sendContent(STOFFListenerPtr, STOFFTable &) |
294 | 0 | { |
295 | 0 | STOFF_DEBUG_MSG(("STOFFCell::sendContent: must not be called!!!\n")); |
296 | 0 | return false; |
297 | 0 | } |
298 | | |
299 | | //////////////////////////////////////////////////////////// |
300 | | // STOFFCellContent |
301 | | //////////////////////////////////////////////////////////// |
302 | | bool STOFFCellContent::double2Date(double val, int &Y, int &M, int &D) |
303 | 3.90k | { |
304 | | /* first convert the date in long*/ |
305 | 3.90k | auto numDaysSinceOrigin=long(val+(val>0 ? -2 : -3)+0.4); |
306 | | // checkme: do we need to check before for isNan(val) ? |
307 | 3.90k | if (numDaysSinceOrigin<-10000*365 || numDaysSinceOrigin>10000*365) { |
308 | | /* normally, we can expect documents to contain date between 1900 |
309 | | and 2100. So even if such a date can make sense, storing it as |
310 | | a number of days is clearly abnormal */ |
311 | 11 | STOFF_DEBUG_MSG(("STOFFCellContent::double2Date: using a double to represent the date %ld seems odd\n", numDaysSinceOrigin)); |
312 | 11 | Y=1900; |
313 | 11 | M=D=1; |
314 | 11 | return false; |
315 | 11 | } |
316 | | // find the century |
317 | 3.89k | int century=19; |
318 | 5.30k | while (numDaysSinceOrigin>=36500+24) { |
319 | 1.40k | long numDaysInCentury=36500+24+((century%4)?0:1); |
320 | 1.40k | if (numDaysSinceOrigin<numDaysInCentury) break; |
321 | 1.40k | numDaysSinceOrigin-=numDaysInCentury; |
322 | 1.40k | ++century; |
323 | 1.40k | } |
324 | 4.50k | while (numDaysSinceOrigin<0) { |
325 | 607 | --century; |
326 | 607 | numDaysSinceOrigin+=36500+24+((century%4)?0:1); |
327 | 607 | } |
328 | | // now compute the year |
329 | 3.89k | Y=int(numDaysSinceOrigin/365); |
330 | 3.89k | long numDaysToEndY1=Y*365+(Y>0 ? (Y-1)/4+((century%4)?0:1) : 0); |
331 | 3.89k | if (numDaysToEndY1>numDaysSinceOrigin) { |
332 | 890 | --Y; |
333 | 890 | numDaysToEndY1=Y*365+(Y>0 ? (Y-1)/4+((century%4)?0:1) : 0); |
334 | 890 | } |
335 | | // finish to compute the date |
336 | 3.89k | auto numDaysFrom1Jan=int(numDaysSinceOrigin-numDaysToEndY1); |
337 | 3.89k | Y+=century*100; |
338 | 3.89k | bool isLeap=(Y%4)==0 && ((Y%400)==0 || (Y%100)!=0); |
339 | | |
340 | 23.9k | for (M=0; M<12; ++M) { |
341 | 23.9k | static const int days[2][12] = { |
342 | 23.9k | { 0,31,59,90,120,151,181,212,243,273,304,334}, |
343 | 23.9k | { 0,31,60,91,121,152,182,213,244,274,305,335} |
344 | 23.9k | }; |
345 | 23.9k | if (M<11 && days[isLeap ? 1 : 0][M+1]<=numDaysFrom1Jan) continue; |
346 | 3.89k | D=(numDaysFrom1Jan-days[isLeap ? 1 : 0][M++])+1; |
347 | 3.89k | break; |
348 | 23.9k | } |
349 | 3.89k | return true; |
350 | 3.90k | } |
351 | | |
352 | | bool STOFFCellContent::date2Double(int Y, int M, int D, double &val) |
353 | 0 | { |
354 | 0 | --M; |
355 | 0 | --D; |
356 | 0 | if (M>11) { |
357 | 0 | Y += M/12; |
358 | 0 | M %= 12; |
359 | 0 | } |
360 | 0 | else if (M<0) { |
361 | 0 | int yDiff = (-M + 11)/12; |
362 | 0 | Y -= yDiff; |
363 | 0 | M+=12*yDiff; |
364 | 0 | } |
365 | | // sanity check |
366 | 0 | if (M<0||M>11) { |
367 | 0 | STOFF_DEBUG_MSG(("STOFFCellContent::date2Double: something is bad\n")); |
368 | 0 | return false; |
369 | 0 | } |
370 | 0 | bool isLeap=(Y%4)==0 && ((Y%400)==0 || (Y%100)!=0); |
371 | 0 | int32_t const daysFrom0=365*Y+(Y/400)-(Y/100)+(Y/4); |
372 | 0 | int32_t const daysFrom1900=365*1900+(1900/400)-(1900/100)+(1900/4); |
373 | 0 | static const int32_t days[2][12] = { |
374 | 0 | { 0,31,59,90,120,151,181,212,243,273,304,334}, |
375 | 0 | { 0,31,60,91,121,152,182,213,244,274,305,335} |
376 | 0 | }; |
377 | 0 | int32_t daysFrom1Jan=days[isLeap ? 1 : 0][M] + D; |
378 | 0 | val=double(daysFrom0-daysFrom1900+daysFrom1Jan); |
379 | 0 | return true; |
380 | 0 | } |
381 | | |
382 | | bool STOFFCellContent::double2Time(double val, int &H, int &M, int &S) |
383 | 6.35k | { |
384 | 6.35k | if (val < 0.0 || val > 1.0) return false; |
385 | 6.02k | double time = 24.*3600.*val+0.5; |
386 | 6.02k | H=int(time/3600.); |
387 | 6.02k | time -= H*3600.; |
388 | 6.02k | M=int(time/60.); |
389 | 6.02k | time -= M*60.; |
390 | 6.02k | S=int(time); |
391 | 6.02k | return true; |
392 | 6.35k | } |
393 | | |
394 | | std::ostream &operator<<(std::ostream &o, STOFFCellContent const &content) |
395 | 0 | { |
396 | 0 | switch (content.m_contentType) { |
397 | 0 | case STOFFCellContent::C_NONE: |
398 | 0 | break; |
399 | 0 | case STOFFCellContent::C_TEXT: |
400 | 0 | o << ",text"; |
401 | 0 | break; |
402 | 0 | case STOFFCellContent::C_TEXT_BASIC: |
403 | 0 | o << ",text=\"" << libstoff::getString(content.m_text).cstr() << "\""; |
404 | 0 | break; |
405 | 0 | case STOFFCellContent::C_NUMBER: |
406 | 0 | o << ",val="<< content.m_value; |
407 | 0 | break; |
408 | 0 | case STOFFCellContent::C_FORMULA: |
409 | 0 | o << ",formula="; |
410 | 0 | for (const auto &l : content.m_formula) |
411 | 0 | o << l; |
412 | 0 | if (content.isValueSet()) o << "[" << content.m_value << "]"; |
413 | 0 | break; |
414 | 0 | case STOFFCellContent::C_UNKNOWN: |
415 | 0 | break; |
416 | 0 | default: |
417 | 0 | o << "###unknown type,"; |
418 | 0 | break; |
419 | 0 | } |
420 | 0 | return o; |
421 | 0 | } |
422 | | |
423 | | // ---------- MWAWContentListener::FormulaInstruction ------------------ |
424 | | librevenge::RVNGPropertyList STOFFCellContent::FormulaInstruction::getPropertyList() const |
425 | 233k | { |
426 | 233k | librevenge::RVNGPropertyList pList; |
427 | 233k | switch (m_type) { |
428 | 0 | case F_None: |
429 | 0 | break; |
430 | 108k | case F_Operator: |
431 | 108k | pList.insert("librevenge:type","librevenge-operator"); |
432 | 108k | pList.insert("librevenge:operator",m_content); |
433 | 108k | break; |
434 | 39.1k | case F_Function: |
435 | 39.1k | pList.insert("librevenge:type","librevenge-function"); |
436 | 39.1k | pList.insert("librevenge:function",m_content); |
437 | 39.1k | break; |
438 | 244 | case F_Text: |
439 | 244 | pList.insert("librevenge:type","librevenge-text"); |
440 | 244 | pList.insert("librevenge:text",m_content); |
441 | 244 | break; |
442 | 1.91k | case F_Double: |
443 | 1.91k | pList.insert("librevenge:type","librevenge-number"); |
444 | 1.91k | pList.insert("librevenge:number",m_doubleValue, librevenge::RVNG_GENERIC); |
445 | 1.91k | break; |
446 | 368 | case F_Long: |
447 | 368 | pList.insert("librevenge:type","librevenge-number"); |
448 | 368 | pList.insert("librevenge:number",double(m_longValue), librevenge::RVNG_GENERIC); |
449 | 368 | break; |
450 | 67.8k | case F_Cell: |
451 | 67.8k | pList.insert("librevenge:type","librevenge-cell"); |
452 | 67.8k | pList.insert("librevenge:column",m_position[0][0], librevenge::RVNG_GENERIC); |
453 | 67.8k | pList.insert("librevenge:row",m_position[0][1], librevenge::RVNG_GENERIC); |
454 | 67.8k | pList.insert("librevenge:column-absolute",!m_positionRelative[0][0]); |
455 | 67.8k | pList.insert("librevenge:row-absolute",!m_positionRelative[0][1]); |
456 | 67.8k | if (!m_sheet.empty()) |
457 | 5.15k | pList.insert("librevenge:sheet",m_sheet); |
458 | 67.8k | break; |
459 | 15.3k | case F_CellList: |
460 | 15.3k | pList.insert("librevenge:type","librevenge-cells"); |
461 | 15.3k | pList.insert("librevenge:start-column",m_position[0][0], librevenge::RVNG_GENERIC); |
462 | 15.3k | pList.insert("librevenge:start-row",m_position[0][1], librevenge::RVNG_GENERIC); |
463 | 15.3k | pList.insert("librevenge:start-column-absolute",!m_positionRelative[0][0]); |
464 | 15.3k | pList.insert("librevenge:start-row-absolute",!m_positionRelative[0][1]); |
465 | 15.3k | pList.insert("librevenge:end-column",m_position[1][0], librevenge::RVNG_GENERIC); |
466 | 15.3k | pList.insert("librevenge:end-row",m_position[1][1], librevenge::RVNG_GENERIC); |
467 | 15.3k | pList.insert("librevenge:end-column-absolute",!m_positionRelative[1][0]); |
468 | 15.3k | pList.insert("librevenge:end-row-absolute",!m_positionRelative[1][1]); |
469 | 15.3k | if (!m_sheet.empty()) |
470 | 356 | pList.insert("librevenge:sheet-name",m_sheet.cstr()); |
471 | 15.3k | break; |
472 | 0 | case F_Index: { |
473 | 0 | static bool first=true; |
474 | 0 | if (first) { |
475 | 0 | STOFF_DEBUG_MSG(("STOFFCellContent::FormulaInstruction::getPropertyList: impossible to send index data\n")); |
476 | 0 | first=false; |
477 | 0 | } |
478 | 0 | break; |
479 | 0 | } |
480 | 0 | default: |
481 | 0 | STOFF_DEBUG_MSG(("STOFFCellContent::FormulaInstruction::getPropertyList: unexpected type\n")); |
482 | 233k | } |
483 | 233k | return pList; |
484 | 233k | } |
485 | | |
486 | | std::ostream &operator<<(std::ostream &o, STOFFCellContent::FormulaInstruction const &inst) |
487 | 0 | { |
488 | 0 | if (inst.m_type==STOFFCellContent::FormulaInstruction::F_Double) |
489 | 0 | o << inst.m_doubleValue; |
490 | 0 | else if (inst.m_type==STOFFCellContent::FormulaInstruction::F_Long) |
491 | 0 | o << inst.m_longValue; |
492 | 0 | else if (inst.m_type==STOFFCellContent::FormulaInstruction::F_Index) |
493 | 0 | o << "[Idx" << inst.m_longValue << "]"; |
494 | 0 | else if (inst.m_type==STOFFCellContent::FormulaInstruction::F_Cell) { |
495 | 0 | if (!inst.m_sheet.empty()) o << inst.m_sheet.cstr(); |
496 | 0 | else if (inst.m_sheetId>=0) { |
497 | 0 | if (!inst.m_sheetIdRelative) o << "$"; |
498 | 0 | o << "S" << inst.m_sheetId; |
499 | 0 | o << ":"; |
500 | 0 | } |
501 | 0 | o << libstoff::getCellName(inst.m_position[0],inst.m_positionRelative[0]); |
502 | 0 | } |
503 | 0 | else if (inst.m_type==STOFFCellContent::FormulaInstruction::F_CellList) { |
504 | 0 | if (!inst.m_sheet.empty()) o << inst.m_sheet.cstr() << ":"; |
505 | 0 | else if (inst.m_sheetId>=0) { |
506 | 0 | if (inst.m_sheetIdRelative) o << "$"; |
507 | 0 | o << "S" << inst.m_sheetId; |
508 | 0 | o << ":"; |
509 | 0 | } |
510 | 0 | for (int l=0; l<2; ++l) { |
511 | 0 | o << libstoff::getCellName(inst.m_position[l],inst.m_positionRelative[l]); |
512 | 0 | if (l==0) o << ":"; |
513 | 0 | } |
514 | 0 | } |
515 | 0 | else if (inst.m_type==STOFFCellContent::FormulaInstruction::F_Text) |
516 | 0 | o << "\"" << inst.m_content.cstr() << "\""; |
517 | 0 | else if (inst.m_type!=STOFFCellContent::FormulaInstruction::F_None) |
518 | 0 | o << inst.m_content.cstr(); |
519 | 0 | if (!inst.m_extra.empty()) |
520 | 0 | o << "[" << inst.m_extra << "]"; |
521 | 0 | return o; |
522 | 0 | } |
523 | | |
524 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |