Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/sw/inc/swtable.hxx
Line
Count
Source (jump to first uncovered line)
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
74
644k
    bool empty() const { return m_vLines.empty(); }
75
764k
    size_type size() const { return m_vLines.size(); }
76
825k
    iterator begin() { return m_vLines.begin(); }
77
81.1k
    const_iterator begin() const { return m_vLines.begin(); }
78
863k
    iterator end() { return m_vLines.end(); }
79
81.1k
    const_iterator end() const { return m_vLines.end(); }
80
136
    SwTableLine* front() const { return m_vLines.front(); }
81
0
    SwTableLine* back() const { return m_vLines.back(); }
82
0
    void clear() { m_vLines.clear(); }
83
0
    iterator erase( iterator aIt ) { return m_vLines.erase( aIt ); }
84
0
    iterator erase( iterator aFirst, iterator aLast ) { return m_vLines.erase( aFirst, aLast ); }
85
92.0k
    iterator insert( iterator aIt, SwTableLine* pLine ) { return m_vLines.insert( aIt, pLine ); }
86
    template<typename TInputIterator>
87
    void insert( iterator aIt, TInputIterator aFirst, TInputIterator aLast )
88
0
    {
89
0
        m_vLines.insert( aIt, aFirst, aLast );
90
0
    }
91
37.4k
    void push_back( SwTableLine* pLine ) { m_vLines.push_back( pLine ); }
92
0
    void reserve( size_type nSize ) { m_vLines.reserve( nSize ); }
93
140k
    SwTableLine*& operator[]( size_type nPos ) { return m_vLines[ nPos ]; }
94
549k
    SwTableLine* operator[]( size_type nPos ) const { return m_vLines[ nPos ]; }
95
96
    // return USHRT_MAX if not found, else index of position
97
    sal_uInt16 GetPos(const SwTableLine* pBox) const
98
10.2k
    {
99
10.2k
        const_iterator it = std::find(begin(), end(), pBox);
100
10.2k
        return it == end() ? USHRT_MAX : it - begin();
101
10.2k
    }
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
157
663k
    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:
181
259k
    SwHTMLTableLayout *GetHTMLTableLayout() { return m_xHTMLLayout.get(); }
182
0
    const SwHTMLTableLayout *GetHTMLTableLayout() const { return m_xHTMLLayout.get(); }
183
    void SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout> const& r);    //Change of property!
184
185
13.6k
    sal_uInt16 IncGrfsThatResize() { return ++m_nGraphicsThatResize; }
186
0
    sal_uInt16 DecGrfsThatResize() { return m_nGraphicsThatResize ? --m_nGraphicsThatResize : 0; }
187
188
59.7k
    void LockModify()   { m_bModifyLocked = true; }   // Must be used always
189
59.7k
    void UnlockModify() { m_bModifyLocked = false;}   // in pairs!
190
191
74.0k
    void SetTableModel( bool bNew ){ m_bNewModel = bNew; }
192
6.18k
    bool IsNewModel() const { return m_bNewModel; }
193
194
    /// Return the table style name of this table.
195
909
    const TableStyleName& GetTableStyleName() const { return maTableStyleName; }
196
197
    /// Set the new table style name for this table.
198
1.85k
    void SetTableStyleName(const TableStyleName& rName) { maTableStyleName = rName; }
199
200
2.26k
    sal_uInt16 GetRowsToRepeat() const { return std::min( o3tl::narrowing<sal_uInt16>(GetTabLines().size()), m_nRowsToRepeat ); }
201
141k
    void SetRowsToRepeat( sal_uInt16 nNumOfRows ) { m_nRowsToRepeat = nNumOfRows; }
202
203
    bool IsHeadline( const SwTableLine& rLine ) const;
204
205
501k
          SwTableLines &GetTabLines() { return m_aLines; }
206
327k
    const SwTableLines &GetTabLines() const { return m_aLines; }
207
208
323k
    SwTableFormat* GetFrameFormat()       { return static_cast<SwTableFormat*>(GetRegisteredIn()); }
209
234k
    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
236
    bool Merge( SwDoc& rDoc, const SwSelBoxes& rBoxes, const SwSelBoxes& rMerged,
237
                SwTableBox* pMergeBox, SwUndoTableMerge* pUndo )
238
14
    {
239
14
        return m_bNewModel ? NewMerge( rDoc, rBoxes, rMerged, pUndo ) :
240
14
                             OldMerge( rDoc, rBoxes, pMergeBox, pUndo );
241
14
    }
242
    bool SplitRow( SwDoc& rDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt,
243
                   bool bSameHeight )
244
0
    {
245
0
        return m_bNewModel ? NewSplitRow( rDoc, rBoxes, nCnt, bSameHeight ) :
246
0
                           OldSplitRow( rDoc, rBoxes, nCnt, bSameHeight );
247
0
    }
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
262
    void FindSuperfluousRows( SwSelBoxes& rBoxes )
263
0
        { FindSuperfluousRows_( rBoxes, nullptr, nullptr ); }
264
    void CheckRowSpan( SwTableLine* &rpLine, bool bUp ) const;
265
266
1.37M
          SwTableSortBoxes& GetTabSortBoxes()       { return m_TabSortContentBoxes; }
267
11.6M
    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 );
299
    const SwTableBox* GetTableBox( SwNodeOffset nSttIdx ) const
300
21.6k
                        {   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;
327
75.9k
    void SetTableNode( SwTableNode* pNode ) { m_pTableNode = pNode; }
328
329
    // Data server methods.
330
    void SetRefObject( SwServerObject* );
331
0
    const SwServerObject* GetObject() const     {  return m_xRefObj.get(); }
332
0
          SwServerObject* GetObject()           {  return m_xRefObj.get(); }
333
334
    // Fill data for chart.
335
    void UpdateCharts() const;
336
337
909
    TableChgMode GetTableChgMode() const        { return m_eTableChgMode; }
338
909
    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;
361
    void SwitchFormulasToExternalRepresentation()
362
0
        { UpdateFields(TBL_BOXNAME); };
363
    void SwitchFormulasToRelativeRepresentation()
364
0
        { UpdateFields(TBL_RELBOXNAME); };
365
    void SwitchFormulasToInternalRepresentation()
366
30
        { 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
387
2.15M
          SwTableBoxes &GetTabBoxes() { return m_aBoxes; }
388
236k
    const SwTableBoxes &GetTabBoxes() const { return m_aBoxes; }
389
    sal_uInt16 GetBoxPos(const SwTableBox* pBox) const
390
4.64k
    {
391
4.64k
        SwTableBoxes::const_iterator it = std::find(m_aBoxes.begin(), m_aBoxes.end(), pBox);
392
4.64k
        return it == m_aBoxes.end() ? USHRT_MAX : it - m_aBoxes.begin();
393
4.64k
    }
394
395
162
          SwTableBox *GetUpper() { return m_pUpper; }
396
85.7k
    const SwTableBox *GetUpper() const { return m_pUpper; }
397
0
    void SetUpper( SwTableBox *pNew ) { m_pUpper = pNew; }
398
399
308k
    SwTableLineFormat* GetFrameFormat()       { return static_cast<SwTableLineFormat*>(GetRegisteredIn()); }
400
8.76k
    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;
439
18
    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
477
635k
          SwTableLines &GetTabLines() { return m_aLines; }
478
34.3k
    const SwTableLines &GetTabLines() const { return m_aLines; }
479
480
33.7k
          SwTableLine *GetUpper() { return m_pUpper; }
481
378k
    const SwTableLine *GetUpper() const { return m_pUpper; }
482
52.8k
    void SetUpper( SwTableLine *pNew ) { m_pUpper = pNew; }
483
484
3.94M
    SwTableBoxFormat* GetFrameFormat()       { return static_cast<SwTableBoxFormat*>(GetRegisteredIn()); }
485
471k
    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.
488
0
    void SetDirectFormatting(bool bDirect) { mbDirectFormatting = bDirect; }
489
490
    /// Do we contain any direct formatting (ie. something not affected by the table style)?
491
0
    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();
498
7.38M
    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.
538
0
    const std::optional<Color>& GetSaveUserColor()  const { return mxUserColor; }
539
62.7k
    const std::optional<Color>& GetSaveNumFormatColor() const { return mxNumFormatColor; }
540
460
    void SetSaveUserColor(std::optional<Color> p ) { mxUserColor = p; }
541
62.7k
    void SetSaveNumFormatColor( std::optional<Color> p ) { mxNumFormatColor = p; }
542
543
91.0k
    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 );
549
    const SwTableBox& FindStartOfRowSpan( const SwTable& rTable,
550
        sal_uInt16 nMaxStep = USHRT_MAX ) const
551
0
        { return const_cast<SwTableBox*>(this)->FindStartOfRowSpan( rTable, nMaxStep ); }
552
553
    SwTableBox& FindEndOfRowSpan( const SwTable&, sal_uInt16 nMaxStep );
554
    const SwTableBox& FindEndOfRowSpan( const SwTable& rTable,
555
        sal_uInt16 nMaxStep ) const
556
0
        { 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: */