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 : #ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEMANAGER_HXX
21 : #define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEMANAGER_HXX
22 :
23 : #include <dmapper/resourcemodel.hxx>
24 :
25 : #include <ooxml/resourceids.hxx>
26 :
27 : #include <memory>
28 : #include <stack>
29 : #include "TagLogger.hxx"
30 :
31 : #include <rtl/strbuf.hxx>
32 : #include <PropertyMap.hxx>
33 : #include <TableData.hxx>
34 :
35 : namespace writerfilter
36 : {
37 : namespace dmapper
38 : {
39 :
40 : /**
41 : Class to handle events generated by TableManager::resolveCurrentTable
42 : */
43 1984 : class TableDataHandler
44 : {
45 : public:
46 : typedef std::shared_ptr<TableDataHandler> Pointer_t;
47 :
48 : /**
49 : Handle start of table.
50 :
51 : @param nRows number of rows in the table
52 : @param nDepth depth of the table in surrounding table hierarchy
53 : @param pProps properties of the table
54 : */
55 : virtual void startTable(unsigned int nRows, unsigned int nDepth, TablePropertyMapPtr pProps) = 0;
56 :
57 : /**
58 : Handle end of table.
59 : */
60 : virtual void endTable(unsigned int nestedTableLevel) = 0;
61 :
62 : /**
63 : Handle start of row.
64 :
65 : @param nCols number of columns in the table
66 : @param pProps properties of the row
67 : */
68 : virtual void startRow(unsigned int nCols, TablePropertyMapPtr pProps) = 0;
69 :
70 : /**
71 : Handle end of row.
72 : */
73 : virtual void endRow() = 0;
74 :
75 : /**
76 : Handle start of cell.
77 :
78 : @param rT start handle of the cell
79 : @param pProps properties of the cell
80 : */
81 : virtual void startCell(const css::uno::Reference<css::text::XTextRange>& xTextRange, TablePropertyMapPtr pProps) = 0;
82 :
83 : /**
84 : Handle end of cell.
85 :
86 : @param rT end handle of cell
87 : */
88 : virtual void endCell(const css::uno::Reference<css::text::XTextRange>& xTextRange) = 0;
89 :
90 : protected:
91 1984 : ~TableDataHandler() {}
92 : };
93 :
94 : /**
95 : The table manager.
96 :
97 : This class gets forwarded events from the tokenizer. It gathers the
98 : table data and after ending the table generates events for the
99 : table structure. The events have to be handles by a TableDataHandler.
100 :
101 : */
102 : class TableManager
103 : {
104 : class TableManagerState
105 : {
106 : /**
107 : properties at the current point in document
108 : */
109 : TablePropertyMapPtr mpProps;
110 :
111 : /**
112 : properties of the current cell
113 : */
114 : TablePropertyMapPtr mpCellProps;
115 :
116 : /**
117 : properties of the current row
118 : */
119 : TablePropertyMapPtr mpRowProps;
120 :
121 : /**
122 : properties of the current table
123 : */
124 : std::stack<TablePropertyMapPtr> mTableProps;
125 :
126 : /**
127 : true if at the end of a row
128 : */
129 : bool mbRowEnd;
130 :
131 : /**
132 : true when in a cell
133 : */
134 : bool mbInCell;
135 :
136 : /**
137 : true when at the end of a cell
138 : */
139 : bool mbCellEnd;
140 :
141 : public:
142 : /**
143 : Constructor
144 : */
145 4834 : TableManagerState()
146 4834 : : mbRowEnd(false), mbInCell(false), mbCellEnd(false)
147 : {
148 4834 : }
149 :
150 4834 : virtual ~TableManagerState()
151 4834 : {
152 4834 : }
153 :
154 5471 : void startLevel()
155 : {
156 5471 : TablePropertyMapPtr pProps;
157 5471 : mTableProps.push(pProps);
158 5471 : }
159 :
160 5439 : void endLevel()
161 : {
162 5439 : mTableProps.pop();
163 5439 : }
164 :
165 : /**
166 : Reset to initial state at beginning of row.
167 : */
168 32569 : void resetCellSpecifics()
169 : {
170 32569 : mbRowEnd = false;
171 32569 : mbInCell = false;
172 32569 : mbCellEnd = false;
173 32569 : }
174 :
175 : void resetProps()
176 : {
177 : mpProps.reset();
178 : }
179 :
180 : void setProps(TablePropertyMapPtr pProps)
181 : {
182 : mpProps = pProps;
183 : }
184 :
185 : TablePropertyMapPtr getProps()
186 : {
187 : return mpProps;
188 : }
189 :
190 12446 : void resetCellProps()
191 : {
192 12446 : mpCellProps.reset();
193 12446 : }
194 :
195 6327 : void setCellProps(TablePropertyMapPtr pProps)
196 : {
197 6327 : mpCellProps = pProps;
198 6327 : }
199 :
200 41814 : TablePropertyMapPtr getCellProps()
201 : {
202 41814 : return mpCellProps;
203 : }
204 :
205 2978 : void resetRowProps()
206 : {
207 2978 : mpRowProps.reset();
208 2978 : }
209 :
210 2941 : void setRowProps(TablePropertyMapPtr pProps)
211 : {
212 2941 : mpRowProps = pProps;
213 2941 : }
214 :
215 9763 : TablePropertyMapPtr getRowProps()
216 : {
217 9763 : return mpRowProps;
218 : }
219 :
220 5439 : void resetTableProps()
221 : {
222 5439 : if (mTableProps.size() > 0)
223 5439 : mTableProps.top().reset();
224 5439 : }
225 :
226 624 : void setTableProps(TablePropertyMapPtr pProps)
227 : {
228 624 : if (mTableProps.size() > 0)
229 624 : mTableProps.top() = pProps;
230 624 : }
231 :
232 13125 : TablePropertyMapPtr getTableProps()
233 : {
234 13125 : TablePropertyMapPtr pResult;
235 :
236 13125 : if (mTableProps.size() > 0)
237 13125 : pResult = mTableProps.top();
238 :
239 13125 : return pResult;
240 : }
241 :
242 25217 : void setInCell(bool bInCell)
243 : {
244 25217 : mbInCell = bInCell;
245 25217 : }
246 :
247 38343 : bool isInCell() const
248 : {
249 38343 : return mbInCell;
250 : }
251 :
252 13177 : void setCellEnd(bool bCellEnd)
253 : {
254 13177 : mbCellEnd = bCellEnd;
255 13177 : }
256 :
257 9468 : bool isCellEnd() const
258 : {
259 9468 : return mbCellEnd;
260 : }
261 :
262 9231 : void setRowEnd(bool bRowEnd)
263 : {
264 9231 : mbRowEnd = bRowEnd;
265 9231 : }
266 :
267 93165 : bool isRowEnd() const
268 : {
269 93165 : return mbRowEnd;
270 : }
271 : };
272 :
273 : /**
274 : handle for the current position in document
275 : */
276 : css::uno::Reference<css::text::XTextRange> mCurHandle;
277 :
278 : TableManagerState mState;
279 :
280 : protected:
281 : TablePropertyMapPtr getProps()
282 : {
283 : return mState.getProps();
284 : }
285 :
286 : void setProps(TablePropertyMapPtr pProps)
287 : {
288 : mState.setProps(pProps);
289 : }
290 :
291 : void resetProps()
292 : {
293 : mState.resetProps();
294 : }
295 :
296 41814 : TablePropertyMapPtr getCellProps()
297 : {
298 41814 : return mState.getCellProps();
299 : }
300 :
301 6327 : void setCellProps(TablePropertyMapPtr pProps)
302 : {
303 6327 : mState.setCellProps(pProps);
304 6327 : }
305 :
306 12446 : void resetCellProps()
307 : {
308 12446 : mState.resetCellProps();
309 12446 : }
310 :
311 9763 : TablePropertyMapPtr getRowProps()
312 : {
313 9763 : return mState.getRowProps();
314 : }
315 :
316 2941 : void setRowProps(TablePropertyMapPtr pProps)
317 : {
318 2941 : mState.setRowProps(pProps);
319 2941 : }
320 :
321 2978 : void resetRowProps()
322 : {
323 2978 : mState.resetRowProps();
324 2978 : }
325 :
326 25217 : void setInCell(bool bInCell)
327 : {
328 25217 : mState.setInCell(bInCell);
329 25217 : }
330 :
331 38343 : bool isInCell() const
332 : {
333 38343 : return mState.isInCell();
334 : }
335 :
336 13177 : void setCellEnd(bool bCellEnd)
337 : {
338 13177 : mState.setCellEnd(bCellEnd);
339 13177 : }
340 :
341 9468 : bool isCellEnd() const
342 : {
343 9468 : return mState.isCellEnd();
344 : }
345 :
346 9231 : void setRowEnd(bool bRowEnd)
347 : {
348 9231 : mState.setRowEnd(bRowEnd);
349 9231 : }
350 :
351 93165 : bool isRowEnd() const
352 : {
353 93165 : return mState.isRowEnd();
354 : }
355 :
356 13125 : TablePropertyMapPtr getTableProps()
357 : {
358 13125 : return mState.getTableProps();
359 : }
360 :
361 624 : void setTableProps(TablePropertyMapPtr pProps)
362 : {
363 624 : mState.setTableProps(pProps);
364 624 : }
365 :
366 5439 : void resetTableProps()
367 : {
368 5439 : mState.resetTableProps();
369 5439 : }
370 :
371 17126 : css::uno::Reference<css::text::XTextRange> getHandle()
372 : {
373 17126 : return mCurHandle;
374 : }
375 :
376 27623 : void setHandle(const css::uno::Reference<css::text::XTextRange>& rHandle)
377 : {
378 27623 : mCurHandle = rHandle;
379 27623 : }
380 :
381 : private:
382 : typedef std::shared_ptr< css::uno::Reference<css::text::XTextRange> > T_p;
383 :
384 : /**
385 : depth of the current cell
386 : */
387 : sal_uInt32 mnTableDepthNew;
388 :
389 : /**
390 : depth of the previous cell
391 : */
392 : sal_uInt32 mnTableDepth;
393 :
394 : /**
395 : stack of table data
396 :
397 : for each level of nested tables there is one frame in the stack
398 : */
399 : std::stack<TableData::Pointer_t> mTableDataStack;
400 : RowData::Pointer_t mpUnfinishedRow;
401 : bool mbKeepUnfinishedRow;
402 :
403 : /**
404 : handler for resolveCurrentTable
405 : */
406 : TableDataHandler::Pointer_t mpTableDataHandler;
407 :
408 : /**
409 : Set flag which indicates the current handle is in a cell.
410 : */
411 : void inCell();
412 :
413 : /**
414 : Set flag which indicate the current handle is at the end of a cell.
415 : */
416 : void endCell();
417 :
418 : /**
419 : Set the table depth of the current cell.
420 :
421 : @param nDepth the cell depth
422 : */
423 : void cellDepth(sal_uInt32 nDepth);
424 :
425 : /**
426 : Set flag indication the current handle is at the end of a row.
427 : */
428 : void endRow();
429 :
430 : /**
431 : Resolve the current table to the TableDataHandler.
432 : */
433 : void resolveCurrentTable();
434 :
435 : /**
436 : Open a cell at current level.
437 : */
438 :
439 : void openCell(const css::uno::Reference<css::text::XTextRange>& handle, TablePropertyMapPtr pProps);
440 :
441 : /**
442 : Close a cell at current level.
443 : */
444 : void closeCell(const css::uno::Reference<css::text::XTextRange>& handle);
445 :
446 : /**
447 : Ensure a cell is open at the current level.
448 : */
449 : void ensureOpenCell(TablePropertyMapPtr pProps);
450 :
451 : protected:
452 :
453 : /**
454 : Return current table depth.
455 : */
456 : sal_uInt32 getTableDepthNew() { return mnTableDepthNew; }
457 :
458 : /**
459 : Return the current table difference, i.e. 1 if we are in the first cell of a new table, etc.
460 : */
461 7929 : sal_uInt32 getTableDepthDifference() { return mnTableDepthNew - mnTableDepth; }
462 :
463 : /**
464 : Action to be carried out at the end of the last paragraph of a
465 : cell.
466 : */
467 : virtual void endOfCellAction();
468 :
469 : /**
470 : Action to be carried out at the end of the "table row"
471 : paragraph.
472 : */
473 : virtual void endOfRowAction();
474 : /** let the derived class clear their table related data
475 : */
476 : virtual void clearData();
477 :
478 : /** Should we keep the unfinished row in endLevel to initialize the table
479 : data in the following startLevel.
480 : */
481 10 : void setKeepUnfinishedRow(bool bKeep)
482 : {
483 10 : mbKeepUnfinishedRow = bKeep;
484 10 : }
485 :
486 :
487 : public:
488 : TableManager();
489 4834 : virtual ~TableManager(){}
490 :
491 : /**
492 : Set handler for resolveCurrentTable.
493 :
494 : @param pTableDataHandler the handler
495 : */
496 : void setHandler(TableDataHandler::Pointer_t pTableDataHandler);
497 :
498 : /**
499 : Set the current handle.
500 :
501 : @param rHandle the handle
502 : */
503 : void handle(const css::uno::Reference<css::text::XTextRange>& rHandle);
504 :
505 : /**
506 : Start a new table level.
507 :
508 : A new context is pushed onto the table data stack,
509 : */
510 : virtual void startLevel();
511 :
512 : /**
513 : End a table level.
514 :
515 : The current table is resolved and the context is popped from
516 : the stack.
517 : */
518 : virtual void endLevel();
519 :
520 : /**
521 : * Signal that the next paragraph definitely won't be part of any table.
522 : */
523 1419 : void endTable()
524 : {
525 1419 : setRowEnd(false);
526 1419 : }
527 :
528 : /**
529 : Tells whether a table has been started or not
530 : */
531 : bool isInTable();
532 :
533 : /**
534 : Handle the start of a paragraph group.
535 : */
536 : void startParagraphGroup();
537 :
538 : /**
539 : Handle the end of a paragraph group.
540 : */
541 : void endParagraphGroup();
542 :
543 : /**
544 : Handle an SPRM at current handle.
545 :
546 : @param rSprm the SPRM
547 : */
548 : virtual bool sprm(Sprm & rSprm);
549 :
550 : /**
551 : Handle occurrence of character 0x7.
552 : */
553 : void handle0x7();
554 :
555 : /**
556 : Handle 8 bit text at current handle.
557 :
558 : @param data array of characters
559 : @param len number of characters to handle
560 : */
561 : void text(const sal_uInt8 * data, size_t len);
562 :
563 : /**
564 : Handle 16 bit text at current handle.
565 :
566 : @param data array of characters
567 : @param len number of characters to handle
568 : */
569 : void utext(const sal_uInt8 * data, size_t len);
570 :
571 : /**
572 : Handle properties of the current cell.
573 :
574 : @param pProps the properties
575 : */
576 : virtual void cellProps(TablePropertyMapPtr pProps);
577 :
578 : /**
579 : Handle properties of a certain cell in the current row.
580 :
581 : @paran i index of the cell in the current row
582 : @param pProps the properties
583 : */
584 : virtual void cellPropsByCell(unsigned int i, TablePropertyMapPtr pProps);
585 :
586 : /**
587 : Handle properties of the current row.
588 :
589 : @param pProps the properties
590 : */
591 : virtual void insertRowProps(TablePropertyMapPtr pProps);
592 :
593 : /**
594 : Handle properties of the current table.
595 :
596 : @param pProps the properties
597 : */
598 : virtual void insertTableProps(TablePropertyMapPtr pProps);
599 :
600 : /**
601 : Return if table manager has detected paragraph to ignore.
602 :
603 : If this function returns true the current paragraph contains
604 : only control information, e.g. end of row.
605 : */
606 : bool isIgnore() const;
607 :
608 :
609 : };
610 :
611 : }
612 :
613 : }
614 :
615 : #endif // INCLUDED_WRITERFILTER_INC_RESOURCEMODEL_TABLEMANAGER_HXX
616 :
617 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|