Mercurial > clickerconvert
comparison src/xlsx/xlsxworkbook.cpp @ 1:93d3106bb9a4
Add qt xlsx library
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Tue, 22 Mar 2016 10:38:08 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:49cd5cc0b072 | 1:93d3106bb9a4 |
---|---|
1 /**************************************************************************** | |
2 ** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me> | |
3 ** All right reserved. | |
4 ** | |
5 ** Permission is hereby granted, free of charge, to any person obtaining | |
6 ** a copy of this software and associated documentation files (the | |
7 ** "Software"), to deal in the Software without restriction, including | |
8 ** without limitation the rights to use, copy, modify, merge, publish, | |
9 ** distribute, sublicense, and/or sell copies of the Software, and to | |
10 ** permit persons to whom the Software is furnished to do so, subject to | |
11 ** the following conditions: | |
12 ** | |
13 ** The above copyright notice and this permission notice shall be | |
14 ** included in all copies or substantial portions of the Software. | |
15 ** | |
16 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
18 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
19 ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
20 ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
21 ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
22 ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
23 ** | |
24 ****************************************************************************/ | |
25 #include "xlsxworkbook.h" | |
26 #include "xlsxworkbook_p.h" | |
27 #include "xlsxsharedstrings_p.h" | |
28 #include "xlsxworksheet.h" | |
29 #include "xlsxchartsheet.h" | |
30 #include "xlsxstyles_p.h" | |
31 #include "xlsxformat.h" | |
32 #include "xlsxworksheet_p.h" | |
33 #include "xlsxformat_p.h" | |
34 #include "xlsxmediafile_p.h" | |
35 #include "xlsxutility_p.h" | |
36 | |
37 #include <QXmlStreamWriter> | |
38 #include <QXmlStreamReader> | |
39 #include <QFile> | |
40 #include <QBuffer> | |
41 #include <QDir> | |
42 | |
43 QT_BEGIN_NAMESPACE_XLSX | |
44 | |
45 WorkbookPrivate::WorkbookPrivate(Workbook *q, Workbook::CreateFlag flag) : | |
46 AbstractOOXmlFilePrivate(q, flag) | |
47 { | |
48 sharedStrings = QSharedPointer<SharedStrings> (new SharedStrings(flag)); | |
49 styles = QSharedPointer<Styles>(new Styles(flag)); | |
50 theme = QSharedPointer<Theme>(new Theme(flag)); | |
51 | |
52 x_window = 240; | |
53 y_window = 15; | |
54 window_width = 16095; | |
55 window_height = 9660; | |
56 | |
57 strings_to_numbers_enabled = false; | |
58 strings_to_hyperlinks_enabled = true; | |
59 html_to_richstring_enabled = false; | |
60 date1904 = false; | |
61 defaultDateFormat = QStringLiteral("yyyy-mm-dd"); | |
62 activesheetIndex = 0; | |
63 firstsheet = 0; | |
64 table_count = 0; | |
65 | |
66 last_worksheet_index = 0; | |
67 last_chartsheet_index = 0; | |
68 last_sheet_id = 0; | |
69 } | |
70 | |
71 Workbook::Workbook(CreateFlag flag) | |
72 : AbstractOOXmlFile(new WorkbookPrivate(this, flag)) | |
73 { | |
74 | |
75 } | |
76 | |
77 Workbook::~Workbook() | |
78 { | |
79 } | |
80 | |
81 bool Workbook::isDate1904() const | |
82 { | |
83 Q_D(const Workbook); | |
84 return d->date1904; | |
85 } | |
86 | |
87 /*! | |
88 Excel for Windows uses a default epoch of 1900 and Excel | |
89 for Mac uses an epoch of 1904. However, Excel on either | |
90 platform will convert automatically between one system | |
91 and the other. Qt Xlsx stores dates in the 1900 format | |
92 by default. | |
93 | |
94 \note This function should be called before any date/time | |
95 has been written. | |
96 */ | |
97 void Workbook::setDate1904(bool date1904) | |
98 { | |
99 Q_D(Workbook); | |
100 d->date1904 = date1904; | |
101 } | |
102 | |
103 /* | |
104 Enable the worksheet.write() method to convert strings | |
105 to numbers, where possible, using float() in order to avoid | |
106 an Excel warning about "Numbers Stored as Text". | |
107 | |
108 The default is false | |
109 */ | |
110 void Workbook::setStringsToNumbersEnabled(bool enable) | |
111 { | |
112 Q_D(Workbook); | |
113 d->strings_to_numbers_enabled = enable; | |
114 } | |
115 | |
116 bool Workbook::isStringsToNumbersEnabled() const | |
117 { | |
118 Q_D(const Workbook); | |
119 return d->strings_to_numbers_enabled; | |
120 } | |
121 | |
122 void Workbook::setStringsToHyperlinksEnabled(bool enable) | |
123 { | |
124 Q_D(Workbook); | |
125 d->strings_to_hyperlinks_enabled = enable; | |
126 } | |
127 | |
128 bool Workbook::isStringsToHyperlinksEnabled() const | |
129 { | |
130 Q_D(const Workbook); | |
131 return d->strings_to_hyperlinks_enabled; | |
132 } | |
133 | |
134 void Workbook::setHtmlToRichStringEnabled(bool enable) | |
135 { | |
136 Q_D(Workbook); | |
137 d->html_to_richstring_enabled = enable; | |
138 } | |
139 | |
140 bool Workbook::isHtmlToRichStringEnabled() const | |
141 { | |
142 Q_D(const Workbook); | |
143 return d->html_to_richstring_enabled; | |
144 } | |
145 | |
146 QString Workbook::defaultDateFormat() const | |
147 { | |
148 Q_D(const Workbook); | |
149 return d->defaultDateFormat; | |
150 } | |
151 | |
152 void Workbook::setDefaultDateFormat(const QString &format) | |
153 { | |
154 Q_D(Workbook); | |
155 d->defaultDateFormat = format; | |
156 } | |
157 | |
158 /*! | |
159 * \brief Create a defined name in the workbook. | |
160 * \param name The defined name | |
161 * \param formula The cell or range that the defined name refers to. | |
162 * \param comment | |
163 * \param scope The name of one worksheet, or empty which means golbal scope. | |
164 * \return Return false if the name invalid. | |
165 */ | |
166 bool Workbook::defineName(const QString &name, const QString &formula, const QString &comment, const QString &scope) | |
167 { | |
168 Q_D(Workbook); | |
169 | |
170 //Remove the = sign from the formula if it exists. | |
171 QString formulaString = formula; | |
172 if (formulaString.startsWith(QLatin1Char('='))) | |
173 formulaString = formula.mid(1); | |
174 | |
175 int id=-1; | |
176 if (!scope.isEmpty()) { | |
177 for (int i=0; i<d->sheets.size(); ++i) { | |
178 if (d->sheets[i]->sheetName() == scope) { | |
179 id = d->sheets[i]->sheetId(); | |
180 break; | |
181 } | |
182 } | |
183 } | |
184 | |
185 d->definedNamesList.append(XlsxDefineNameData(name, formulaString, comment, id)); | |
186 return true; | |
187 } | |
188 | |
189 AbstractSheet *Workbook::addSheet(const QString &name, AbstractSheet::SheetType type) | |
190 { | |
191 Q_D(Workbook); | |
192 return insertSheet(d->sheets.size(), name, type); | |
193 } | |
194 | |
195 /*! | |
196 * \internal | |
197 */ | |
198 QStringList Workbook::worksheetNames() const | |
199 { | |
200 Q_D(const Workbook); | |
201 return d->sheetNames; | |
202 } | |
203 | |
204 /*! | |
205 * \internal | |
206 * Used only when load the xlsx file!! | |
207 */ | |
208 AbstractSheet *Workbook::addSheet(const QString &name, int sheetId, AbstractSheet::SheetType type) | |
209 { | |
210 Q_D(Workbook); | |
211 if (sheetId > d->last_sheet_id) | |
212 d->last_sheet_id = sheetId; | |
213 AbstractSheet *sheet=0; | |
214 if (type == AbstractSheet::ST_WorkSheet) { | |
215 sheet = new Worksheet(name, sheetId, this, F_LoadFromExists); | |
216 } else if (type == AbstractSheet::ST_ChartSheet) { | |
217 sheet = new Chartsheet(name, sheetId, this, F_LoadFromExists); | |
218 } else { | |
219 qWarning("unsupported sheet type."); | |
220 Q_ASSERT(false); | |
221 } | |
222 d->sheets.append(QSharedPointer<AbstractSheet>(sheet)); | |
223 d->sheetNames.append(name); | |
224 return sheet; | |
225 } | |
226 | |
227 AbstractSheet *Workbook::insertSheet(int index, const QString &name, AbstractSheet::SheetType type) | |
228 { | |
229 Q_D(Workbook); | |
230 QString sheetName = createSafeSheetName(name); | |
231 if (!sheetName.isEmpty()) { | |
232 //If user given an already in-used name, we should not continue any more! | |
233 if (d->sheetNames.contains(sheetName)) | |
234 return 0; | |
235 } else { | |
236 if (type == AbstractSheet::ST_WorkSheet) { | |
237 do { | |
238 ++d->last_worksheet_index; | |
239 sheetName = QStringLiteral("Sheet%1").arg(d->last_worksheet_index); | |
240 } while (d->sheetNames.contains(sheetName)); | |
241 } else if (type == AbstractSheet::ST_ChartSheet) { | |
242 do { | |
243 ++d->last_chartsheet_index; | |
244 sheetName = QStringLiteral("Chart%1").arg(d->last_chartsheet_index); | |
245 } while (d->sheetNames.contains(sheetName)); | |
246 } else { | |
247 qWarning("unsupported sheet type."); | |
248 return 0; | |
249 } | |
250 } | |
251 | |
252 ++d->last_sheet_id; | |
253 AbstractSheet *sheet; | |
254 if (type == AbstractSheet::ST_WorkSheet) | |
255 sheet = new Worksheet(sheetName, d->last_sheet_id, this, F_NewFromScratch); | |
256 else | |
257 sheet = new Chartsheet(sheetName, d->last_sheet_id, this, F_NewFromScratch); | |
258 | |
259 d->sheets.insert(index, QSharedPointer<AbstractSheet>(sheet)); | |
260 d->sheetNames.insert(index, sheetName); | |
261 d->activesheetIndex = index; | |
262 return sheet; | |
263 } | |
264 | |
265 /*! | |
266 * Returns current active worksheet. | |
267 */ | |
268 AbstractSheet *Workbook::activeSheet() const | |
269 { | |
270 Q_D(const Workbook); | |
271 if (d->sheets.isEmpty()) | |
272 const_cast<Workbook*>(this)->addSheet(); | |
273 return d->sheets[d->activesheetIndex].data(); | |
274 } | |
275 | |
276 bool Workbook::setActiveSheet(int index) | |
277 { | |
278 Q_D(Workbook); | |
279 if (index < 0 || index >= d->sheets.size()) { | |
280 //warning | |
281 return false; | |
282 } | |
283 d->activesheetIndex = index; | |
284 return true; | |
285 } | |
286 | |
287 /*! | |
288 * Rename the worksheet at the \a index to \a newName. | |
289 */ | |
290 bool Workbook::renameSheet(int index, const QString &newName) | |
291 { | |
292 Q_D(Workbook); | |
293 QString name = createSafeSheetName(newName); | |
294 if (index < 0 || index >= d->sheets.size()) | |
295 return false; | |
296 | |
297 //If user given an already in-used name, return false | |
298 for (int i=0; i<d->sheets.size(); ++i) { | |
299 if (d->sheets[i]->sheetName() == name) | |
300 return false; | |
301 } | |
302 | |
303 d->sheets[index]->setSheetName(name); | |
304 d->sheetNames[index] = name; | |
305 return true; | |
306 } | |
307 | |
308 /*! | |
309 * Remove the worksheet at pos \a index. | |
310 */ | |
311 bool Workbook::deleteSheet(int index) | |
312 { | |
313 Q_D(Workbook); | |
314 if (d->sheets.size() <= 1) | |
315 return false; | |
316 if (index < 0 || index >= d->sheets.size()) | |
317 return false; | |
318 d->sheets.removeAt(index); | |
319 d->sheetNames.removeAt(index); | |
320 return true; | |
321 } | |
322 | |
323 /*! | |
324 * Moves the worksheet form \a srcIndex to \a distIndex. | |
325 */ | |
326 bool Workbook::moveSheet(int srcIndex, int distIndex) | |
327 { | |
328 Q_D(Workbook); | |
329 if (srcIndex == distIndex) | |
330 return false; | |
331 | |
332 if (srcIndex < 0 || srcIndex >= d->sheets.size()) | |
333 return false; | |
334 | |
335 QSharedPointer<AbstractSheet> sheet = d->sheets.takeAt(srcIndex); | |
336 d->sheetNames.takeAt(srcIndex); | |
337 if (distIndex >= 0 || distIndex <= d->sheets.size()) { | |
338 d->sheets.insert(distIndex, sheet); | |
339 d->sheetNames.insert(distIndex, sheet->sheetName()); | |
340 } else { | |
341 d->sheets.append(sheet); | |
342 d->sheetNames.append(sheet->sheetName()); | |
343 } | |
344 return true; | |
345 } | |
346 | |
347 bool Workbook::copySheet(int index, const QString &newName) | |
348 { | |
349 Q_D(Workbook); | |
350 if (index < 0 || index >= d->sheets.size()) | |
351 return false; | |
352 | |
353 QString worksheetName = createSafeSheetName(newName); | |
354 if (!newName.isEmpty()) { | |
355 //If user given an already in-used name, we should not continue any more! | |
356 if (d->sheetNames.contains(newName)) | |
357 return false; | |
358 } else { | |
359 int copy_index = 1; | |
360 do { | |
361 ++copy_index; | |
362 worksheetName = QStringLiteral("%1(%2)").arg(d->sheets[index]->sheetName()).arg(copy_index); | |
363 } while (d->sheetNames.contains(worksheetName)); | |
364 } | |
365 | |
366 ++d->last_sheet_id; | |
367 AbstractSheet *sheet = d->sheets[index]->copy(worksheetName, d->last_sheet_id); | |
368 d->sheets.append(QSharedPointer<AbstractSheet> (sheet)); | |
369 d->sheetNames.append(sheet->sheetName()); | |
370 | |
371 return false; | |
372 } | |
373 | |
374 /*! | |
375 * Returns count of worksheets. | |
376 */ | |
377 int Workbook::sheetCount() const | |
378 { | |
379 Q_D(const Workbook); | |
380 return d->sheets.count(); | |
381 } | |
382 | |
383 /*! | |
384 * Returns the sheet object at index \a sheetIndex. | |
385 */ | |
386 AbstractSheet *Workbook::sheet(int index) const | |
387 { | |
388 Q_D(const Workbook); | |
389 if (index < 0 || index >= d->sheets.size()) | |
390 return 0; | |
391 return d->sheets.at(index).data(); | |
392 } | |
393 | |
394 SharedStrings *Workbook::sharedStrings() const | |
395 { | |
396 Q_D(const Workbook); | |
397 return d->sharedStrings.data(); | |
398 } | |
399 | |
400 Styles *Workbook::styles() | |
401 { | |
402 Q_D(Workbook); | |
403 return d->styles.data(); | |
404 } | |
405 | |
406 Theme *Workbook::theme() | |
407 { | |
408 Q_D(Workbook); | |
409 return d->theme.data(); | |
410 } | |
411 | |
412 /*! | |
413 * \internal | |
414 * | |
415 * Unlike media files, drawing file is a property of the sheet. | |
416 */ | |
417 QList<Drawing *> Workbook::drawings() | |
418 { | |
419 Q_D(Workbook); | |
420 QList<Drawing *> ds; | |
421 for (int i=0; i<d->sheets.size(); ++i) { | |
422 QSharedPointer<AbstractSheet> sheet = d->sheets[i]; | |
423 if (sheet->drawing()) | |
424 ds.append(sheet->drawing()); | |
425 } | |
426 | |
427 return ds; | |
428 } | |
429 | |
430 /*! | |
431 * \internal | |
432 */ | |
433 QList<QSharedPointer<AbstractSheet> > Workbook::getSheetsByTypes(AbstractSheet::SheetType type) const | |
434 { | |
435 Q_D(const Workbook); | |
436 QList<QSharedPointer<AbstractSheet> > list; | |
437 for (int i=0; i<d->sheets.size(); ++i) { | |
438 if (d->sheets[i]->sheetType() == type) | |
439 list.append(d->sheets[i]); | |
440 } | |
441 return list; | |
442 } | |
443 | |
444 void Workbook::saveToXmlFile(QIODevice *device) const | |
445 { | |
446 Q_D(const Workbook); | |
447 d->relationships->clear(); | |
448 if (d->sheets.isEmpty()) | |
449 const_cast<Workbook *>(this)->addSheet(); | |
450 | |
451 QXmlStreamWriter writer(device); | |
452 | |
453 writer.writeStartDocument(QStringLiteral("1.0"), true); | |
454 writer.writeStartElement(QStringLiteral("workbook")); | |
455 writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main")); | |
456 writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships")); | |
457 | |
458 writer.writeEmptyElement(QStringLiteral("fileVersion")); | |
459 writer.writeAttribute(QStringLiteral("appName"), QStringLiteral("xl")); | |
460 writer.writeAttribute(QStringLiteral("lastEdited"), QStringLiteral("4")); | |
461 writer.writeAttribute(QStringLiteral("lowestEdited"), QStringLiteral("4")); | |
462 writer.writeAttribute(QStringLiteral("rupBuild"), QStringLiteral("4505")); | |
463 // writer.writeAttribute(QStringLiteral("codeName"), QStringLiteral("{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}")); | |
464 | |
465 writer.writeEmptyElement(QStringLiteral("workbookPr")); | |
466 if (d->date1904) | |
467 writer.writeAttribute(QStringLiteral("date1904"), QStringLiteral("1")); | |
468 writer.writeAttribute(QStringLiteral("defaultThemeVersion"), QStringLiteral("124226")); | |
469 | |
470 writer.writeStartElement(QStringLiteral("bookViews")); | |
471 writer.writeEmptyElement(QStringLiteral("workbookView")); | |
472 writer.writeAttribute(QStringLiteral("xWindow"), QString::number(d->x_window)); | |
473 writer.writeAttribute(QStringLiteral("yWindow"), QString::number(d->y_window)); | |
474 writer.writeAttribute(QStringLiteral("windowWidth"), QString::number(d->window_width)); | |
475 writer.writeAttribute(QStringLiteral("windowHeight"), QString::number(d->window_height)); | |
476 //Store the firstSheet when it isn't the default | |
477 //For example, when "the first sheet 0 is hidden", the first sheet will be 1 | |
478 if (d->firstsheet > 0) | |
479 writer.writeAttribute(QStringLiteral("firstSheet"), QString::number(d->firstsheet + 1)); | |
480 //Store the activeTab when it isn't the first sheet | |
481 if (d->activesheetIndex > 0) | |
482 writer.writeAttribute(QStringLiteral("activeTab"), QString::number(d->activesheetIndex)); | |
483 writer.writeEndElement();//bookViews | |
484 | |
485 writer.writeStartElement(QStringLiteral("sheets")); | |
486 int worksheetIndex = 0; | |
487 int chartsheetIndex = 0; | |
488 for (int i=0; i<d->sheets.size(); ++i) { | |
489 QSharedPointer<AbstractSheet> sheet = d->sheets[i]; | |
490 writer.writeEmptyElement(QStringLiteral("sheet")); | |
491 writer.writeAttribute(QStringLiteral("name"), sheet->sheetName()); | |
492 writer.writeAttribute(QStringLiteral("sheetId"), QString::number(sheet->sheetId())); | |
493 if (sheet->sheetState() == AbstractSheet::SS_Hidden) | |
494 writer.writeAttribute(QStringLiteral("state"), QStringLiteral("hidden")); | |
495 else if (sheet->sheetState() == AbstractSheet::SS_VeryHidden) | |
496 writer.writeAttribute(QStringLiteral("state"), QStringLiteral("veryHidden")); | |
497 | |
498 if (sheet->sheetType() == AbstractSheet::ST_WorkSheet) | |
499 d->relationships->addDocumentRelationship(QStringLiteral("/worksheet"), QStringLiteral("worksheets/sheet%1.xml").arg(++worksheetIndex)); | |
500 else | |
501 d->relationships->addDocumentRelationship(QStringLiteral("/chartsheet"), QStringLiteral("chartsheets/sheet%1.xml").arg(++chartsheetIndex)); | |
502 | |
503 writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count())); | |
504 } | |
505 writer.writeEndElement();//sheets | |
506 | |
507 if (d->externalLinks.size() > 0) { | |
508 writer.writeStartElement(QStringLiteral("externalReferences")); | |
509 for (int i=0; i<d->externalLinks.size(); ++i) { | |
510 writer.writeEmptyElement(QStringLiteral("externalReference")); | |
511 d->relationships->addDocumentRelationship(QStringLiteral("/externalLink"), QStringLiteral("externalLinks/externalLink%1.xml").arg(i+1)); | |
512 writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count())); | |
513 } | |
514 writer.writeEndElement();//externalReferences | |
515 } | |
516 | |
517 if (!d->definedNamesList.isEmpty()) { | |
518 writer.writeStartElement(QStringLiteral("definedNames")); | |
519 foreach (XlsxDefineNameData data, d->definedNamesList) { | |
520 writer.writeStartElement(QStringLiteral("definedName")); | |
521 writer.writeAttribute(QStringLiteral("name"), data.name); | |
522 if (!data.comment.isEmpty()) | |
523 writer.writeAttribute(QStringLiteral("comment"), data.comment); | |
524 if (data.sheetId != -1) { | |
525 //find the local index of the sheet. | |
526 for (int i=0; i<d->sheets.size(); ++i) { | |
527 if (d->sheets[i]->sheetId() == data.sheetId) { | |
528 writer.writeAttribute(QStringLiteral("localSheetId"), QString::number(i)); | |
529 break; | |
530 } | |
531 } | |
532 } | |
533 writer.writeCharacters(data.formula); | |
534 writer.writeEndElement();//definedName | |
535 } | |
536 writer.writeEndElement();//definedNames | |
537 } | |
538 | |
539 writer.writeStartElement(QStringLiteral("calcPr")); | |
540 writer.writeAttribute(QStringLiteral("calcId"), QStringLiteral("124519")); | |
541 writer.writeEndElement(); //calcPr | |
542 | |
543 writer.writeEndElement();//workbook | |
544 writer.writeEndDocument(); | |
545 | |
546 d->relationships->addDocumentRelationship(QStringLiteral("/theme"), QStringLiteral("theme/theme1.xml")); | |
547 d->relationships->addDocumentRelationship(QStringLiteral("/styles"), QStringLiteral("styles.xml")); | |
548 if (!sharedStrings()->isEmpty()) | |
549 d->relationships->addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml")); | |
550 } | |
551 | |
552 bool Workbook::loadFromXmlFile(QIODevice *device) | |
553 { | |
554 Q_D(Workbook); | |
555 | |
556 QXmlStreamReader reader(device); | |
557 while (!reader.atEnd()) { | |
558 QXmlStreamReader::TokenType token = reader.readNext(); | |
559 if (token == QXmlStreamReader::StartElement) { | |
560 if (reader.name() == QLatin1String("sheet")) { | |
561 QXmlStreamAttributes attributes = reader.attributes(); | |
562 const QString name = attributes.value(QLatin1String("name")).toString(); | |
563 int sheetId = attributes.value(QLatin1String("sheetId")).toString().toInt(); | |
564 const QString rId = attributes.value(QLatin1String("r:id")).toString(); | |
565 const QStringRef &stateString = attributes.value(QLatin1String("state")); | |
566 AbstractSheet::SheetState state = AbstractSheet::SS_Visible; | |
567 if (stateString == QLatin1String("hidden")) | |
568 state = AbstractSheet::SS_Hidden; | |
569 else if (stateString == QLatin1String("veryHidden")) | |
570 state = AbstractSheet::SS_VeryHidden; | |
571 | |
572 XlsxRelationship relationship = d->relationships->getRelationshipById(rId); | |
573 | |
574 AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet; | |
575 if (relationship.type.endsWith(QLatin1String("/worksheet"))) | |
576 type = AbstractSheet::ST_WorkSheet; | |
577 else if (relationship.type.endsWith(QLatin1String("/chartsheet"))) | |
578 type = AbstractSheet::ST_ChartSheet; | |
579 else if (relationship.type.endsWith(QLatin1String("/dialogsheet"))) | |
580 type = AbstractSheet::ST_DialogSheet; | |
581 else if (relationship.type.endsWith(QLatin1String("/xlMacrosheet"))) | |
582 type = AbstractSheet::ST_MacroSheet; | |
583 else | |
584 qWarning("unknown sheet type"); | |
585 | |
586 AbstractSheet *sheet = addSheet(name, sheetId, type); | |
587 sheet->setSheetState(state); | |
588 const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target); | |
589 sheet->setFilePath(fullPath); | |
590 } else if (reader.name() == QLatin1String("workbookPr")) { | |
591 QXmlStreamAttributes attrs = reader.attributes(); | |
592 if (attrs.hasAttribute(QLatin1String("date1904"))) | |
593 d->date1904 = true; | |
594 } else if (reader.name() == QLatin1String("bookviews")) { | |
595 while (!(reader.name() == QLatin1String("bookviews") && reader.tokenType() == QXmlStreamReader::EndElement)) { | |
596 reader.readNextStartElement(); | |
597 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
598 if (reader.name() == QLatin1String("workbookView")) { | |
599 QXmlStreamAttributes attrs = reader.attributes(); | |
600 if (attrs.hasAttribute(QLatin1String("xWindow"))) | |
601 d->x_window = attrs.value(QLatin1String("xWindow")).toString().toInt(); | |
602 if (attrs.hasAttribute(QLatin1String("yWindow"))) | |
603 d->y_window = attrs.value(QLatin1String("yWindow")).toString().toInt(); | |
604 if (attrs.hasAttribute(QLatin1String("windowWidth"))) | |
605 d->window_width = attrs.value(QLatin1String("windowWidth")).toString().toInt(); | |
606 if (attrs.hasAttribute(QLatin1String("windowHeight"))) | |
607 d->window_height = attrs.value(QLatin1String("windowHeight")).toString().toInt(); | |
608 if (attrs.hasAttribute(QLatin1String("firstSheet"))) | |
609 d->firstsheet = attrs.value(QLatin1String("firstSheet")).toString().toInt(); | |
610 if (attrs.hasAttribute(QLatin1String("activeTab"))) | |
611 d->activesheetIndex = attrs.value(QLatin1String("activeTab")).toString().toInt(); | |
612 } | |
613 } | |
614 } | |
615 } else if (reader.name() == QLatin1String("externalReference")) { | |
616 QXmlStreamAttributes attributes = reader.attributes(); | |
617 const QString rId = attributes.value(QLatin1String("r:id")).toString(); | |
618 XlsxRelationship relationship = d->relationships->getRelationshipById(rId); | |
619 | |
620 QSharedPointer<SimpleOOXmlFile> link(new SimpleOOXmlFile(F_LoadFromExists)); | |
621 const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target); | |
622 link->setFilePath(fullPath); | |
623 d->externalLinks.append(link); | |
624 } else if (reader.name() == QLatin1String("definedName")) { | |
625 QXmlStreamAttributes attrs = reader.attributes(); | |
626 XlsxDefineNameData data; | |
627 | |
628 data.name = attrs.value(QLatin1String("name")).toString(); | |
629 if (attrs.hasAttribute(QLatin1String("comment"))) | |
630 data.comment = attrs.value(QLatin1String("comment")).toString(); | |
631 if (attrs.hasAttribute(QLatin1String("localSheetId"))) { | |
632 int localId = attrs.value(QLatin1String("localSheetId")).toString().toInt(); | |
633 int sheetId = d->sheets.at(localId)->sheetId(); | |
634 data.sheetId = sheetId; | |
635 } | |
636 data.formula = reader.readElementText(); | |
637 d->definedNamesList.append(data); | |
638 } | |
639 } | |
640 } | |
641 return true; | |
642 } | |
643 | |
644 /*! | |
645 * \internal | |
646 */ | |
647 QList<QSharedPointer<MediaFile> > Workbook::mediaFiles() const | |
648 { | |
649 Q_D(const Workbook); | |
650 | |
651 return d->mediaFiles; | |
652 } | |
653 | |
654 /*! | |
655 * \internal | |
656 */ | |
657 void Workbook::addMediaFile(QSharedPointer<MediaFile> media, bool force) | |
658 { | |
659 Q_D(Workbook); | |
660 if (!force) { | |
661 for (int i=0; i<d->mediaFiles.size(); ++i) { | |
662 if (d->mediaFiles[i]->hashKey() == media->hashKey()) { | |
663 media->setIndex(i); | |
664 return; | |
665 } | |
666 } | |
667 } | |
668 media->setIndex(d->mediaFiles.size()); | |
669 d->mediaFiles.append(media); | |
670 } | |
671 | |
672 /*! | |
673 * \internal | |
674 */ | |
675 QList<QSharedPointer<Chart> > Workbook::chartFiles() const | |
676 { | |
677 Q_D(const Workbook); | |
678 | |
679 return d->chartFiles; | |
680 } | |
681 | |
682 /*! | |
683 * \internal | |
684 */ | |
685 void Workbook::addChartFile(QSharedPointer<Chart> chart) | |
686 { | |
687 Q_D(Workbook); | |
688 | |
689 if (!d->chartFiles.contains(chart)) | |
690 d->chartFiles.append(chart); | |
691 } | |
692 | |
693 QT_END_NAMESPACE_XLSX |