Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <TableManager.hxx>
21 : #include <util.hxx>
22 :
23 : namespace writerfilter
24 : {
25 : namespace dmapper
26 : {
27 :
28 0 : void TableManager::clearData()
29 : {
30 0 : }
31 :
32 8783 : void TableManager::openCell(const css::uno::Reference<css::text::XTextRange>& rHandle, TablePropertyMapPtr pProps)
33 : {
34 : #ifdef DEBUG_WRITERFILTER
35 : TagLogger::getInstance().startElement("tablemanager.openCell");
36 : TagLogger::getInstance().chars(XTextRangeToString(rHandle));
37 : TagLogger::getInstance().endElement();
38 : #endif
39 :
40 8783 : if (mTableDataStack.size() > 0)
41 : {
42 8783 : TableData::Pointer_t pTableData = mTableDataStack.top();
43 :
44 8783 : pTableData->addCell(rHandle, pProps);
45 : }
46 8783 : }
47 :
48 80719 : bool TableManager::isIgnore() const
49 : {
50 80719 : return isRowEnd();
51 : }
52 :
53 0 : void TableManager::endOfRowAction()
54 : {
55 0 : }
56 :
57 0 : void TableManager::endOfCellAction()
58 : {
59 0 : }
60 :
61 2978 : void TableManager::insertTableProps(TablePropertyMapPtr pProps)
62 : {
63 : #ifdef DEBUG_WRITERFILTER
64 : TagLogger::getInstance().startElement("tablemanager.insertTableProps");
65 : #endif
66 :
67 2978 : if (getTableProps().get() && getTableProps() != pProps)
68 2354 : getTableProps()->InsertProps(pProps);
69 : else
70 624 : setTableProps(pProps);
71 :
72 : #ifdef DEBUG_WRITERFILTER
73 : TagLogger::getInstance().endElement();
74 : #endif
75 2978 : }
76 :
77 4863 : void TableManager::insertRowProps(TablePropertyMapPtr pProps)
78 : {
79 : #ifdef DEBUG_WRITERFILTER
80 : TagLogger::getInstance().startElement("tablemanager.insertRowProps");
81 : #endif
82 :
83 4863 : if (getRowProps().get())
84 1922 : getRowProps()->InsertProps(pProps);
85 : else
86 2941 : setRowProps(pProps);
87 :
88 : #ifdef DEBUG_WRITERFILTER
89 : TagLogger::getInstance().endElement();
90 : #endif
91 4863 : }
92 :
93 0 : void TableManager::cellPropsByCell(unsigned int i, TablePropertyMapPtr pProps)
94 : {
95 : #ifdef DEBUG_WRITERFILTER
96 : TagLogger::getInstance().startElement("tablemanager.cellPropsByCell");
97 : #endif
98 :
99 0 : mTableDataStack.top()->insertCellProperties(i, pProps);
100 :
101 : #ifdef DEBUG_WRITERFILTER
102 : TagLogger::getInstance().endElement();
103 : #endif
104 0 : }
105 :
106 19305 : void TableManager::cellProps(TablePropertyMapPtr pProps)
107 : {
108 : #ifdef DEBUG_WRITERFILTER
109 : TagLogger::getInstance().startElement("tablemanager.cellProps");
110 : #endif
111 :
112 19305 : if (getCellProps().get())
113 12978 : getCellProps()->InsertProps(pProps);
114 : else
115 6327 : setCellProps(pProps);
116 :
117 : #ifdef DEBUG_WRITERFILTER
118 : TagLogger::getInstance().endElement();
119 : #endif
120 19305 : }
121 :
122 79659 : void TableManager::utext(const sal_uInt8* data, size_t len)
123 : {
124 : // optimization: cell/row end characters are the last characters in a run
125 :
126 79659 : if (len > 0)
127 : {
128 79659 : sal_Unicode nChar = data[(len - 1) * 2] + (data[(len - 1) * 2 + 1] << 8);
129 79659 : if (nChar == 0x7)
130 2 : handle0x7();
131 : }
132 79659 : }
133 :
134 0 : void TableManager::text(const sal_uInt8* data, size_t len)
135 : {
136 : // optimization: cell/row end characters are the last characters in a run
137 0 : if (len > 0)
138 : {
139 0 : if (data[len - 1] == 0x7)
140 0 : handle0x7();
141 : }
142 0 : }
143 :
144 2 : void TableManager::handle0x7()
145 : {
146 : #ifdef DEBUG_WRITERFILTER
147 : TagLogger::getInstance().startElement("tablemanager.handle0x7");
148 : #endif
149 :
150 2 : if (mnTableDepthNew < 1)
151 2 : mnTableDepthNew = 1;
152 :
153 2 : if (isInCell())
154 0 : endCell();
155 : else
156 2 : endRow();
157 :
158 : #ifdef DEBUG_WRITERFILTER
159 : TagLogger::getInstance().endElement();
160 : #endif
161 2 : }
162 :
163 487564 : bool TableManager::sprm(Sprm& rSprm)
164 : {
165 487564 : bool bRet = true;
166 487564 : switch (rSprm.getId())
167 : {
168 : case NS_ooxml::LN_tblDepth:
169 : {
170 20665 : Value::Pointer_t pValue = rSprm.getValue();
171 :
172 20665 : cellDepth(pValue->getInt());
173 : }
174 20665 : break;
175 : case NS_ooxml::LN_inTbl:
176 20383 : inCell();
177 20383 : break;
178 : case NS_ooxml::LN_tblCell:
179 8343 : endCell();
180 8343 : break;
181 : case NS_ooxml::LN_tblRow:
182 2976 : endRow();
183 2976 : break;
184 : default:
185 435197 : bRet = false;
186 : }
187 487564 : return bRet;
188 : }
189 :
190 8343 : void TableManager::closeCell(const css::uno::Reference<css::text::XTextRange>& rHandle)
191 : {
192 : #ifdef DEBUG_WRITERFILTER
193 : TagLogger::getInstance().startElement("tablemanager.closeCell");
194 : TagLogger::getInstance().chars(XTextRangeToString(rHandle));
195 : TagLogger::getInstance().endElement();
196 : #endif
197 :
198 8343 : if (mTableDataStack.size() > 0)
199 : {
200 8343 : TableData::Pointer_t pTableData = mTableDataStack.top();
201 :
202 8343 : pTableData->endCell(rHandle);
203 : }
204 8343 : }
205 :
206 10101 : void TableManager::ensureOpenCell(TablePropertyMapPtr pProps)
207 : {
208 : #ifdef DEBUG_WRITERFILTER
209 : TagLogger::getInstance().startElement("tablemanager.ensureOpenCell");
210 : #endif
211 :
212 10101 : if (mTableDataStack.size() > 0)
213 : {
214 10101 : TableData::Pointer_t pTableData = mTableDataStack.top();
215 :
216 10101 : if (pTableData.get() != nullptr)
217 : {
218 10101 : if (!pTableData->isCellOpen())
219 8783 : openCell(getHandle(), pProps);
220 : else
221 1318 : pTableData->insertCellProperties(pProps);
222 10101 : }
223 : }
224 : #ifdef DEBUG_WRITERFILTER
225 : TagLogger::getInstance().endElement();
226 : #endif
227 10101 : }
228 :
229 32554 : void TableManager::endParagraphGroup()
230 : {
231 32554 : sal_Int32 nTableDepthDifference = mnTableDepthNew - mnTableDepth;
232 :
233 32554 : TablePropertyMapPtr pEmptyProps;
234 :
235 65741 : while (nTableDepthDifference > 0)
236 : {
237 633 : ensureOpenCell(pEmptyProps);
238 633 : startLevel();
239 :
240 633 : --nTableDepthDifference;
241 : }
242 65709 : while (nTableDepthDifference < 0)
243 : {
244 601 : endLevel();
245 :
246 601 : ++nTableDepthDifference;
247 : }
248 :
249 32554 : mnTableDepth = mnTableDepthNew;
250 :
251 32554 : if (mnTableDepth > 0)
252 : {
253 12446 : TableData::Pointer_t pTableData = mTableDataStack.top();
254 :
255 12446 : if (isRowEnd())
256 : {
257 2978 : endOfRowAction();
258 2978 : mTableDataStack.top()->endRow(getRowProps());
259 2978 : resetRowProps();
260 : }
261 :
262 9468 : else if (isInCell())
263 : {
264 9468 : ensureOpenCell(getCellProps());
265 :
266 9468 : if (isCellEnd())
267 : {
268 8343 : endOfCellAction();
269 8343 : closeCell(getHandle());
270 : }
271 : }
272 12446 : resetCellProps();
273 32554 : }
274 32554 : }
275 :
276 32569 : void TableManager::startParagraphGroup()
277 : {
278 32569 : mState.resetCellSpecifics();
279 32569 : mnTableDepthNew = 0;
280 32569 : }
281 :
282 5439 : void TableManager::resolveCurrentTable()
283 : {
284 : #ifdef DEBUG_WRITERFILTER
285 : TagLogger::getInstance().startElement("tablemanager.resolveCurrentTable");
286 : #endif
287 :
288 5439 : if (mpTableDataHandler.get() != nullptr)
289 : {
290 : try
291 : {
292 5439 : TableData::Pointer_t pTableData = mTableDataStack.top();
293 :
294 5439 : unsigned int nRows = pTableData->getRowCount();
295 :
296 5439 : mpTableDataHandler->startTable(nRows, pTableData->getDepth(), getTableProps());
297 :
298 8415 : for (unsigned int nRow = 0; nRow < nRows; ++nRow)
299 : {
300 2978 : RowData::Pointer_t pRowData = pTableData->getRow(nRow);
301 :
302 2978 : unsigned int nCells = pRowData->getCellCount();
303 :
304 2978 : mpTableDataHandler->startRow(nCells, pRowData->getProperties());
305 :
306 11319 : for (unsigned int nCell = 0; nCell < nCells; ++nCell)
307 : {
308 8345 : mpTableDataHandler->startCell(pRowData->getCellStart(nCell), pRowData->getCellProperties(nCell));
309 :
310 8341 : mpTableDataHandler->endCell(pRowData->getCellEnd(nCell));
311 : }
312 :
313 2976 : mpTableDataHandler->endRow();
314 2978 : }
315 :
316 5439 : mpTableDataHandler->endTable(mTableDataStack.size() - 1);
317 : }
318 2 : catch (css::uno::Exception const& e)
319 : {
320 : SAL_WARN("writerfilter", "resolving of current table failed with: " << e.Message);
321 : }
322 : }
323 5439 : resetTableProps();
324 5439 : clearData();
325 :
326 : #ifdef DEBUG_WRITERFILTER
327 : TagLogger::getInstance().endElement();
328 : #endif
329 5439 : }
330 :
331 5439 : void TableManager::endLevel()
332 : {
333 5439 : if (mpTableDataHandler.get() != nullptr)
334 5439 : resolveCurrentTable();
335 :
336 : // Store the unfinished row as it will be used for the next table
337 5439 : if (mbKeepUnfinishedRow)
338 5 : mpUnfinishedRow = mTableDataStack.top()->getCurrentRow();
339 5439 : mState.endLevel();
340 5439 : mTableDataStack.pop();
341 :
342 : #ifdef DEBUG_WRITERFILTER
343 : TableData::Pointer_t pTableData;
344 :
345 : if (mTableDataStack.size() > 0)
346 : pTableData = mTableDataStack.top();
347 :
348 : TagLogger::getInstance().startElement("tablemanager.endLevel");
349 : TagLogger::getInstance().attribute("level", mTableDataStack.size());
350 :
351 : if (pTableData.get() != nullptr)
352 : TagLogger::getInstance().attribute("openCell", pTableData->isCellOpen() ? "yes" : "no");
353 :
354 : TagLogger::getInstance().endElement();
355 : #endif
356 5439 : }
357 :
358 5471 : void TableManager::startLevel()
359 : {
360 : #ifdef DEBUG_WRITERFILTER
361 : TableData::Pointer_t pTableData;
362 :
363 : if (mTableDataStack.size() > 0)
364 : pTableData = mTableDataStack.top();
365 :
366 : TagLogger::getInstance().startElement("tablemanager.startLevel");
367 : TagLogger::getInstance().attribute("level", mTableDataStack.size());
368 :
369 : if (pTableData.get() != nullptr)
370 : TagLogger::getInstance().attribute("openCell", pTableData->isCellOpen() ? "yes" : "no");
371 :
372 : TagLogger::getInstance().endElement();
373 : #endif
374 :
375 5471 : TableData::Pointer_t pTableData2(new TableData(mTableDataStack.size()));
376 :
377 : // If we have an unfinished row stored here, then push it to the new TableData
378 5471 : if (mpUnfinishedRow)
379 : {
380 13 : for (unsigned int i = 0; i < mpUnfinishedRow->getCellCount(); ++i)
381 : {
382 8 : pTableData2->addCell(mpUnfinishedRow->getCellStart(i), mpUnfinishedRow->getCellProperties(i));
383 8 : pTableData2->endCell(mpUnfinishedRow->getCellEnd(i));
384 : }
385 5 : mpUnfinishedRow.reset();
386 : }
387 :
388 5471 : mTableDataStack.push(pTableData2);
389 5471 : mState.startLevel();
390 5471 : }
391 :
392 115 : bool TableManager::isInTable()
393 : {
394 115 : bool bInTable = false;
395 115 : if (!mTableDataStack.empty())
396 115 : bInTable = mTableDataStack.top()->getDepth() > 0;
397 115 : return bInTable;
398 : }
399 :
400 27623 : void TableManager::handle(const css::uno::Reference<css::text::XTextRange>& rHandle)
401 : {
402 : #ifdef DEBUG_WRITERFILTER
403 : TagLogger::getInstance().startElement("tablemanager.handle");
404 : TagLogger::getInstance().chars(XTextRangeToString(rHandle));
405 : TagLogger::getInstance().endElement();
406 : #endif
407 :
408 27623 : setHandle(rHandle);
409 27623 : }
410 :
411 4833 : void TableManager::setHandler(TableDataHandler::Pointer_t pTableDataHandler)
412 : {
413 4833 : mpTableDataHandler = pTableDataHandler;
414 4833 : }
415 :
416 2978 : void TableManager::endRow()
417 : {
418 : #ifdef DEBUG_WRITERFILTER
419 : TagLogger::getInstance().element("tablemanager.endRow");
420 : #endif
421 :
422 2978 : setRowEnd(true);
423 2978 : }
424 :
425 8343 : void TableManager::endCell()
426 : {
427 : #ifdef DEBUG_WRITERFILTER
428 : TagLogger::getInstance().element("tablemanager.endCell");
429 : #endif
430 :
431 8343 : setCellEnd(true);
432 8343 : }
433 :
434 20383 : void TableManager::inCell()
435 : {
436 : #ifdef DEBUG_WRITERFILTER
437 : TagLogger::getInstance().element("tablemanager.inCell");
438 : #endif
439 20383 : setInCell(true);
440 :
441 20383 : if (mnTableDepthNew < 1)
442 508 : mnTableDepthNew = 1;
443 20383 : }
444 :
445 20665 : void TableManager::cellDepth(sal_uInt32 nDepth)
446 : {
447 : #ifdef DEBUG_WRITERFILTER
448 : TagLogger::getInstance().startElement("tablemanager.cellDepth");
449 : TagLogger::getInstance().attribute("depth", nDepth);
450 : TagLogger::getInstance().endElement();
451 : #endif
452 :
453 20665 : mnTableDepthNew = nDepth;
454 20665 : }
455 :
456 4834 : TableManager::TableManager()
457 4834 : : mnTableDepthNew(0), mnTableDepth(0), mbKeepUnfinishedRow(false)
458 : {
459 4834 : setRowEnd(false);
460 4834 : setInCell(false);
461 4834 : setCellEnd(false);
462 4834 : }
463 :
464 : }
465 :
466 : }
467 :
468 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|