Avoid potential negative array index access to cached text.
[LibreOffice.git] / writerfilter / source / dmapper / TableManager.hxx
blobfbace0cfe10bb167755d0028371896723036f7b4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include <memory>
23 #include <stack>
25 #include "PropertyMap.hxx"
26 #include "TableData.hxx"
28 #include <dmapper/resourcemodel.hxx>
30 namespace writerfilter::dmapper
33 class DomainMapperTableHandler;
35 /**
36 The table manager.
38 This class gets forwarded events from the tokenizer. It gathers the
39 table data and after ending the table generates events for the
40 table structure. The events have to be handles by a TableDataHandler.
43 class TableManager : public virtual SvRefBase
45 class TableManagerState final
47 /**
48 properties of the current cell
50 TablePropertyMapPtr mpCellProps;
52 /**
53 properties of the current row
55 TablePropertyMapPtr mpRowProps;
57 /**
58 table exception properties of the current row
60 TablePropertyMapPtr mpTableExceptionProps;
62 /**
63 properties of the current table
65 std::stack<TablePropertyMapPtr> mTableProps;
67 /**
68 true if at the end of a row
70 bool mbRowEnd;
72 /**
73 true when in a cell
75 bool mbInCell;
77 /**
78 true when at the end of a cell
80 bool mbCellEnd;
82 public:
83 /**
84 Constructor
86 TableManagerState()
87 : mbRowEnd(false), mbInCell(false), mbCellEnd(false)
91 void startLevel()
93 TablePropertyMapPtr pProps;
94 mTableProps.push(pProps);
97 void endLevel()
99 mTableProps.pop();
103 Reset to initial state at beginning of row.
105 void resetCellSpecifics()
107 mbRowEnd = false;
108 mbInCell = false;
109 mbCellEnd = false;
112 void resetCellProps()
114 // copy tblPrEx table exception properties, if they exist
115 if (getTableExceptionProps().is())
117 mpCellProps = new TablePropertyMap;
118 mpCellProps->InsertProps(getTableExceptionProps().get());
120 else
121 mpCellProps.clear();
124 void setCellProps(const TablePropertyMapPtr& pProps)
126 mpCellProps = pProps;
129 const TablePropertyMapPtr& getCellProps() const
131 return mpCellProps;
134 void resetRowProps()
136 // reset also table exception and
137 // its copy set by the previous resetCellProps()
138 mpTableExceptionProps.clear();
139 resetCellProps();
140 mpRowProps.clear();
143 void setRowProps(TablePropertyMapPtr pProps)
145 mpRowProps = pProps;
148 const TablePropertyMapPtr& getRowProps() const
150 return mpRowProps;
153 void setTableExceptionProps(const TablePropertyMapPtr& pProps)
155 mpTableExceptionProps = pProps;
156 // set table exception properties of the first cell
157 resetCellProps();
160 const TablePropertyMapPtr& getTableExceptionProps() const
162 return mpTableExceptionProps;
165 void resetTableProps()
167 if (mTableProps.size() > 0)
168 mTableProps.top().clear();
171 void setTableProps(TablePropertyMapPtr pProps)
173 if (mTableProps.size() > 0)
174 mTableProps.top() = pProps;
177 TablePropertyMapPtr getTableProps()
179 TablePropertyMapPtr pResult;
181 if (mTableProps.size() > 0)
182 pResult = mTableProps.top();
184 return pResult;
187 void setInCell(bool bInCell)
189 mbInCell = bInCell;
192 bool isInCell() const
194 return mbInCell;
197 void setCellEnd(bool bCellEnd)
199 mbCellEnd = bCellEnd;
202 bool isCellEnd() const
204 return mbCellEnd;
207 void setRowEnd(bool bRowEnd)
209 mbRowEnd = bRowEnd;
212 bool isRowEnd() const
214 return mbRowEnd;
219 handle for the current position in document
221 css::uno::Reference<css::text::XTextRange> mCurHandle;
223 TableManagerState mState;
225 protected:
226 TablePropertyMapPtr const & getCellProps() const
228 return mState.getCellProps();
231 public:
232 TablePropertyMapPtr const & getRowProps() const
234 return mState.getRowProps();
237 TablePropertyMapPtr const & getTableExceptionProps() const
239 return mState.getTableExceptionProps();
242 protected:
243 void setInCell(bool bInCell)
245 mState.setInCell(bInCell);
248 bool isInCell() const
250 return mState.isInCell();
253 void setCellEnd(bool bCellEnd)
255 mState.setCellEnd(bCellEnd);
258 void setRowEnd(bool bRowEnd)
260 mState.setRowEnd(bRowEnd);
263 bool isRowEnd() const
265 return mState.isRowEnd();
268 TablePropertyMapPtr getTableProps()
270 return mState.getTableProps();
273 const css::uno::Reference<css::text::XTextRange>& getHandle() const
275 return mCurHandle;
278 void setHandle(const css::uno::Reference<css::text::XTextRange>& rHandle)
280 mCurHandle = rHandle;
283 private:
284 typedef tools::SvRef< css::uno::Reference<css::text::XTextRange> > T_p;
287 depth of the current cell
289 sal_uInt32 mnTableDepthNew;
292 depth of the previous cell
294 sal_uInt32 mnTableDepth;
297 stack of table data
299 for each level of nested tables there is one frame in the stack
301 std::vector<TableData::Pointer_t> mTableDataStack;
302 RowData::Pointer_t mpUnfinishedRow;
303 bool mbKeepUnfinishedRow;
305 bool m_bCellLastParaAfterAutospacing;
308 handler for resolveCurrentTable
310 tools::SvRef<DomainMapperTableHandler> mpTableDataHandler;
313 Set flag which indicates the current handle is in a cell.
315 void inCell();
318 Set flag which indicate the current handle is at the end of a cell.
320 void endCell();
323 Set the table depth of the current cell.
325 @param nDepth the cell depth
327 void cellDepth(sal_uInt32 nDepth);
330 Set flag indication the current handle is at the end of a row.
332 void endRow();
335 Resolve the current table to the TableDataHandler.
337 void resolveCurrentTable();
340 Open a cell at current level.
343 void openCell(const css::uno::Reference<css::text::XTextRange>& rHandle, const TablePropertyMapPtr& pProps);
346 Close a cell at current level.
348 void closeCell(const css::uno::Reference<css::text::XTextRange>& rHandle);
351 Ensure a cell is open at the current level.
353 void ensureOpenCell(const TablePropertyMapPtr& pProps);
355 protected:
357 Return the current table difference, i.e. 1 if we are in the first cell of a new table, etc.
359 sal_Int32 getTableDepthDifference() const { return mnTableDepthNew - mnTableDepth; }
361 sal_uInt32 getTableDepth() const { return mnTableDepthNew; }
364 Action to be carried out at the end of the last paragraph of a
365 cell.
367 virtual void endOfCellAction();
370 Action to be carried out at the end of the "table row"
371 paragraph.
373 virtual void endOfRowAction();
374 /** let the derived class clear their table related data
376 virtual void clearData();
378 /** Should we keep the unfinished row in endLevel to initialize the table
379 data in the following startLevel.
381 void setKeepUnfinishedRow(bool bKeep)
383 mbKeepUnfinishedRow = bKeep;
387 public:
388 TableManager();
389 ~TableManager();
392 Set handler for resolveCurrentTable.
394 @param pTableDataHandler the handler
396 void setHandler(const tools::SvRef<DomainMapperTableHandler>& pTableDataHandler);
399 Set the current handle.
401 @param rHandle the handle
403 void handle(const css::uno::Reference<css::text::XTextRange>& rHandle);
406 Start a new table level.
408 A new context is pushed onto the table data stack,
410 virtual void startLevel();
413 End a table level.
415 The current table is resolved and the context is popped from
416 the stack.
418 virtual void endLevel();
421 * Signal that the next paragraph definitely won't be part of any table.
423 void endTable()
425 setRowEnd(false);
429 Tells whether a table has been started or not
431 bool isInTable();
434 Handle the start of a paragraph group.
436 void startParagraphGroup();
439 Handle the end of a paragraph group.
441 void endParagraphGroup();
444 Handle an SPRM at current handle.
446 @param rSprm the SPRM
448 virtual bool sprm(Sprm & rSprm);
451 Handle occurrence of character 0x7.
453 void handle0x7();
456 Handle 8 bit text at current handle.
458 @param data array of characters
459 @param len number of characters to handle
461 void text(const sal_uInt8 * data, size_t len);
464 Handle 16 bit text at current handle.
466 @param data array of characters
467 @param len number of characters to handle
469 void utext(const sal_Unicode * data, size_t len);
472 Handle properties of the current cell.
474 @param pProps the properties
476 virtual void cellProps(const TablePropertyMapPtr& pProps);
479 Handle properties of the current row.
481 @param pProps the properties
483 virtual void insertRowProps(const TablePropertyMapPtr& pProps);
486 Handle table exception properties of the current row.
488 @param pProps the properties
490 virtual void tableExceptionProps(const TablePropertyMapPtr& pProps);
493 Handle properties of the current table.
495 @param pProps the properties
497 virtual void insertTableProps(const TablePropertyMapPtr& pProps);
500 Return if table manager has detected paragraph to ignore.
502 If this function returns true the current paragraph contains
503 only control information, e.g. end of row.
505 bool isIgnore() const;
507 sal_uInt32 getGridBefore(sal_uInt32 nRow);
508 sal_uInt32 getCurrentGridBefore();
509 void setCurrentGridBefore( sal_uInt32 nSkipGrids );
510 sal_uInt32 getGridAfter(sal_uInt32 nRow);
511 void setCurrentGridAfter( sal_uInt32 nSkipGrids );
512 std::vector<sal_uInt32> getCurrentGridSpans();
513 void setCurrentGridSpan( sal_uInt32 nGridSpan, bool bFirstCell = false );
514 /// Given a zero-based row/cell, return the zero-based grid it belongs to, or SAL_MAX_UINT16 for invalid.
515 sal_uInt32 findColumn( const sal_uInt32 nRow, const sal_uInt32 nCell );
516 /// Given a zero-based row/col, return the zero-based cell describing that grid, or SAL_MAX_UINT16 for invalid.
517 sal_uInt32 findColumnCell( const sal_uInt32 nRow, const sal_uInt32 nCol );
519 void setCellLastParaAfterAutospacing(bool bIsAfterAutospacing);
520 bool isCellLastParaAfterAutospacing() const {return m_bCellLastParaAfterAutospacing;}
527 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */