/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: */ |