bump product version to 4.1.6.2
[LibreOffice.git] / sw / inc / swtable.hxx
blob29a7fd1158c5c6b3b33aa7cd917ca246d0f5ff1f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef _SWTABLE_HXX
20 #define _SWTABLE_HXX
21 #include <tools/mempool.hxx>
22 #include <tools/ref.hxx>
23 #include <tblenum.hxx>
24 #include <swtypes.hxx>
25 #include <calbck.hxx>
26 #include <swrect.hxx>
28 #include <memory>
29 #include <boost/noncopyable.hpp>
30 #include <vector>
31 #include <algorithm>
32 #include <o3tl/sorted_vector.hxx>
34 class SwStartNode;
35 class SwFmt;
36 class Color;
37 class SwFrmFmt;
38 class SwTableFmt;
39 class SwTableLineFmt;
40 class SwTableBoxFmt;
41 class SwHTMLTableLayout;
42 class SwTableLine;
43 class SwTableBox;
44 class SwTableNode;
45 class SwTabCols;
46 class SwDoc;
47 class SwSelBoxes;
48 class SwTblCalcPara;
49 struct SwPosition;
50 class SwNodeIndex;
51 class SwNode;
52 class SfxPoolItem;
53 class SwUndoTblMerge;
54 class SwUndo;
55 class SwPaM;
56 class SwTableBox_Impl;
57 class SwUndoTblCpyTbl;
58 class SwBoxSelection;
59 struct SwSaveRowSpan;
60 struct Parm;
62 #ifndef SW_DECL_SWSERVEROBJECT_DEFINED
63 #define SW_DECL_SWSERVEROBJECT_DEFINED
64 SV_DECL_REF( SwServerObject )
65 #endif
67 class SwTableLines : public std::vector<SwTableLine*> {
68 public:
69 // free's any remaining child objects
70 ~SwTableLines();
72 // return USHRT_MAX if not found, else index of position
73 sal_uInt16 GetPos(const SwTableLine* pBox) const
75 const_iterator it = std::find(begin(), end(), pBox);
76 return it == end() ? USHRT_MAX : it - begin();
80 class SwTableBoxes : public std::vector<SwTableBox*> {
81 public:
82 // return USHRT_MAX if not found, else index of position
83 sal_uInt16 GetPos(const SwTableBox* pBox) const
85 const_iterator it = std::find(begin(), end(), pBox);
86 return it == end() ? USHRT_MAX : it - begin();
90 // Save content-bearing box-pointers additionally in a sorted array
91 // (for calculation in table).
92 class SwTableSortBoxes : public o3tl::sorted_vector<SwTableBox*> {};
94 class SW_DLLPUBLIC SwTable: public SwClient //Client of FrmFmt.
98 protected:
99 SwTableLines aLines;
100 SwTableSortBoxes m_TabSortContentBoxes;
101 SwServerObjectRef refObj; // In case DataServer -> pointer is set.
103 SwHTMLTableLayout *pHTMLLayout;
105 // Usually, the table node of a SwTable can be accessed by getting a box
106 // out of m_TabSortContentBoxes, which know their SwStartNode. But in some rare
107 // cases, we need to know the table node of a SwTable, before the table
108 // boxes have been build (SwTableNode::MakeCopy with tables in tables).
109 SwTableNode* pTableNode;
111 // Should that be adjustable for every table?
112 TblChgMode eTblChgMode;
114 sal_uInt16 nGrfsThatResize; // Count of Grfs that initiate a resize of table
115 // at HTML-import.
116 sal_uInt16 nRowsToRepeat; // Number of rows to repeat on every page.
118 bool bModifyLocked :1;
119 sal_Bool bNewModel :1; // sal_False: old SubTableModel; sal_True: new RowSpanModel
120 #ifdef DBG_UTIL
121 /// This is set by functions (like Merge()) to forbid a late model change.
122 bool m_bDontChangeModel;
123 #endif
125 bool IsModifyLocked(){ return bModifyLocked;}
127 virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew );
129 public:
130 enum SearchType
132 SEARCH_NONE, // Default: expand to rectangle
133 SEARCH_ROW, // row selection
134 SEARCH_COL // column selection
137 TYPEINFO();
139 // single argument ctors shall be explicit.
140 explicit SwTable( SwTableFmt* );
141 virtual ~SwTable();
143 // @@@ public copy ctor, but no copy assignment?
144 SwTable( const SwTable& rTable ); // no copy of the lines !!
145 private:
146 // @@@ public copy ctor, but no copy assignment?
147 SwTable & operator= (const SwTable &);
148 // no default ctor.
149 SwTable();
150 bool OldMerge( SwDoc*, const SwSelBoxes&, SwTableBox*, SwUndoTblMerge* );
151 bool OldSplitRow( SwDoc*, const SwSelBoxes&, sal_uInt16, bool );
152 sal_Bool NewMerge( SwDoc*, const SwSelBoxes&, const SwSelBoxes& rMerged,
153 SwTableBox*, SwUndoTblMerge* );
154 sal_Bool NewSplitRow( SwDoc*, const SwSelBoxes&, sal_uInt16, sal_Bool );
155 SwBoxSelection* CollectBoxSelection( const SwPaM& rPam ) const;
156 void InsertSpannedRow( SwDoc* pDoc, sal_uInt16 nIdx, sal_uInt16 nCnt );
157 bool _InsertRow( SwDoc*, const SwSelBoxes&, sal_uInt16 nCnt, bool bBehind );
158 bool NewInsertCol( SwDoc*, const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool );
159 void _FindSuperfluousRows( SwSelBoxes& rBoxes, SwTableLine*, SwTableLine* );
160 void AdjustWidths( const long nOld, const long nNew );
161 void NewSetTabCols( Parm &rP, const SwTabCols &rNew, const SwTabCols &rOld,
162 const SwTableBox *pStart, sal_Bool bCurRowOnly );
164 public:
166 SwHTMLTableLayout *GetHTMLTableLayout() { return pHTMLLayout; }
167 const SwHTMLTableLayout *GetHTMLTableLayout() const { return pHTMLLayout; }
168 void SetHTMLTableLayout( SwHTMLTableLayout *p ); //Change of property!
170 sal_uInt16 IncGrfsThatResize() { return ++nGrfsThatResize; }
171 sal_uInt16 DecGrfsThatResize() { return nGrfsThatResize ? --nGrfsThatResize : 0; }
173 void LockModify() { bModifyLocked = true; } // Must be used always
174 void UnlockModify() { bModifyLocked = false;} // in pairs!
176 void SetTableModel( sal_Bool bNew ){ bNewModel = bNew; }
177 sal_Bool IsNewModel() const { return bNewModel; }
179 sal_uInt16 GetRowsToRepeat() const { return std::min( (sal_uInt16)GetTabLines().size(), nRowsToRepeat ); }
180 sal_uInt16 _GetRowsToRepeat() const { return nRowsToRepeat; }
181 void SetRowsToRepeat( sal_uInt16 nNumOfRows ) { nRowsToRepeat = nNumOfRows; }
183 bool IsHeadline( const SwTableLine& rLine ) const;
185 SwTableLines &GetTabLines() { return aLines; }
186 const SwTableLines &GetTabLines() const { return aLines; }
188 SwFrmFmt* GetFrmFmt() { return (SwFrmFmt*)GetRegisteredIn(); }
189 SwFrmFmt* GetFrmFmt() const { return (SwFrmFmt*)GetRegisteredIn(); }
190 SwTableFmt* GetTableFmt() const { return (SwTableFmt*)GetRegisteredIn(); }
192 void GetTabCols( SwTabCols &rToFill, const SwTableBox *pStart,
193 sal_Bool bHidden = sal_False, sal_Bool bCurRowOnly = sal_False ) const;
194 void SetTabCols( const SwTabCols &rNew, const SwTabCols &rOld,
195 const SwTableBox *pStart, sal_Bool bCurRowOnly );
197 // The following functions are for new table model only...
198 void CreateSelection( const SwPaM& rPam, SwSelBoxes& rBoxes,
199 const SearchType eSearchType, bool bProtect ) const;
200 void CreateSelection( const SwNode* pStart, const SwNode* pEnd,
201 SwSelBoxes& rBoxes, const SearchType eSearchType, bool bProtect ) const;
202 void ExpandSelection( SwSelBoxes& rBoxes ) const;
203 // When a table is splitted into two tables, the row spans which overlaps
204 // the split have to be corrected and stored for undo
205 // SwSavRowSpan is the structure needed by Undo to undo the split operation
206 // CleanUpRowSpan corrects the (top of the) second table and delviers the structure
207 // for Undo
208 SwSaveRowSpan* CleanUpTopRowSpan( sal_uInt16 nSplitLine );
209 // RestoreRowSpan is called by Undo to restore the old row span values
210 void RestoreRowSpan( const SwSaveRowSpan& );
211 // CleanUpBottomRowSpan corrects the overhanging row spans at the end of the first table
212 void CleanUpBottomRowSpan( sal_uInt16 nDelLines );
215 // The following functions are "pseudo-virtual", i.e. they are different for old and new table model
216 // It's not allowed to change the table model after the first call of one of these functions.
218 sal_Bool Merge( SwDoc* pDoc, const SwSelBoxes& rBoxes, const SwSelBoxes& rMerged,
219 SwTableBox* pMergeBox, SwUndoTblMerge* pUndo = 0 )
221 #ifdef DBG_UTIL
222 m_bDontChangeModel = true;
223 #endif
224 return bNewModel ? NewMerge( pDoc, rBoxes, rMerged, pMergeBox, pUndo ) :
225 OldMerge( pDoc, rBoxes, pMergeBox, pUndo );
227 bool SplitRow( SwDoc* pDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt=1,
228 bool bSameHeight = false )
230 #ifdef DBG_UTIL
231 m_bDontChangeModel = true;
232 #endif
233 return bNewModel ? NewSplitRow( pDoc, rBoxes, nCnt, bSameHeight ) :
234 OldSplitRow( pDoc, rBoxes, nCnt, bSameHeight );
236 bool PrepareMerge( const SwPaM& rPam, SwSelBoxes& rBoxes,
237 SwSelBoxes& rMerged, SwTableBox** ppMergeBox, SwUndoTblMerge* pUndo );
238 void ExpandColumnSelection( SwSelBoxes& rBoxes, long &rMin, long &rMax ) const;
239 void PrepareDeleteCol( long nMin, long nMax );
241 bool InsertCol( SwDoc*, const SwSelBoxes& rBoxes,
242 sal_uInt16 nCnt = 1, bool bBehind = true );
243 bool InsertRow( SwDoc*, const SwSelBoxes& rBoxes,
244 sal_uInt16 nCnt = 1, bool bBehind = true );
245 void PrepareDelBoxes( const SwSelBoxes& rBoxes );
246 bool DeleteSel( SwDoc*, const SwSelBoxes& rBoxes, const SwSelBoxes* pMerged,
247 SwUndo* pUndo, const bool bDelMakeFrms, const bool bCorrBorder );
248 bool SplitCol( SwDoc* pDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt=1 );
249 sal_Bool Merge( const SwSelBoxes& rBoxes,
250 SwTableBox* pMergeBox, SwUndoTblMerge* = 0 );
252 void FindSuperfluousRows( SwSelBoxes& rBoxes )
253 { _FindSuperfluousRows( rBoxes, 0, 0 ); }
254 void CheckRowSpan( SwTableLine* &rpLine, bool bUp ) const;
256 SwTableSortBoxes& GetTabSortBoxes() { return m_TabSortContentBoxes; }
257 const SwTableSortBoxes& GetTabSortBoxes() const { return m_TabSortContentBoxes; }
259 // Read 1st number and delete it from string (used by GetTblBox and SwTblFld).
261 // #i80314#
262 // add 3rd parameter in order to control validation check on <rStr>
263 static sal_uInt16 _GetBoxNum( String& rStr,
264 sal_Bool bFirst = sal_False,
265 const bool bPerformValidCheck = false );
267 // Search content-bearing box with that name.
269 // #i80314#
270 // add 2nd parameter in order to control validation check in called method
271 // <_GetBoxNum(..)>
272 const SwTableBox* GetTblBox( const String& rName,
273 const bool bPerformValidCheck = false ) const;
274 // Copy selected boxes to another document.
275 bool MakeCopy( SwDoc*, const SwPosition&, const SwSelBoxes&,
276 bool bCpyNds = true, bool bCpyName = false ) const;
277 // Copy table in this
278 sal_Bool InsTable( const SwTable& rCpyTbl, const SwNodeIndex&,
279 SwUndoTblCpyTbl* pUndo = 0 );
280 sal_Bool InsTable( const SwTable& rCpyTbl, const SwSelBoxes&,
281 SwUndoTblCpyTbl* pUndo = 0 );
282 sal_Bool InsNewTable( const SwTable& rCpyTbl, const SwSelBoxes&,
283 SwUndoTblCpyTbl* pUndo );
284 // Copy headline of table (with content!) into an other one.
285 bool CopyHeadlineIntoTable( SwTableNode& rTblNd );
287 // Get box, whose start index is set on nBoxStt.
288 SwTableBox* GetTblBox( sal_uLong nSttIdx );
289 const SwTableBox* GetTblBox( sal_uLong nSttIdx ) const
290 { return ((SwTable*)this)->GetTblBox( nSttIdx ); }
292 // Returns true if table contains nestings.
293 bool IsTblComplex() const;
295 // Returns true if table or selection is balanced.
296 bool IsTblComplexForChart( const String& rSel ) const;
298 // Search all content-bearing boxes of the base line on which this box stands.
299 // rBoxes as a return value for immediate use.
300 // steht. rBoxes auch als Return-Wert, um es gleich weiter zu benutzen
301 // bToTop = true -> up to base line, sal_False-> else only line of box.
302 SwSelBoxes& SelLineFromBox( const SwTableBox* pBox,
303 SwSelBoxes& rBoxes, bool bToTop = true ) const;
305 // Get information from client.
306 virtual bool GetInfo( SfxPoolItem& ) const;
308 // Search in format for registered table.
309 static SwTable * FindTable( SwFrmFmt const*const pFmt );
311 // Clean up structure a bit.
312 void GCLines();
314 // Returns the table node via m_TabSortContentBoxes or pTableNode.
315 SwTableNode* GetTableNode() const;
316 void SetTableNode( SwTableNode* pNode ) { pTableNode = pNode; }
318 // Data server methods.
319 void SetRefObject( SwServerObject* );
320 const SwServerObject* GetObject() const { return &refObj; }
321 SwServerObject* GetObject() { return &refObj; }
323 // Fill data for chart.
324 void UpdateCharts() const;
326 TblChgMode GetTblChgMode() const { return eTblChgMode; }
327 void SetTblChgMode( TblChgMode eMode ) { eTblChgMode = eMode; }
329 bool SetColWidth( SwTableBox& rAktBox, sal_uInt16 eType,
330 SwTwips nAbsDiff, SwTwips nRelDiff, SwUndo** ppUndo );
331 bool SetRowHeight( SwTableBox& rAktBox, sal_uInt16 eType,
332 SwTwips nAbsDiff, SwTwips nRelDiff, SwUndo** ppUndo );
333 void RegisterToFormat( SwFmt& rFmt );
334 #ifdef DBG_UTIL
335 void CheckConsistency() const;
336 #endif
338 bool HasLayout() const;
341 class SW_DLLPUBLIC SwTableLine: public SwClient // Client of FrmFmt.
343 SwTableBoxes aBoxes;
344 SwTableBox *pUpper;
346 public:
347 TYPEINFO();
349 SwTableLine() : pUpper(0) {}
351 SwTableLine( SwTableLineFmt*, sal_uInt16 nBoxes, SwTableBox *pUp );
352 virtual ~SwTableLine();
354 SwTableBoxes &GetTabBoxes() { return aBoxes; }
355 const SwTableBoxes &GetTabBoxes() const { return aBoxes; }
357 SwTableBox *GetUpper() { return pUpper; }
358 const SwTableBox *GetUpper() const { return pUpper; }
359 void SetUpper( SwTableBox *pNew ) { pUpper = pNew; }
362 SwFrmFmt* GetFrmFmt() { return (SwFrmFmt*)GetRegisteredIn(); }
363 SwFrmFmt* GetFrmFmt() const { return (SwFrmFmt*)GetRegisteredIn(); }
365 // Creates a own FrmFmt if more lines depend on it.
366 SwFrmFmt* ClaimFrmFmt();
367 void ChgFrmFmt( SwTableLineFmt* pNewFmt );
369 // Search next/previous box with content.
370 SwTableBox* FindNextBox( const SwTable&, const SwTableBox* =0,
371 bool bOvrTblLns=true ) const;
372 SwTableBox* FindPreviousBox( const SwTable&, const SwTableBox* =0,
373 bool bOvrTblLns=true ) const;
375 SwTwips GetTableLineHeight( bool& bLayoutAvailable ) const;
377 bool hasSoftPageBreak() const;
378 void RegisterToFormat( SwFmt& rFmt );
381 class SW_DLLPUBLIC SwTableBox: public SwClient //Client of FrmFmt.
383 friend class SwNodes; // Transpose index.
384 friend void DelBoxNode(SwTableSortBoxes&); // Delete StartNode* !
385 friend class SwXMLTableContext;
387 // Not implemented (any more).
388 SwTableBox( const SwTableBox & );
389 SwTableBox &operator=( const SwTableBox &); // Does not exist.
391 SwTableLines aLines;
392 const SwStartNode * pSttNd;
393 SwTableLine *pUpper;
394 SwTableBox_Impl* pImpl;
396 // In case Format contains formulas/values already,
397 // a new one must be created for the new box.
398 SwTableBoxFmt* CheckBoxFmt( SwTableBoxFmt* );
400 public:
401 TYPEINFO();
403 SwTableBox() : pSttNd(0), pUpper(0), pImpl(0) {}
405 SwTableBox( SwTableBoxFmt*, sal_uInt16 nLines, SwTableLine *pUp = 0 );
406 SwTableBox( SwTableBoxFmt*, const SwStartNode&, SwTableLine *pUp = 0 );
407 SwTableBox( SwTableBoxFmt*, const SwNodeIndex&, SwTableLine *pUp = 0 );
408 virtual ~SwTableBox();
410 SwTableLines &GetTabLines() { return aLines; }
411 const SwTableLines &GetTabLines() const { return aLines; }
413 SwTableLine *GetUpper() { return pUpper; }
414 const SwTableLine *GetUpper() const { return pUpper; }
415 void SetUpper( SwTableLine *pNew ) { pUpper = pNew; }
417 SwFrmFmt* GetFrmFmt() { return (SwFrmFmt*)GetRegisteredIn(); }
418 SwFrmFmt* GetFrmFmt() const { return (SwFrmFmt*)GetRegisteredIn(); }
420 // Creates its own FrmFmt if more boxes depend on it.
421 SwFrmFmt* ClaimFrmFmt();
422 void ChgFrmFmt( SwTableBoxFmt *pNewFmt );
424 void RemoveFromTable();
425 const SwStartNode *GetSttNd() const { return pSttNd; }
426 sal_uLong GetSttIdx() const;
428 // Search next/previous box with content.
429 SwTableBox* FindNextBox( const SwTable&, const SwTableBox* =0,
430 bool bOvrTblLns=true ) const;
431 SwTableBox* FindPreviousBox( const SwTable&, const SwTableBox* =0,
432 bool bOvrTblLns=true ) const;
433 // Return name of this box. It is determined dynamically and
434 // is calculated from the position in the lines/boxes/table.
435 String GetName() const;
436 // Return "value" of box (for calculating in table).
437 double GetValue( SwTblCalcPara& rPara ) const;
439 sal_Bool IsInHeadline( const SwTable* pTbl = 0 ) const;
441 // Contains box contents, that can be formated as a number?
442 sal_Bool HasNumCntnt( double& rNum, sal_uInt32& rFmtIndex,
443 sal_Bool& rIsEmptyTxtNd ) const;
444 sal_uLong IsValidNumTxtNd( sal_Bool bCheckAttr = sal_True ) const;
445 // If a table formula is set, test if box contents is congruent with number.
446 // (For Redo of change of NumFormat!).
447 sal_Bool IsNumberChanged() const;
449 // Is that a formula box or a box with numeric contents (AutoSum)?
450 // What it is is indicated by the return value - the WhichId of the attribute.
451 // Empty boxes have the return value USHRT_MAX !!
452 sal_uInt16 IsFormulaOrValueBox() const;
454 // Loading of a document requires an actualisation of cells with values
455 void ActualiseValueBox();
457 DECL_FIXEDMEMPOOL_NEWDEL(SwTableBox)
459 // Access on internal data - currently used for the NumFormatter.
460 inline const Color* GetSaveUserColor() const;
461 inline const Color* GetSaveNumFmtColor() const;
462 inline void SetSaveUserColor(const Color* p );
463 inline void SetSaveNumFmtColor( const Color* p );
465 long getRowSpan() const;
466 void setRowSpan( long nNewRowSpan );
467 bool getDummyFlag() const;
468 void setDummyFlag( bool bDummy );
470 SwTableBox& FindStartOfRowSpan( const SwTable&, sal_uInt16 nMaxStep = USHRT_MAX );
471 const SwTableBox& FindStartOfRowSpan( const SwTable& rTable,
472 sal_uInt16 nMaxStep = USHRT_MAX ) const
473 { return const_cast<SwTableBox*>(this)->FindStartOfRowSpan( rTable, nMaxStep ); }
475 SwTableBox& FindEndOfRowSpan( const SwTable&, sal_uInt16 nMaxStep = USHRT_MAX );
476 const SwTableBox& FindEndOfRowSpan( const SwTable& rTable,
477 sal_uInt16 nMaxStep = USHRT_MAX ) const
478 { return const_cast<SwTableBox*>(this)->FindEndOfRowSpan( rTable, nMaxStep ); }
479 void RegisterToFormat( SwFmt& rFmt ) ;
482 class SwCellFrm;
483 class SW_DLLPUBLIC SwTableCellInfo : public ::boost::noncopyable
485 struct Impl;
486 ::std::auto_ptr<Impl> m_pImpl;
488 const SwCellFrm * getCellFrm() const ;
490 public:
491 SwTableCellInfo(const SwTable * pTable);
492 ~SwTableCellInfo();
494 bool getNext();
495 SwRect getRect() const;
496 const SwTableBox * getTableBox() const;
499 #endif //_SWTABLE_HXX
501 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */