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 <memory> 24 #include <stack> 25 26 #include "PropertyMap.hxx" 27 #include "TableData.hxx" 28 29 namespace writerfilter 30 { 31 namespace dmapper 32 { 33 34 class DomainMapperTableHandler; 35 36 /** 37 The table manager. 38 39 This class gets forwarded events from the tokenizer. It gathers the 40 table data and after ending the table generates events for the 41 table structure. The events have to be handles by a TableDataHandler. 42 43 */ 44 class TableManager : public virtual SvRefBase 45 { 46 class TableManagerState final 47 { 48 /** 49 properties of the current cell 50 */ 51 TablePropertyMapPtr mpCellProps; 52 53 /** 54 properties of the current row 55 */ 56 TablePropertyMapPtr mpRowProps; 57 58 /** 59 properties of the current table 60 */ 61 std::stack<TablePropertyMapPtr> mTableProps; 62 63 /** 64 true if at the end of a row 65 */ 66 bool mbRowEnd; 67 68 /** 69 true when in a cell 70 */ 71 bool mbInCell; 72 73 /** 74 true when at the end of a cell 75 */ 76 bool mbCellEnd; 77 78 public: 79 /** 80 Constructor 81 */ TableManagerState()82 TableManagerState() 83 : mbRowEnd(false), mbInCell(false), mbCellEnd(false) 84 { 85 } 86 startLevel()87 void startLevel() 88 { 89 TablePropertyMapPtr pProps; 90 mTableProps.push(pProps); 91 } 92 endLevel()93 void endLevel() 94 { 95 mTableProps.pop(); 96 } 97 98 /** 99 Reset to initial state at beginning of row. 100 */ resetCellSpecifics()101 void resetCellSpecifics() 102 { 103 mbRowEnd = false; 104 mbInCell = false; 105 mbCellEnd = false; 106 } 107 resetCellProps()108 void resetCellProps() 109 { 110 mpCellProps.clear(); 111 } 112 setCellProps(TablePropertyMapPtr pProps)113 void setCellProps(TablePropertyMapPtr pProps) 114 { 115 mpCellProps = pProps; 116 } 117 getCellProps() const118 const TablePropertyMapPtr& getCellProps() const 119 { 120 return mpCellProps; 121 } 122 resetRowProps()123 void resetRowProps() 124 { 125 mpRowProps.clear(); 126 } 127 setRowProps(TablePropertyMapPtr pProps)128 void setRowProps(TablePropertyMapPtr pProps) 129 { 130 mpRowProps = pProps; 131 } 132 getRowProps() const133 const TablePropertyMapPtr& getRowProps() const 134 { 135 return mpRowProps; 136 } 137 resetTableProps()138 void resetTableProps() 139 { 140 if (mTableProps.size() > 0) 141 mTableProps.top().clear(); 142 } 143 setTableProps(TablePropertyMapPtr pProps)144 void setTableProps(TablePropertyMapPtr pProps) 145 { 146 if (mTableProps.size() > 0) 147 mTableProps.top() = pProps; 148 } 149 getTableProps()150 TablePropertyMapPtr getTableProps() 151 { 152 TablePropertyMapPtr pResult; 153 154 if (mTableProps.size() > 0) 155 pResult = mTableProps.top(); 156 157 return pResult; 158 } 159 setInCell(bool bInCell)160 void setInCell(bool bInCell) 161 { 162 mbInCell = bInCell; 163 } 164 isInCell() const165 bool isInCell() const 166 { 167 return mbInCell; 168 } 169 setCellEnd(bool bCellEnd)170 void setCellEnd(bool bCellEnd) 171 { 172 mbCellEnd = bCellEnd; 173 } 174 isCellEnd() const175 bool isCellEnd() const 176 { 177 return mbCellEnd; 178 } 179 setRowEnd(bool bRowEnd)180 void setRowEnd(bool bRowEnd) 181 { 182 mbRowEnd = bRowEnd; 183 } 184 isRowEnd() const185 bool isRowEnd() const 186 { 187 return mbRowEnd; 188 } 189 }; 190 191 /** 192 handle for the current position in document 193 */ 194 css::uno::Reference<css::text::XTextRange> mCurHandle; 195 196 TableManagerState mState; 197 198 protected: getCellProps() const199 TablePropertyMapPtr const & getCellProps() const 200 { 201 return mState.getCellProps(); 202 } 203 204 public: getRowProps() const205 TablePropertyMapPtr const & getRowProps() const 206 { 207 return mState.getRowProps(); 208 } 209 210 protected: setInCell(bool bInCell)211 void setInCell(bool bInCell) 212 { 213 mState.setInCell(bInCell); 214 } 215 isInCell() const216 bool isInCell() const 217 { 218 return mState.isInCell(); 219 } 220 setCellEnd(bool bCellEnd)221 void setCellEnd(bool bCellEnd) 222 { 223 mState.setCellEnd(bCellEnd); 224 } 225 setRowEnd(bool bRowEnd)226 void setRowEnd(bool bRowEnd) 227 { 228 mState.setRowEnd(bRowEnd); 229 } 230 isRowEnd() const231 bool isRowEnd() const 232 { 233 return mState.isRowEnd(); 234 } 235 getTableProps()236 TablePropertyMapPtr getTableProps() 237 { 238 return mState.getTableProps(); 239 } 240 getHandle() const241 const css::uno::Reference<css::text::XTextRange>& getHandle() const 242 { 243 return mCurHandle; 244 } 245 setHandle(const css::uno::Reference<css::text::XTextRange> & rHandle)246 void setHandle(const css::uno::Reference<css::text::XTextRange>& rHandle) 247 { 248 mCurHandle = rHandle; 249 } 250 251 private: 252 typedef tools::SvRef< css::uno::Reference<css::text::XTextRange> > T_p; 253 254 /** 255 depth of the current cell 256 */ 257 sal_uInt32 mnTableDepthNew; 258 259 /** 260 depth of the previous cell 261 */ 262 sal_uInt32 mnTableDepth; 263 264 /** 265 stack of table data 266 267 for each level of nested tables there is one frame in the stack 268 */ 269 std::stack<TableData::Pointer_t> mTableDataStack; 270 RowData::Pointer_t mpUnfinishedRow; 271 bool mbKeepUnfinishedRow; 272 /// If this is a nested table, does it start at cell start? 273 bool m_bTableStartsAtCellStart; 274 275 bool m_bCellLastParaAfterAutospacing; 276 277 /** 278 handler for resolveCurrentTable 279 */ 280 tools::SvRef<DomainMapperTableHandler> mpTableDataHandler; 281 282 /** 283 Set flag which indicates the current handle is in a cell. 284 */ 285 void inCell(); 286 287 /** 288 Set flag which indicate the current handle is at the end of a cell. 289 */ 290 void endCell(); 291 292 /** 293 Set the table depth of the current cell. 294 295 @param nDepth the cell depth 296 */ 297 void cellDepth(sal_uInt32 nDepth); 298 299 /** 300 Set flag indication the current handle is at the end of a row. 301 */ 302 void endRow(); 303 304 /** 305 Resolve the current table to the TableDataHandler. 306 */ 307 void resolveCurrentTable(); 308 309 /** 310 Open a cell at current level. 311 */ 312 313 void openCell(const css::uno::Reference<css::text::XTextRange>& rHandle, const TablePropertyMapPtr& pProps); 314 315 /** 316 Close a cell at current level. 317 */ 318 void closeCell(const css::uno::Reference<css::text::XTextRange>& rHandle); 319 320 /** 321 Ensure a cell is open at the current level. 322 */ 323 void ensureOpenCell(const TablePropertyMapPtr& pProps); 324 325 protected: 326 /** 327 Return the current table difference, i.e. 1 if we are in the first cell of a new table, etc. 328 */ getTableDepthDifference() const329 sal_uInt32 getTableDepthDifference() const { return mnTableDepthNew - mnTableDepth; } 330 getTableDepth() const331 sal_uInt32 getTableDepth() const { return mnTableDepthNew; } 332 333 /** 334 Action to be carried out at the end of the last paragraph of a 335 cell. 336 */ 337 virtual void endOfCellAction(); 338 339 /** 340 Action to be carried out at the end of the "table row" 341 paragraph. 342 */ 343 virtual void endOfRowAction(); 344 /** let the derived class clear their table related data 345 */ 346 virtual void clearData(); 347 348 /** Should we keep the unfinished row in endLevel to initialize the table 349 data in the following startLevel. 350 */ setKeepUnfinishedRow(bool bKeep)351 void setKeepUnfinishedRow(bool bKeep) 352 { 353 mbKeepUnfinishedRow = bKeep; 354 } 355 356 357 public: 358 TableManager(); 359 ~TableManager(); 360 361 /** 362 Set handler for resolveCurrentTable. 363 364 @param pTableDataHandler the handler 365 */ 366 void setHandler(const tools::SvRef<DomainMapperTableHandler>& pTableDataHandler); 367 368 /** 369 Set the current handle. 370 371 @param rHandle the handle 372 */ 373 void handle(const css::uno::Reference<css::text::XTextRange>& rHandle); 374 375 /** 376 Start a new table level. 377 378 A new context is pushed onto the table data stack, 379 */ 380 virtual void startLevel(); 381 382 /** 383 End a table level. 384 385 The current table is resolved and the context is popped from 386 the stack. 387 */ 388 virtual void endLevel(); 389 390 /** 391 * Signal that the next paragraph definitely won't be part of any table. 392 */ endTable()393 void endTable() 394 { 395 setRowEnd(false); 396 } 397 398 /** 399 Tells whether a table has been started or not 400 */ 401 bool isInTable(); 402 403 /** 404 Handle the start of a paragraph group. 405 */ 406 void startParagraphGroup(); 407 408 /** 409 Handle the end of a paragraph group. 410 */ 411 void endParagraphGroup(); 412 413 /** 414 Handle an SPRM at current handle. 415 416 @param rSprm the SPRM 417 */ 418 virtual bool sprm(Sprm & rSprm); 419 420 /** 421 Handle occurrence of character 0x7. 422 */ 423 void handle0x7(); 424 425 /** 426 Handle 8 bit text at current handle. 427 428 @param data array of characters 429 @param len number of characters to handle 430 */ 431 void text(const sal_uInt8 * data, size_t len); 432 433 /** 434 Handle 16 bit text at current handle. 435 436 @param data array of characters 437 @param len number of characters to handle 438 */ 439 void utext(const sal_uInt8 * data, size_t len); 440 441 /** 442 Handle properties of the current cell. 443 444 @param pProps the properties 445 */ 446 virtual void cellProps(const TablePropertyMapPtr& pProps); 447 448 /** 449 Handle properties of the current row. 450 451 @param pProps the properties 452 */ 453 virtual void insertRowProps(const TablePropertyMapPtr& pProps); 454 455 /** 456 Handle properties of the current table. 457 458 @param pProps the properties 459 */ 460 virtual void insertTableProps(const TablePropertyMapPtr& pProps); 461 462 /** 463 Return if table manager has detected paragraph to ignore. 464 465 If this function returns true the current paragraph contains 466 only control information, e.g. end of row. 467 */ 468 bool isIgnore() const; 469 470 471 void setTableStartsAtCellStart(bool bTableStartsAtCellStart); 472 void setCellLastParaAfterAutospacing(bool bIsAfterAutospacing); isCellLastParaAfterAutospacing() const473 bool isCellLastParaAfterAutospacing() const {return m_bCellLastParaAfterAutospacing;} 474 }; 475 476 } 477 478 } 479 480 #endif // INCLUDED_WRITERFILTER_INC_RESOURCEMODEL_TABLEMANAGER_HXX 481 482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 483