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 #ifndef INCLUDED_SW_INC_SWTABLE_HXX 20 #define INCLUDED_SW_INC_SWTABLE_HXX 21 22 #include <tools/ref.hxx> 23 #include "tblenum.hxx" 24 #include "swtypes.hxx" 25 #include "calbck.hxx" 26 #include "swrect.hxx" 27 #include "swtblfmt.hxx" 28 #include "docary.hxx" 29 #include "nodeoffset.hxx" 30 31 #include <memory> 32 #include <vector> 33 #include <algorithm> 34 #include <o3tl/sorted_vector.hxx> 35 #include <optional> 36 37 class SwStartNode; 38 class SwFormat; 39 class SwHTMLTableLayout; 40 class SwTableLine; 41 class SwTableBox; 42 class SwTableNode; 43 class SwTabCols; 44 class SwDoc; 45 class SwSelBoxes; 46 class SwTableCalcPara; 47 struct SwPosition; 48 class SwNodeIndex; 49 class SwNode; 50 class SwUndoTableMerge; 51 class SwUndo; 52 class SwPaM; 53 class SwUndoTableCpyTable; 54 class SwBoxSelection; 55 struct SwSaveRowSpan; 56 struct Parm; 57 class SwServerObject; 58 class SwHistory; 59 60 void sw_GetTableBoxColStr( sal_uInt16 nCol, OUString& rNm ); 61 62 class SwTableLines 63 { 64 std::vector<SwTableLine*> m_vLines; 65 66 public: 67 typedef std::vector<SwTableLine*>::size_type size_type; 68 typedef std::vector<SwTableLine*>::iterator iterator; 69 typedef std::vector<SwTableLine*>::const_iterator const_iterator; 70 71 // free's any remaining child objects 72 ~SwTableLines(); 73 empty() const74 bool empty() const { return m_vLines.empty(); } size() const75 size_type size() const { return m_vLines.size(); } begin()76 iterator begin() { return m_vLines.begin(); } begin() const77 const_iterator begin() const { return m_vLines.begin(); } end()78 iterator end() { return m_vLines.end(); } end() const79 const_iterator end() const { return m_vLines.end(); } front() const80 SwTableLine* front() const { return m_vLines.front(); } back() const81 SwTableLine* back() const { return m_vLines.back(); } clear()82 void clear() { m_vLines.clear(); } erase(iterator aIt)83 iterator erase( iterator aIt ) { return m_vLines.erase( aIt ); } erase(iterator aFirst,iterator aLast)84 iterator erase( iterator aFirst, iterator aLast ) { return m_vLines.erase( aFirst, aLast ); } insert(iterator aIt,SwTableLine * pLine)85 iterator insert( iterator aIt, SwTableLine* pLine ) { return m_vLines.insert( aIt, pLine ); } 86 template<typename TInputIterator> insert(iterator aIt,TInputIterator aFirst,TInputIterator aLast)87 void insert( iterator aIt, TInputIterator aFirst, TInputIterator aLast ) 88 { 89 m_vLines.insert( aIt, aFirst, aLast ); 90 } push_back(SwTableLine * pLine)91 void push_back( SwTableLine* pLine ) { m_vLines.push_back( pLine ); } reserve(size_type nSize)92 void reserve( size_type nSize ) { m_vLines.reserve( nSize ); } operator [](size_type nPos)93 SwTableLine*& operator[]( size_type nPos ) { return m_vLines[ nPos ]; } operator [](size_type nPos) const94 SwTableLine* operator[]( size_type nPos ) const { return m_vLines[ nPos ]; } 95 96 // return USHRT_MAX if not found, else index of position GetPos(const SwTableLine * pBox) const97 sal_uInt16 GetPos(const SwTableLine* pBox) const 98 { 99 const_iterator it = std::find(begin(), end(), pBox); 100 return it == end() ? USHRT_MAX : it - begin(); 101 } 102 }; 103 104 using SwTableBoxes = std::vector<SwTableBox*>; 105 106 // Save content-bearing box-pointers additionally in a sorted array 107 // (for calculation in table). 108 class SwTableSortBoxes : public o3tl::sorted_vector<SwTableBox*> {}; 109 110 /// SwTable is one table in the document model, containing rows (which contain cells). 111 class SAL_DLLPUBLIC_RTTI SwTable: public SwClient //Client of FrameFormat. 112 { 113 114 protected: 115 SwTableLines m_aLines; 116 SwTableSortBoxes m_TabSortContentBoxes; 117 tools::SvRef<SwServerObject> m_xRefObj; // In case DataServer -> pointer is set. 118 119 std::shared_ptr<SwHTMLTableLayout> m_xHTMLLayout; 120 121 // Usually, the table node of a SwTable can be accessed by getting a box 122 // out of m_TabSortContentBoxes, which know their SwStartNode. But in some rare 123 // cases, we need to know the table node of a SwTable, before the table 124 // boxes have been build (SwTableNode::MakeCopy with tables in tables). 125 SwTableNode* m_pTableNode; 126 127 // Should that be adjustable for every table? 128 TableChgMode m_eTableChgMode; 129 130 sal_uInt16 m_nGraphicsThatResize; // Count of Grfs that initiate a resize of table 131 // at HTML-import. 132 sal_uInt16 m_nRowsToRepeat; // Number of rows to repeat on every page. 133 134 /// Name of the table style to be applied on this table. 135 TableStyleName maTableStyleName; 136 137 bool m_bModifyLocked :1; 138 bool m_bNewModel :1; // false: old SubTableModel; true: new RowSpanModel 139 140 virtual void SwClientNotify(const SwModify&, const SfxHint&) override; 141 142 public: 143 enum SearchType 144 { 145 SEARCH_NONE, // Default: expand to rectangle 146 SEARCH_ROW, // row selection 147 SEARCH_COL // column selection 148 }; 149 150 151 explicit SwTable(); 152 virtual ~SwTable() override; 153 154 // @@@ public copy ctor, but no copy assignment? 155 SwTable( const SwTable& rTable ); // no copy of the lines !! 156 DynCastTable() const157 virtual const SwTable* DynCastTable() const override { return this; } 158 159 private: 160 // @@@ public copy ctor, but no copy assignment? 161 SwTable & operator= (const SwTable &) = delete; 162 bool OldMerge( SwDoc&, const SwSelBoxes&, SwTableBox*, SwUndoTableMerge* ); 163 bool OldSplitRow( SwDoc&, const SwSelBoxes&, sal_uInt16, bool ); 164 bool NewMerge( SwDoc&, const SwSelBoxes&, const SwSelBoxes& rMerged, 165 SwUndoTableMerge* ); 166 bool NewSplitRow( SwDoc&, const SwSelBoxes&, sal_uInt16, bool ); 167 std::optional<SwBoxSelection> CollectBoxSelection( const SwPaM& rPam ) const; 168 void InsertSpannedRow( SwDoc& rDoc, sal_uInt16 nIdx, sal_uInt16 nCnt ); 169 bool InsertRow_( SwDoc&, const SwSelBoxes&, sal_uInt16 nCnt, bool bBehind, bool bInsertDummy ); 170 bool NewInsertCol( SwDoc&, const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool, bool bInsertDummy ); 171 void FindSuperfluousRows_( SwSelBoxes& rBoxes, SwTableLine*, SwTableLine* ); 172 void AdjustWidths( const tools::Long nOld, const tools::Long nNew ); 173 void NewSetTabCols( Parm &rP, const SwTabCols &rNew, const SwTabCols &rOld, 174 const SwTableBox *pStart, bool bCurRowOnly ); 175 void ConvertSubtableBox(sal_uInt16 const nRow, sal_uInt16 const nBox); 176 // Only used for TBL_BOXNAME and TBL_RELBOXNAME for now 177 void UpdateFields(TableFormulaUpdateFlags eFlags); 178 void GatherFormulas(std::vector<SwTableBoxFormula*>& rvFormulas); 179 180 public: GetHTMLTableLayout()181 SwHTMLTableLayout *GetHTMLTableLayout() { return m_xHTMLLayout.get(); } GetHTMLTableLayout() const182 const SwHTMLTableLayout *GetHTMLTableLayout() const { return m_xHTMLLayout.get(); } 183 void SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout> const& r); //Change of property! 184 IncGrfsThatResize()185 sal_uInt16 IncGrfsThatResize() { return ++m_nGraphicsThatResize; } DecGrfsThatResize()186 sal_uInt16 DecGrfsThatResize() { return m_nGraphicsThatResize ? --m_nGraphicsThatResize : 0; } 187 LockModify()188 void LockModify() { m_bModifyLocked = true; } // Must be used always UnlockModify()189 void UnlockModify() { m_bModifyLocked = false;} // in pairs! 190 SetTableModel(bool bNew)191 void SetTableModel( bool bNew ){ m_bNewModel = bNew; } IsNewModel() const192 bool IsNewModel() const { return m_bNewModel; } 193 194 /// Return the table style name of this table. GetTableStyleName() const195 const TableStyleName& GetTableStyleName() const { return maTableStyleName; } 196 197 /// Set the new table style name for this table. SetTableStyleName(const TableStyleName & rName)198 void SetTableStyleName(const TableStyleName& rName) { maTableStyleName = rName; } 199 GetRowsToRepeat() const200 sal_uInt16 GetRowsToRepeat() const { return std::min( o3tl::narrowing<sal_uInt16>(GetTabLines().size()), m_nRowsToRepeat ); } SetRowsToRepeat(sal_uInt16 nNumOfRows)201 void SetRowsToRepeat( sal_uInt16 nNumOfRows ) { m_nRowsToRepeat = nNumOfRows; } 202 203 bool IsHeadline( const SwTableLine& rLine ) const; 204 GetTabLines()205 SwTableLines &GetTabLines() { return m_aLines; } GetTabLines() const206 const SwTableLines &GetTabLines() const { return m_aLines; } 207 GetFrameFormat()208 SwTableFormat* GetFrameFormat() { return static_cast<SwTableFormat*>(GetRegisteredIn()); } GetFrameFormat() const209 SwTableFormat* GetFrameFormat() const { return const_cast<SwTableFormat*>(static_cast<const SwTableFormat*>(GetRegisteredIn())); } 210 211 SW_DLLPUBLIC void GetTabCols( SwTabCols &rToFill, const SwTableBox *pStart, 212 bool bHidden = false, bool bCurRowOnly = false ) const; 213 SW_DLLPUBLIC void SetTabCols( const SwTabCols &rNew, const SwTabCols &rOld, 214 const SwTableBox *pStart, bool bCurRowOnly ); 215 216 // The following functions are for new table model only... 217 void CreateSelection( const SwPaM& rPam, SwSelBoxes& rBoxes, 218 const SearchType eSearchType, bool bProtect ) const; 219 void CreateSelection( const SwNode* pStart, const SwNode* pEnd, 220 SwSelBoxes& rBoxes, const SearchType eSearchType, bool bProtect ) const; 221 void ExpandSelection( SwSelBoxes& rBoxes ) const; 222 // When a table is split into two tables, the row spans which overlaps 223 // the split have to be corrected and stored for undo 224 // SwSavRowSpan is the structure needed by Undo to undo the split operation 225 // CleanUpRowSpan corrects the (top of the) second table and delivers the structure 226 // for Undo 227 std::unique_ptr<SwSaveRowSpan> CleanUpTopRowSpan( sal_uInt16 nSplitLine ); 228 // RestoreRowSpan is called by Undo to restore the old row span values 229 void RestoreRowSpan( const SwSaveRowSpan& ); 230 // CleanUpBottomRowSpan corrects the overhanging row spans at the end of the first table 231 void CleanUpBottomRowSpan( sal_uInt16 nDelLines ); 232 233 // The following functions are "pseudo-virtual", i.e. they are different for old and new table model 234 // It's not allowed to change the table model after the first call of one of these functions. 235 Merge(SwDoc & rDoc,const SwSelBoxes & rBoxes,const SwSelBoxes & rMerged,SwTableBox * pMergeBox,SwUndoTableMerge * pUndo)236 bool Merge( SwDoc& rDoc, const SwSelBoxes& rBoxes, const SwSelBoxes& rMerged, 237 SwTableBox* pMergeBox, SwUndoTableMerge* pUndo ) 238 { 239 return m_bNewModel ? NewMerge( rDoc, rBoxes, rMerged, pUndo ) : 240 OldMerge( rDoc, rBoxes, pMergeBox, pUndo ); 241 } SplitRow(SwDoc & rDoc,const SwSelBoxes & rBoxes,sal_uInt16 nCnt,bool bSameHeight)242 bool SplitRow( SwDoc& rDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt, 243 bool bSameHeight ) 244 { 245 return m_bNewModel ? NewSplitRow( rDoc, rBoxes, nCnt, bSameHeight ) : 246 OldSplitRow( rDoc, rBoxes, nCnt, bSameHeight ); 247 } 248 bool PrepareMerge( const SwPaM& rPam, SwSelBoxes& rBoxes, 249 SwSelBoxes& rMerged, SwTableBox** ppMergeBox, SwUndoTableMerge* pUndo ); 250 void ExpandColumnSelection( SwSelBoxes& rBoxes, tools::Long &rMin, tools::Long &rMax ) const; 251 void PrepareDeleteCol( tools::Long nMin, tools::Long nMax ); 252 253 bool InsertCol( SwDoc&, const SwSelBoxes& rBoxes, 254 sal_uInt16 nCnt, bool bBehind, bool bInsertDummy ); 255 bool InsertRow( SwDoc&, const SwSelBoxes& rBoxes, 256 sal_uInt16 nCnt, bool bBehind, bool bInsertDummy = true ); 257 void PrepareDelBoxes( const SwSelBoxes& rBoxes ); 258 bool DeleteSel( SwDoc&, const SwSelBoxes& rBoxes, const SwSelBoxes* pMerged, 259 SwUndo* pUndo, const bool bDelMakeFrames, const bool bCorrBorder ); 260 bool SplitCol( SwDoc& rDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt ); 261 FindSuperfluousRows(SwSelBoxes & rBoxes)262 void FindSuperfluousRows( SwSelBoxes& rBoxes ) 263 { FindSuperfluousRows_( rBoxes, nullptr, nullptr ); } 264 void CheckRowSpan( SwTableLine* &rpLine, bool bUp ) const; 265 GetTabSortBoxes()266 SwTableSortBoxes& GetTabSortBoxes() { return m_TabSortContentBoxes; } GetTabSortBoxes() const267 const SwTableSortBoxes& GetTabSortBoxes() const { return m_TabSortContentBoxes; } 268 269 // Read 1st number and delete it from string (used by GetTableBox and SwTableField). 270 271 // #i80314# 272 // add 3rd parameter in order to control validation check on <rStr> 273 static sal_uInt16 GetBoxNum( OUString& rStr, 274 bool bFirst = false, 275 const bool bPerformValidCheck = false ); 276 277 // Search content-bearing box with that name. 278 279 // #i80314# 280 // add 2nd parameter in order to control validation check in called method 281 // <GetBoxNum(..)> 282 SW_DLLPUBLIC const SwTableBox* GetTableBox( const OUString& rName, 283 const bool bPerformValidCheck = false ) const; 284 // Copy selected boxes to another document. 285 bool MakeCopy( SwDoc&, const SwPosition&, const SwSelBoxes&, 286 bool bCpyName = false, const TableStyleName& rStyleName = TableStyleName() ) const; 287 // Copy table in this 288 bool InsTable( const SwTable& rCpyTable, const SwNodeIndex&, 289 SwUndoTableCpyTable* pUndo ); 290 bool InsTable( const SwTable& rCpyTable, const SwSelBoxes&, 291 SwUndoTableCpyTable* pUndo ); 292 bool InsNewTable( const SwTable& rCpyTable, const SwSelBoxes&, 293 SwUndoTableCpyTable* pUndo ); 294 // Copy headline of table (with content!) into another one. 295 void CopyHeadlineIntoTable( SwTableNode& rTableNd ); 296 297 // Get box, whose start index is set on nBoxStt. 298 SwTableBox* GetTableBox( SwNodeOffset nSttIdx ); GetTableBox(SwNodeOffset nSttIdx) const299 const SwTableBox* GetTableBox( SwNodeOffset nSttIdx ) const 300 { return const_cast<SwTable*>(this)->GetTableBox( nSttIdx ); } 301 302 // Returns true if table contains nestings. 303 SW_DLLPUBLIC bool IsTableComplex() const; 304 305 // Returns true if table or selection is balanced. 306 bool IsTableComplexForChart( std::u16string_view aSel ) const; 307 308 // Search all content-bearing boxes of the base line on which this box stands. 309 // rBoxes as a return value for immediate use. 310 // bToTop = true -> up to base line, false-> else only line of box. 311 SW_DLLPUBLIC static SwSelBoxes& SelLineFromBox( const SwTableBox* pBox, 312 SwSelBoxes& rBoxes, bool bToTop = true ); 313 314 // Get information from client. 315 virtual bool GetInfo( SwFindNearestNode& ) const override; 316 317 // Search in format for registered table. 318 SW_DLLPUBLIC static SwTable * FindTable( SwFrameFormat const*const pFormat ); 319 320 // Clean up structure of subtables a bit: 321 // convert row with 1 box with subtable; box with subtable with 1 row; 322 // by removing the subtable (both recursively) 323 void GCLines(); 324 325 // Returns the table node via m_TabSortContentBoxes or pTableNode. 326 SW_DLLPUBLIC SwTableNode* GetTableNode() const; SetTableNode(SwTableNode * pNode)327 void SetTableNode( SwTableNode* pNode ) { m_pTableNode = pNode; } 328 329 // Data server methods. 330 void SetRefObject( SwServerObject* ); GetObject() const331 const SwServerObject* GetObject() const { return m_xRefObj.get(); } GetObject()332 SwServerObject* GetObject() { return m_xRefObj.get(); } 333 334 // Fill data for chart. 335 void UpdateCharts() const; 336 GetTableChgMode() const337 TableChgMode GetTableChgMode() const { return m_eTableChgMode; } SetTableChgMode(TableChgMode eMode)338 void SetTableChgMode( TableChgMode eMode ) { m_eTableChgMode = eMode; } 339 340 bool SetColWidth( SwTableBox& rCurrentBox, TableChgWidthHeightType eType, 341 SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr<SwUndo>* ppUndo ); 342 bool SetRowHeight( SwTableBox& rCurrentBox, TableChgWidthHeightType eType, 343 SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr<SwUndo>* ppUndo ); 344 void RegisterToFormat( SwFormat& rFormat ); 345 #ifdef DBG_UTIL 346 void CheckConsistency() const; 347 #endif 348 349 SW_DLLPUBLIC bool HasLayout() const; 350 351 bool CanConvertSubtables() const; 352 void ConvertSubtables(); 353 354 // is it a table deleted completely with change tracking 355 bool IsDeleted() const; 356 // is it a table with a deleted row or cell 357 SW_DLLPUBLIC bool HasDeletedRowOrCell() const; 358 // it doesn't contain box content (except single empty nested tables of the boxes 359 // which could remain after deletion of text content of the selected table) 360 bool IsEmpty() const; SwitchFormulasToExternalRepresentation()361 void SwitchFormulasToExternalRepresentation() 362 { UpdateFields(TBL_BOXNAME); }; SwitchFormulasToRelativeRepresentation()363 void SwitchFormulasToRelativeRepresentation() 364 { UpdateFields(TBL_RELBOXNAME); }; SwitchFormulasToInternalRepresentation()365 void SwitchFormulasToInternalRepresentation() 366 { UpdateFields(TBL_BOXPTR); } 367 void Merge(const SwTable& rTable, SwHistory* pHistory); 368 void Split(const UIName& sNewTableName, sal_uInt16 nSplitLine, SwHistory* pHistory); 369 370 static void GatherFormulas(SwDoc& rDoc, std::vector<SwTableBoxFormula*>& rvFormulas); 371 372 void dumpAsXml(xmlTextWriterPtr pWriter) const; 373 }; 374 375 /// SwTableLine is one table row in the document model. 376 class SW_DLLPUBLIC SwTableLine final : public SwClient // Client of FrameFormat. 377 { 378 SwTableBoxes m_aBoxes; 379 SwTableBox *m_pUpper; 380 RedlineType m_eRedlineType; 381 382 public: 383 384 SwTableLine( SwTableLineFormat*, sal_uInt16 nBoxes, SwTableBox *pUp ); 385 virtual ~SwTableLine() override; 386 GetTabBoxes()387 SwTableBoxes &GetTabBoxes() { return m_aBoxes; } GetTabBoxes() const388 const SwTableBoxes &GetTabBoxes() const { return m_aBoxes; } GetBoxPos(const SwTableBox * pBox) const389 sal_uInt16 GetBoxPos(const SwTableBox* pBox) const 390 { 391 SwTableBoxes::const_iterator it = std::find(m_aBoxes.begin(), m_aBoxes.end(), pBox); 392 return it == m_aBoxes.end() ? USHRT_MAX : it - m_aBoxes.begin(); 393 } 394 GetUpper()395 SwTableBox *GetUpper() { return m_pUpper; } GetUpper() const396 const SwTableBox *GetUpper() const { return m_pUpper; } SetUpper(SwTableBox * pNew)397 void SetUpper( SwTableBox *pNew ) { m_pUpper = pNew; } 398 GetFrameFormat()399 SwTableLineFormat* GetFrameFormat() { return static_cast<SwTableLineFormat*>(GetRegisteredIn()); } GetFrameFormat() const400 SwTableLineFormat* GetFrameFormat() const { return const_cast<SwTableLineFormat*>(static_cast<const SwTableLineFormat*>(GetRegisteredIn())); } 401 402 // Creates an own FrameFormat if more lines depend on it. 403 SwTableLineFormat* ClaimFrameFormat(); 404 void ChgFrameFormat( SwTableLineFormat* pNewFormat ); 405 406 // Search next/previous box with content. 407 SwTableBox* FindNextBox( const SwTable&, const SwTableBox* =nullptr, 408 bool bOvrTableLns=true ) const; 409 SwTableBox* FindPreviousBox( const SwTable&, const SwTableBox* =nullptr, 410 bool bOvrTableLns=true ) const; 411 412 SwTwips GetTableLineHeight( bool& bLayoutAvailable ) const; 413 414 bool hasSoftPageBreak() const; 415 416 // it doesn't contain box content (except single empty nested tables of the boxes 417 // which could remain after deletion of text content of the selected table row) 418 bool IsEmpty() const; 419 420 // Update TextChangesOnly property based on the redlines of the table row. 421 // rRedlinePos: search from this redline index to speed up SwTable::IsDeleted(). 422 // bUpdateProperty: don't update HasTextChangesOnly property, if bUpdateProperty = false. 423 // Set rRedlinePos after the last redline index of the table row. 424 // Return with the redline, which associated to the row change (latest deletion 425 // in the case of deleted row, the first insertion in the case of row insertion 426 // or npos, if TextChangesOnly is true, i.e. the table row is not deleted or inserted). 427 // Cache also the type of the redline associated to the changed table row. 428 SwRedlineTable::size_type UpdateTextChangesOnly( 429 SwRedlineTable::size_type& rRedlinePos, bool bUpdateProperty = true) const; 430 // tracked text changes, i.e. a single redline can contain tables 431 // get that redline for the table row, if it exists 432 SwRedlineTable::size_type GetTableRedline() const; 433 // is it a tracked row 434 bool IsTracked(SwRedlineTable::size_type& rRedlinePos, bool bOnlyDeleted = false) const; 435 // is it a tracked deleted row 436 bool IsDeleted(SwRedlineTable::size_type& rRedlinePos) const; 437 // set/get (if it's possible, cached) redline type 438 RedlineType GetRedlineType() const; SetRedlineType(RedlineType eType)439 void SetRedlineType(RedlineType eType) { m_eRedlineType = eType; } 440 441 void dumpAsXml(xmlTextWriterPtr pWriter) const; 442 }; 443 444 /// SwTableBox is one table cell in the document model. 445 class SW_DLLPUBLIC SwTableBox final : public SwClient //Client of FrameFormat. 446 { 447 friend class SwNodes; // Transpose index. 448 friend void DelBoxNode(SwTableSortBoxes const &); // Delete StartNode* ! 449 friend class SwXMLTableContext; 450 451 SwTableBox( const SwTableBox & ) = delete; 452 SwTableBox &operator=( const SwTableBox &) = delete; 453 454 SwTableLines m_aLines; 455 const SwStartNode * m_pStartNode; 456 SwTableLine *m_pUpper; 457 458 std::optional<Color> mxUserColor; 459 std::optional<Color> mxNumFormatColor; 460 sal_Int32 mnRowSpan; 461 bool mbDummyFlag; 462 463 /// Do we contain any direct formatting? 464 bool mbDirectFormatting; 465 466 // In case Format contains formulas/values already, 467 // a new one must be created for the new box. 468 static SwTableBoxFormat* CheckBoxFormat( SwTableBoxFormat* ); 469 470 public: 471 472 SwTableBox( SwTableBoxFormat*, sal_uInt16 nLines, SwTableLine *pUp ); 473 SwTableBox( SwTableBoxFormat*, const SwStartNode&, SwTableLine *pUp ); 474 SwTableBox( SwTableBoxFormat*, const SwNodeIndex&, SwTableLine *pUp ); 475 virtual ~SwTableBox() override; 476 GetTabLines()477 SwTableLines &GetTabLines() { return m_aLines; } GetTabLines() const478 const SwTableLines &GetTabLines() const { return m_aLines; } 479 GetUpper()480 SwTableLine *GetUpper() { return m_pUpper; } GetUpper() const481 const SwTableLine *GetUpper() const { return m_pUpper; } SetUpper(SwTableLine * pNew)482 void SetUpper( SwTableLine *pNew ) { m_pUpper = pNew; } 483 GetFrameFormat()484 SwTableBoxFormat* GetFrameFormat() { return static_cast<SwTableBoxFormat*>(GetRegisteredIn()); } GetFrameFormat() const485 SwTableBoxFormat* GetFrameFormat() const { return const_cast<SwTableBoxFormat*>(static_cast<const SwTableBoxFormat*>(GetRegisteredIn())); } 486 487 /// Set that this table box contains formatting that is not set by the table style. SetDirectFormatting(bool bDirect)488 void SetDirectFormatting(bool bDirect) { mbDirectFormatting = bDirect; } 489 490 /// Do we contain any direct formatting (ie. something not affected by the table style)? HasDirectFormatting() const491 bool HasDirectFormatting() const { return mbDirectFormatting; } 492 493 // Creates its own FrameFormat if more boxes depend on it. 494 SwTableBoxFormat* ClaimFrameFormat(); 495 void ChgFrameFormat( SwTableBoxFormat *pNewFormat, bool bNeedToReregister = true ); 496 497 void RemoveFromTable(); GetSttNd() const498 const SwStartNode *GetSttNd() const { return m_pStartNode; } 499 SwNodeOffset GetSttIdx() const; 500 // it doesn't contain box content or if bWithRemainingNestedTable = true, 501 // it contains only an empty nested table as box content (which 502 // could remain after deletion of the text content of the selected box). 503 bool IsEmpty( bool bWithRemainingNestedTable = true ) const; 504 505 // Search next/previous box with content. 506 SwTableBox* FindNextBox( const SwTable&, const SwTableBox*, 507 bool bOvrTableLns=true ) const; 508 SwTableBox* FindPreviousBox( const SwTable&, const SwTableBox* ) const; 509 // Return name of this box. It is determined dynamically and 510 // is calculated from the position in the lines/boxes/table. 511 OUString GetName() const; 512 // Return "value" of box (for calculating in table). 513 double GetValue( SwTableCalcPara& rPara ) const; 514 515 // Computes "coordinates" of a box, used to computed selection 516 // width or height when inserting cols or rows 517 Point GetCoordinates() const; 518 519 bool IsInHeadline( const SwTable* pTable ) const; 520 521 // Contains box contents, that can be formatted as a number? 522 bool HasNumContent( double& rNum, sal_uInt32& rFormatIndex, 523 bool& rIsEmptyTextNd ) const; 524 SwNodeOffset IsValidNumTextNd( bool bCheckAttr = true ) const; 525 // If a table formula is set, test if box contents is congruent with number. 526 // (For Redo of change of NumFormat!). 527 bool IsNumberChanged() const; 528 529 // Is that a formula box or a box with numeric contents (AutoSum)? 530 // What it is indicated by the return value - the WhichId of the attribute. 531 // Empty boxes have the return value USHRT_MAX !! 532 sal_uInt16 IsFormulaOrValueBox() const; 533 534 // Loading of a document requires an actualization of cells with values 535 void ActualiseValueBox(); 536 537 // Access on internal data - currently used for the NumFormatter. GetSaveUserColor() const538 const std::optional<Color>& GetSaveUserColor() const { return mxUserColor; } GetSaveNumFormatColor() const539 const std::optional<Color>& GetSaveNumFormatColor() const { return mxNumFormatColor; } SetSaveUserColor(std::optional<Color> p)540 void SetSaveUserColor(std::optional<Color> p ) { mxUserColor = p; } SetSaveNumFormatColor(std::optional<Color> p)541 void SetSaveNumFormatColor( std::optional<Color> p ) { mxNumFormatColor = p; } 542 getRowSpan() const543 sal_Int32 getRowSpan() const { return mnRowSpan; } 544 void setRowSpan( sal_Int32 nNewRowSpan ); 545 bool getDummyFlag() const; 546 void setDummyFlag( bool bDummy ); 547 548 SwTableBox& FindStartOfRowSpan( const SwTable&, sal_uInt16 nMaxStep = USHRT_MAX ); FindStartOfRowSpan(const SwTable & rTable,sal_uInt16 nMaxStep=USHRT_MAX) const549 const SwTableBox& FindStartOfRowSpan( const SwTable& rTable, 550 sal_uInt16 nMaxStep = USHRT_MAX ) const 551 { return const_cast<SwTableBox*>(this)->FindStartOfRowSpan( rTable, nMaxStep ); } 552 553 SwTableBox& FindEndOfRowSpan( const SwTable&, sal_uInt16 nMaxStep ); FindEndOfRowSpan(const SwTable & rTable,sal_uInt16 nMaxStep) const554 const SwTableBox& FindEndOfRowSpan( const SwTable& rTable, 555 sal_uInt16 nMaxStep ) const 556 { return const_cast<SwTableBox*>(this)->FindEndOfRowSpan( rTable, nMaxStep ); } 557 void RegisterToFormat( SwFormat& rFormat ) ; 558 // get redline for the table cell, if it exists 559 SwRedlineTable::size_type GetRedline() const; 560 // get redline type 561 RedlineType GetRedlineType() const; 562 563 void dumpAsXml(xmlTextWriterPtr pWriter) const; 564 }; 565 566 class SwCellFrame; 567 class SW_DLLPUBLIC SwTableCellInfo 568 { 569 struct Impl; 570 std::unique_ptr<Impl> m_pImpl; 571 572 const SwCellFrame * getCellFrame() const; 573 574 SwTableCellInfo(SwTableCellInfo const&) = delete; 575 SwTableCellInfo& operator=(SwTableCellInfo const&) = delete; 576 577 public: 578 SwTableCellInfo(const SwTable * pTable); 579 ~SwTableCellInfo(); 580 581 bool getNext(); 582 SwRect getRect() const; 583 const SwTableBox * getTableBox() const; 584 }; 585 586 #endif // INCLUDED_SW_INC_SWTABLE_HXX 587 588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 589
