xref: /core/sw/inc/swtable.hxx (revision 3e86a879508e55673b4f6d24ce84eb98b332da63)
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