xref: /trunk/main/sw/source/core/docnode/ndtbl1.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*efeef26fSAndrew Rist  * specific language governing permissions and limitations
18*efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "hintids.hxx"
28cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
29cdf0e10cSrcweir #include <editeng/boxitem.hxx>
30cdf0e10cSrcweir #include <editeng/brshitem.hxx>
31cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
32cdf0e10cSrcweir #include <fmtornt.hxx>
33cdf0e10cSrcweir #include <fmtfsize.hxx>
34cdf0e10cSrcweir #include <fmtlsplt.hxx>
35cdf0e10cSrcweir #include <fmtrowsplt.hxx>
36cdf0e10cSrcweir #include <tabcol.hxx>
37cdf0e10cSrcweir #include <frmatr.hxx>
38cdf0e10cSrcweir #include <cellfrm.hxx>
39cdf0e10cSrcweir #include <tabfrm.hxx>
40cdf0e10cSrcweir #include <cntfrm.hxx>
41cdf0e10cSrcweir #include <txtfrm.hxx>
42cdf0e10cSrcweir #include <svx/svxids.hrc>
43cdf0e10cSrcweir #include <doc.hxx>
44cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
45cdf0e10cSrcweir #include "pam.hxx"
46cdf0e10cSrcweir #include "swcrsr.hxx"
47cdf0e10cSrcweir #include "viscrs.hxx"
48cdf0e10cSrcweir #include "swtable.hxx"
49cdf0e10cSrcweir #include "htmltbl.hxx"
50cdf0e10cSrcweir #include "tblsel.hxx"
51cdf0e10cSrcweir #include "swtblfmt.hxx"
52cdf0e10cSrcweir #include "docary.hxx"
53cdf0e10cSrcweir #include "ndindex.hxx"
54cdf0e10cSrcweir #include "undobj.hxx"
55cdf0e10cSrcweir #include "switerator.hxx"
56cdf0e10cSrcweir #include <UndoTable.hxx>
57cdf0e10cSrcweir 
58cdf0e10cSrcweir using namespace ::com::sun::star;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 
61cdf0e10cSrcweir extern void ClearFEShellTabCols();
62cdf0e10cSrcweir 
63cdf0e10cSrcweir //siehe auch swtable.cxx
64cdf0e10cSrcweir #define COLFUZZY 20L
65cdf0e10cSrcweir 
IsSame(long nA,long nB)66cdf0e10cSrcweir inline sal_Bool IsSame( long nA, long nB ) { return  Abs(nA-nB) <= COLFUZZY; }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir class SwTblFmtCmp
69cdf0e10cSrcweir {
70cdf0e10cSrcweir public:
71cdf0e10cSrcweir     SwFrmFmt *pOld,
72cdf0e10cSrcweir              *pNew;
73cdf0e10cSrcweir     sal_Int16     nType;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir     SwTblFmtCmp( SwFrmFmt *pOld, SwFrmFmt *pNew, sal_Int16 nType );
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     static SwFrmFmt *FindNewFmt( SvPtrarr &rArr, SwFrmFmt*pOld, sal_Int16 nType );
78cdf0e10cSrcweir     static void Delete( SvPtrarr &rArr );
79cdf0e10cSrcweir };
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 
SwTblFmtCmp(SwFrmFmt * pO,SwFrmFmt * pN,sal_Int16 nT)82cdf0e10cSrcweir SwTblFmtCmp::SwTblFmtCmp( SwFrmFmt *pO, SwFrmFmt *pN, sal_Int16 nT )
83cdf0e10cSrcweir     : pOld ( pO ), pNew ( pN ), nType( nT )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
FindNewFmt(SvPtrarr & rArr,SwFrmFmt * pOld,sal_Int16 nType)87cdf0e10cSrcweir SwFrmFmt *SwTblFmtCmp::FindNewFmt( SvPtrarr &rArr, SwFrmFmt *pOld, sal_Int16 nType )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rArr.Count(); ++i )
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         SwTblFmtCmp *pCmp = (SwTblFmtCmp*)rArr[i];
92cdf0e10cSrcweir         if ( pCmp->pOld == pOld && pCmp->nType == nType )
93cdf0e10cSrcweir             return pCmp->pNew;
94cdf0e10cSrcweir     }
95cdf0e10cSrcweir     return 0;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
Delete(SvPtrarr & rArr)98cdf0e10cSrcweir void SwTblFmtCmp::Delete( SvPtrarr &rArr )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rArr.Count(); ++i )
101cdf0e10cSrcweir         delete (SwTblFmtCmp*)rArr[i];
102cdf0e10cSrcweir }
103cdf0e10cSrcweir 
lcl_GetStartEndCell(const SwCursor & rCrsr,SwLayoutFrm * & prStart,SwLayoutFrm * & prEnd)104cdf0e10cSrcweir void lcl_GetStartEndCell( const SwCursor& rCrsr,
105cdf0e10cSrcweir                         SwLayoutFrm *&prStart, SwLayoutFrm *&prEnd )
106cdf0e10cSrcweir {
107cdf0e10cSrcweir     ASSERT( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( sal_False ),
108cdf0e10cSrcweir             "Tabselection nicht auf Cnt." );
109cdf0e10cSrcweir 
110cdf0e10cSrcweir     Point aPtPos, aMkPos;
111cdf0e10cSrcweir     const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
112cdf0e10cSrcweir     if( pShCrsr )
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         aPtPos = pShCrsr->GetPtPos();
115cdf0e10cSrcweir         aMkPos = pShCrsr->GetMkPos();
116cdf0e10cSrcweir     }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     // robust:
119cdf0e10cSrcweir     SwCntntNode* pPointNd = rCrsr.GetCntntNode();
120cdf0e10cSrcweir     SwCntntNode* pMarkNd  = rCrsr.GetCntntNode(sal_False);
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     SwFrm* pPointFrm = pPointNd ? pPointNd->getLayoutFrm( pPointNd->GetDoc()->GetCurrentLayout(), &aPtPos ) : 0;
123cdf0e10cSrcweir     SwFrm* pMarkFrm  = pMarkNd  ? pMarkNd->getLayoutFrm( pMarkNd->GetDoc()->GetCurrentLayout(), &aMkPos )  : 0;
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     prStart = pPointFrm ? pPointFrm->GetUpper() : 0;
126cdf0e10cSrcweir     prEnd   = pMarkFrm  ? pMarkFrm->GetUpper() : 0;
127cdf0e10cSrcweir }
128cdf0e10cSrcweir 
lcl_GetBoxSel(const SwCursor & rCursor,SwSelBoxes & rBoxes,sal_Bool bAllCrsr=sal_False)129cdf0e10cSrcweir sal_Bool lcl_GetBoxSel( const SwCursor& rCursor, SwSelBoxes& rBoxes,
130cdf0e10cSrcweir                     sal_Bool bAllCrsr = sal_False )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     const SwTableCursor* pTblCrsr =
133cdf0e10cSrcweir         dynamic_cast<const SwTableCursor*>(&rCursor);
134cdf0e10cSrcweir     if( pTblCrsr )
135cdf0e10cSrcweir         ::GetTblSelCrs( *pTblCrsr, rBoxes );
136cdf0e10cSrcweir     else
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir         const SwPaM *pCurPam = &rCursor, *pSttPam = pCurPam;
139cdf0e10cSrcweir         do {
140cdf0e10cSrcweir             const SwNode* pNd = pCurPam->GetNode()->FindTableBoxStartNode();
141cdf0e10cSrcweir             if( pNd )
142cdf0e10cSrcweir             {
143cdf0e10cSrcweir                 SwTableBox* pBox = (SwTableBox*)pNd->FindTableNode()->GetTable().
144cdf0e10cSrcweir                                             GetTblBox( pNd->GetIndex() );
145cdf0e10cSrcweir                 rBoxes.Insert( pBox );
146cdf0e10cSrcweir             }
147cdf0e10cSrcweir         } while( bAllCrsr &&
148cdf0e10cSrcweir                 pSttPam != ( pCurPam = (SwPaM*)pCurPam->GetNext()) );
149cdf0e10cSrcweir     }
150cdf0e10cSrcweir     return 0 != rBoxes.Count();
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir /***********************************************************************
154cdf0e10cSrcweir #*  Class      :  SwDoc
155cdf0e10cSrcweir #*  Methoden   :  SetRowHeight(), GetRowHeight()
156cdf0e10cSrcweir #*  Datum      :  MA 17. May. 93
157cdf0e10cSrcweir #*  Update     :  JP 28.04.98
158cdf0e10cSrcweir #***********************************************************************/
159cdf0e10cSrcweir //Die Zeilenhoehe wird ausgehend von der Selektion ermittelt/gesetzt.
160cdf0e10cSrcweir //Ausgehend von jeder Zelle innerhalb der Selektion werden nach oben alle
161cdf0e10cSrcweir //Zeilen abgeklappert, die oberste Zeile erhaelt den gewuenschten Wert alle
162cdf0e10cSrcweir //tieferliegenden Zeilen einen entsprechenden Wert der sich aus der
163cdf0e10cSrcweir //Relation der alten und neuen Groesse der obersten Zeile und ihrer
164cdf0e10cSrcweir //eigenen Groesse ergiebt.
165cdf0e10cSrcweir //Alle veraenderten Zeilen erhalten ggf. ein eigenes FrmFmt.
166cdf0e10cSrcweir //Natuerlich darf jede Zeile nur einmal angefasst werden.
167cdf0e10cSrcweir 
InsertLine(SvPtrarr & rLineArr,SwTableLine * pLine)168cdf0e10cSrcweir inline void InsertLine( SvPtrarr& rLineArr, SwTableLine* pLine )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir     if( USHRT_MAX == rLineArr.GetPos( pLine ) )
171cdf0e10cSrcweir         rLineArr.Insert( pLine, rLineArr.Count() );
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir //-----------------------------------------------------------------------------
175cdf0e10cSrcweir 
lcl_IsAnLower(const SwTableLine * pLine,const SwTableLine * pAssumed)176cdf0e10cSrcweir sal_Bool lcl_IsAnLower( const SwTableLine *pLine, const SwTableLine *pAssumed )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir     const SwTableLine *pTmp = pAssumed->GetUpper() ?
179cdf0e10cSrcweir                                     pAssumed->GetUpper()->GetUpper() : 0;
180cdf0e10cSrcweir     while ( pTmp )
181cdf0e10cSrcweir     {
182cdf0e10cSrcweir         if ( pTmp == pLine )
183cdf0e10cSrcweir             return sal_True;
184cdf0e10cSrcweir         pTmp = pTmp->GetUpper() ? pTmp->GetUpper()->GetUpper() : 0;
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir     return sal_False;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir //-----------------------------------------------------------------------------
189cdf0e10cSrcweir 
190cdf0e10cSrcweir struct LinesAndTable
191cdf0e10cSrcweir {
192cdf0e10cSrcweir           SvPtrarr &rLines;
193cdf0e10cSrcweir     const SwTable  &rTable;
194cdf0e10cSrcweir           sal_Bool      bInsertLines;
195cdf0e10cSrcweir 
LinesAndTableLinesAndTable196cdf0e10cSrcweir     LinesAndTable( SvPtrarr &rL, const SwTable &rTbl ) :
197cdf0e10cSrcweir           rLines( rL ), rTable( rTbl ), bInsertLines( sal_True ) {}
198cdf0e10cSrcweir };
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 
201cdf0e10cSrcweir sal_Bool _FindLine( const _FndLine*& rpLine, void* pPara );
202cdf0e10cSrcweir 
_FindBox(const _FndBox * & rpBox,void * pPara)203cdf0e10cSrcweir sal_Bool _FindBox( const _FndBox*& rpBox, void* pPara )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     if ( rpBox->GetLines().Count() )
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir         ((LinesAndTable*)pPara)->bInsertLines = sal_True;
208cdf0e10cSrcweir         ((_FndBox*)rpBox)->GetLines().ForEach( _FindLine, pPara );
209cdf0e10cSrcweir         if ( ((LinesAndTable*)pPara)->bInsertLines )
210cdf0e10cSrcweir         {
211cdf0e10cSrcweir             const SwTableLines &rLines = rpBox->GetBox()
212cdf0e10cSrcweir                                     ? rpBox->GetBox()->GetTabLines()
213cdf0e10cSrcweir                                     : ((LinesAndTable*)pPara)->rTable.GetTabLines();
214cdf0e10cSrcweir             if ( rpBox->GetLines().Count() == rLines.Count() )
215cdf0e10cSrcweir             {
216cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
217cdf0e10cSrcweir                     ::InsertLine( ((LinesAndTable*)pPara)->rLines,
218cdf0e10cSrcweir                                   (SwTableLine*)rLines[i] );
219cdf0e10cSrcweir             }
220cdf0e10cSrcweir             else
221cdf0e10cSrcweir                 ((LinesAndTable*)pPara)->bInsertLines = sal_False;
222cdf0e10cSrcweir         }
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir     else if ( rpBox->GetBox() )
225cdf0e10cSrcweir         ::InsertLine( ((LinesAndTable*)pPara)->rLines,
226cdf0e10cSrcweir                       (SwTableLine*)rpBox->GetBox()->GetUpper() );
227cdf0e10cSrcweir     return sal_True;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
_FindLine(const _FndLine * & rpLine,void * pPara)230cdf0e10cSrcweir sal_Bool _FindLine( const _FndLine*& rpLine, void* pPara )
231cdf0e10cSrcweir {
232cdf0e10cSrcweir     ((_FndLine*)rpLine)->GetBoxes().ForEach( _FindBox, pPara );
233cdf0e10cSrcweir     return sal_True;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
lcl_CollectLines(SvPtrarr & rArr,const SwCursor & rCursor,bool bRemoveLines)236cdf0e10cSrcweir void lcl_CollectLines( SvPtrarr &rArr, const SwCursor& rCursor, bool bRemoveLines )
237cdf0e10cSrcweir {
238cdf0e10cSrcweir     //Zuerst die selektierten Boxen einsammeln.
239cdf0e10cSrcweir     SwSelBoxes aBoxes;
240cdf0e10cSrcweir     if( !::lcl_GetBoxSel( rCursor, aBoxes ))
241cdf0e10cSrcweir         return ;
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     //Die selektierte Struktur kopieren.
244cdf0e10cSrcweir     const SwTable &rTable = aBoxes[0]->GetSttNd()->FindTableNode()->GetTable();
245cdf0e10cSrcweir     LinesAndTable aPara( rArr, rTable );
246cdf0e10cSrcweir     _FndBox aFndBox( 0, 0 );
247cdf0e10cSrcweir     {
248cdf0e10cSrcweir         _FndPara aTmpPara( aBoxes, &aFndBox );
249cdf0e10cSrcweir         ((SwTableLines&)rTable.GetTabLines()).ForEach( &_FndLineCopyCol, &aTmpPara );
250cdf0e10cSrcweir     }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir     //Diejenigen Lines einsammeln, die nur selektierte Boxen enthalten.
253cdf0e10cSrcweir     const _FndBox *pTmp = &aFndBox;
254cdf0e10cSrcweir     ::_FindBox( pTmp, &aPara );
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     // Remove lines, that have a common superordinate row.
257cdf0e10cSrcweir     // (Not for row split)
258cdf0e10cSrcweir     if ( bRemoveLines )
259cdf0e10cSrcweir     {
260cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < rArr.Count(); ++i )
261cdf0e10cSrcweir         {
262cdf0e10cSrcweir             SwTableLine *pUpLine = (SwTableLine*)rArr[i];
263cdf0e10cSrcweir             for ( sal_uInt16 k = 0; k < rArr.Count(); ++k )
264cdf0e10cSrcweir             {
265cdf0e10cSrcweir                 if ( k != i && ::lcl_IsAnLower( pUpLine, (SwTableLine*)rArr[k] ) )
266cdf0e10cSrcweir                 {
267cdf0e10cSrcweir                     rArr.Remove( k );
268cdf0e10cSrcweir                     if ( k <= i )
269cdf0e10cSrcweir                         --i;
270cdf0e10cSrcweir                     --k;
271cdf0e10cSrcweir                 }
272cdf0e10cSrcweir             }
273cdf0e10cSrcweir         }
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir //-----------------------------------------------------------------------------
278cdf0e10cSrcweir 
lcl_ProcessRowAttr(SvPtrarr & rFmtCmp,SwTableLine * pLine,const SfxPoolItem & rNew)279cdf0e10cSrcweir void lcl_ProcessRowAttr( SvPtrarr& rFmtCmp, SwTableLine* pLine, const SfxPoolItem& rNew )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     SwFrmFmt *pNewFmt;
282cdf0e10cSrcweir     if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( rFmtCmp, pLine->GetFrmFmt(), 0 )))
283cdf0e10cSrcweir         pLine->ChgFrmFmt( (SwTableLineFmt*)pNewFmt );
284cdf0e10cSrcweir     else
285cdf0e10cSrcweir     {
286cdf0e10cSrcweir         SwFrmFmt *pOld = pLine->GetFrmFmt();
287cdf0e10cSrcweir         SwFrmFmt *pNew = pLine->ClaimFrmFmt();
288cdf0e10cSrcweir         pNew->SetFmtAttr( rNew );
289cdf0e10cSrcweir         rFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, 0 ), rFmtCmp.Count());
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir //-----------------------------------------------------------------------------
294cdf0e10cSrcweir 
295cdf0e10cSrcweir void lcl_ProcessBoxSize( SvPtrarr &rFmtCmp, SwTableBox *pBox, const SwFmtFrmSize &rNew );
296cdf0e10cSrcweir 
lcl_ProcessRowSize(SvPtrarr & rFmtCmp,SwTableLine * pLine,const SwFmtFrmSize & rNew)297cdf0e10cSrcweir void lcl_ProcessRowSize( SvPtrarr &rFmtCmp, SwTableLine *pLine, const SwFmtFrmSize &rNew )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir     lcl_ProcessRowAttr( rFmtCmp, pLine, rNew );
300cdf0e10cSrcweir     SwTableBoxes &rBoxes = pLine->GetTabBoxes();
301cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rBoxes.Count(); ++i )
302cdf0e10cSrcweir         ::lcl_ProcessBoxSize( rFmtCmp, rBoxes[i], rNew );
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir //-----------------------------------------------------------------------------
306cdf0e10cSrcweir 
lcl_ProcessBoxSize(SvPtrarr & rFmtCmp,SwTableBox * pBox,const SwFmtFrmSize & rNew)307cdf0e10cSrcweir void lcl_ProcessBoxSize( SvPtrarr &rFmtCmp, SwTableBox *pBox, const SwFmtFrmSize &rNew )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir     SwTableLines &rLines = pBox->GetTabLines();
310cdf0e10cSrcweir     if ( rLines.Count() )
311cdf0e10cSrcweir     {
312cdf0e10cSrcweir         SwFmtFrmSize aSz( rNew );
313cdf0e10cSrcweir         aSz.SetHeight( rNew.GetHeight() ? rNew.GetHeight() / rLines.Count() : 0 );
314cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
315cdf0e10cSrcweir             ::lcl_ProcessRowSize( rFmtCmp, rLines[i], aSz );
316cdf0e10cSrcweir     }
317cdf0e10cSrcweir }
318cdf0e10cSrcweir 
319cdf0e10cSrcweir //-----------------------------------------------------------------------------
320cdf0e10cSrcweir 
321cdf0e10cSrcweir /******************************************************************************
322cdf0e10cSrcweir  *              void SwDoc::SetRowSplit()
323cdf0e10cSrcweir  ******************************************************************************/
SetRowSplit(const SwCursor & rCursor,const SwFmtRowSplit & rNew)324cdf0e10cSrcweir void SwDoc::SetRowSplit( const SwCursor& rCursor, const SwFmtRowSplit &rNew )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
327cdf0e10cSrcweir     if( pTblNd )
328cdf0e10cSrcweir     {
329cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
330cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, false );
331cdf0e10cSrcweir 
332cdf0e10cSrcweir         if( aRowArr.Count() )
333cdf0e10cSrcweir         {
334cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
335cdf0e10cSrcweir             {
336cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
337cdf0e10cSrcweir             }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir             SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
340cdf0e10cSrcweir 
341cdf0e10cSrcweir             for( sal_uInt16 i = 0; i < aRowArr.Count(); ++i )
342cdf0e10cSrcweir                 ::lcl_ProcessRowAttr( aFmtCmp, (SwTableLine*)aRowArr[i], rNew );
343cdf0e10cSrcweir 
344cdf0e10cSrcweir             SwTblFmtCmp::Delete( aFmtCmp );
345cdf0e10cSrcweir             SetModified();
346cdf0e10cSrcweir         }
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 
351cdf0e10cSrcweir /******************************************************************************
352cdf0e10cSrcweir  *               SwTwips SwDoc::GetRowSplit() const
353cdf0e10cSrcweir  ******************************************************************************/
GetRowSplit(const SwCursor & rCursor,SwFmtRowSplit * & rpSz) const354cdf0e10cSrcweir void SwDoc::GetRowSplit( const SwCursor& rCursor, SwFmtRowSplit *& rpSz ) const
355cdf0e10cSrcweir {
356cdf0e10cSrcweir     rpSz = 0;
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
359cdf0e10cSrcweir     if( pTblNd )
360cdf0e10cSrcweir     {
361cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln der Lines.
362cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, false );
363cdf0e10cSrcweir 
364cdf0e10cSrcweir         if( aRowArr.Count() )
365cdf0e10cSrcweir         {
366cdf0e10cSrcweir             rpSz = &(SwFmtRowSplit&)((SwTableLine*)aRowArr[0])->
367cdf0e10cSrcweir                                                 GetFrmFmt()->GetRowSplit();
368cdf0e10cSrcweir 
369cdf0e10cSrcweir             for ( sal_uInt16 i = 1; i < aRowArr.Count() && rpSz; ++i )
370cdf0e10cSrcweir             {
371cdf0e10cSrcweir                 if ( (*rpSz).GetValue() != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetRowSplit().GetValue() )
372cdf0e10cSrcweir                     rpSz = 0;
373cdf0e10cSrcweir             }
374cdf0e10cSrcweir             if ( rpSz )
375cdf0e10cSrcweir                 rpSz = new SwFmtRowSplit( *rpSz );
376cdf0e10cSrcweir         }
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 
381cdf0e10cSrcweir /******************************************************************************
382cdf0e10cSrcweir  *              void SwDoc::SetRowHeight( SwTwips nNew )
383cdf0e10cSrcweir  ******************************************************************************/
SetRowHeight(const SwCursor & rCursor,const SwFmtFrmSize & rNew)384cdf0e10cSrcweir void SwDoc::SetRowHeight( const SwCursor& rCursor, const SwFmtFrmSize &rNew )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
387cdf0e10cSrcweir     if( pTblNd )
388cdf0e10cSrcweir     {
389cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
390cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, true );
391cdf0e10cSrcweir 
392cdf0e10cSrcweir         if( aRowArr.Count() )
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
395cdf0e10cSrcweir             {
396cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
397cdf0e10cSrcweir             }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir             SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
400cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < aRowArr.Count(); ++i )
401cdf0e10cSrcweir                 ::lcl_ProcessRowSize( aFmtCmp, (SwTableLine*)aRowArr[i], rNew );
402cdf0e10cSrcweir             SwTblFmtCmp::Delete( aFmtCmp );
403cdf0e10cSrcweir 
404cdf0e10cSrcweir             SetModified();
405cdf0e10cSrcweir         }
406cdf0e10cSrcweir     }
407cdf0e10cSrcweir }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 
410cdf0e10cSrcweir /******************************************************************************
411cdf0e10cSrcweir  *               SwTwips SwDoc::GetRowHeight() const
412cdf0e10cSrcweir  ******************************************************************************/
GetRowHeight(const SwCursor & rCursor,SwFmtFrmSize * & rpSz) const413cdf0e10cSrcweir void SwDoc::GetRowHeight( const SwCursor& rCursor, SwFmtFrmSize *& rpSz ) const
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     rpSz = 0;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
418cdf0e10cSrcweir     if( pTblNd )
419cdf0e10cSrcweir     {
420cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln der Lines.
421cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, true );
422cdf0e10cSrcweir 
423cdf0e10cSrcweir         if( aRowArr.Count() )
424cdf0e10cSrcweir         {
425cdf0e10cSrcweir             rpSz = &(SwFmtFrmSize&)((SwTableLine*)aRowArr[0])->
426cdf0e10cSrcweir                                                 GetFrmFmt()->GetFrmSize();
427cdf0e10cSrcweir 
428cdf0e10cSrcweir             for ( sal_uInt16 i = 1; i < aRowArr.Count() && rpSz; ++i )
429cdf0e10cSrcweir             {
430cdf0e10cSrcweir                 if ( *rpSz != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetFrmSize() )
431cdf0e10cSrcweir                     rpSz = 0;
432cdf0e10cSrcweir             }
433cdf0e10cSrcweir             if ( rpSz )
434cdf0e10cSrcweir                 rpSz = new SwFmtFrmSize( *rpSz );
435cdf0e10cSrcweir         }
436cdf0e10cSrcweir     }
437cdf0e10cSrcweir }
438cdf0e10cSrcweir 
BalanceRowHeight(const SwCursor & rCursor,sal_Bool bTstOnly)439cdf0e10cSrcweir sal_Bool SwDoc::BalanceRowHeight( const SwCursor& rCursor, sal_Bool bTstOnly )
440cdf0e10cSrcweir {
441cdf0e10cSrcweir     sal_Bool bRet = sal_False;
442cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
443cdf0e10cSrcweir     if( pTblNd )
444cdf0e10cSrcweir     {
445cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln der Lines.
446cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, true );
447cdf0e10cSrcweir 
448cdf0e10cSrcweir         if( 1 < aRowArr.Count() )
449cdf0e10cSrcweir         {
450cdf0e10cSrcweir             if( !bTstOnly )
451cdf0e10cSrcweir             {
452cdf0e10cSrcweir                 long nHeight = 0;
453cdf0e10cSrcweir                 sal_uInt16 i;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir                 for ( i = 0; i < aRowArr.Count(); ++i )
456cdf0e10cSrcweir                 {
457cdf0e10cSrcweir                     SwIterator<SwFrm,SwFmt> aIter( *((SwTableLine*)aRowArr[i])->GetFrmFmt() );
458cdf0e10cSrcweir                     SwFrm* pFrm = aIter.First();
459cdf0e10cSrcweir                     while ( pFrm )
460cdf0e10cSrcweir                     {
461cdf0e10cSrcweir                         nHeight = Max( nHeight, pFrm->Frm().Height() );
462cdf0e10cSrcweir                         pFrm = aIter.Next();
463cdf0e10cSrcweir                     }
464cdf0e10cSrcweir                 }
465cdf0e10cSrcweir                 SwFmtFrmSize aNew( ATT_MIN_SIZE, 0, nHeight );
466cdf0e10cSrcweir 
467cdf0e10cSrcweir                 if (GetIDocumentUndoRedo().DoesUndo())
468cdf0e10cSrcweir                 {
469cdf0e10cSrcweir                     GetIDocumentUndoRedo().AppendUndo(
470cdf0e10cSrcweir                             new SwUndoAttrTbl(*pTblNd));
471cdf0e10cSrcweir                 }
472cdf0e10cSrcweir 
473cdf0e10cSrcweir                 SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
474cdf0e10cSrcweir                 for( i = 0; i < aRowArr.Count(); ++i )
475cdf0e10cSrcweir                     ::lcl_ProcessRowSize( aFmtCmp, (SwTableLine*)aRowArr[i], aNew );
476cdf0e10cSrcweir                 SwTblFmtCmp::Delete( aFmtCmp );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir                 SetModified();
479cdf0e10cSrcweir             }
480cdf0e10cSrcweir             bRet = sal_True;
481cdf0e10cSrcweir         }
482cdf0e10cSrcweir     }
483cdf0e10cSrcweir     return bRet;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir /******************************************************************************
487cdf0e10cSrcweir  *              void SwDoc::SetRowBackground()
488cdf0e10cSrcweir  ******************************************************************************/
SetRowBackground(const SwCursor & rCursor,const SvxBrushItem & rNew)489cdf0e10cSrcweir void SwDoc::SetRowBackground( const SwCursor& rCursor, const SvxBrushItem &rNew )
490cdf0e10cSrcweir {
491cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
492cdf0e10cSrcweir     if( pTblNd )
493cdf0e10cSrcweir     {
494cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
495cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, true );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir         if( aRowArr.Count() )
498cdf0e10cSrcweir         {
499cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
500cdf0e10cSrcweir             {
501cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
502cdf0e10cSrcweir             }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir             SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
505cdf0e10cSrcweir 
506cdf0e10cSrcweir             for( sal_uInt16 i = 0; i < aRowArr.Count(); ++i )
507cdf0e10cSrcweir                 ::lcl_ProcessRowAttr( aFmtCmp, (SwTableLine*)aRowArr[i], rNew );
508cdf0e10cSrcweir 
509cdf0e10cSrcweir             SwTblFmtCmp::Delete( aFmtCmp );
510cdf0e10cSrcweir             SetModified();
511cdf0e10cSrcweir         }
512cdf0e10cSrcweir     }
513cdf0e10cSrcweir }
514cdf0e10cSrcweir 
515cdf0e10cSrcweir /******************************************************************************
516cdf0e10cSrcweir  *               SwTwips SwDoc::GetRowBackground() const
517cdf0e10cSrcweir  ******************************************************************************/
GetRowBackground(const SwCursor & rCursor,SvxBrushItem & rToFill) const518cdf0e10cSrcweir sal_Bool SwDoc::GetRowBackground( const SwCursor& rCursor, SvxBrushItem &rToFill ) const
519cdf0e10cSrcweir {
520cdf0e10cSrcweir     sal_Bool bRet = sal_False;
521cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
522cdf0e10cSrcweir     if( pTblNd )
523cdf0e10cSrcweir     {
524cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
525cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, true );
526cdf0e10cSrcweir 
527cdf0e10cSrcweir         if( aRowArr.Count() )
528cdf0e10cSrcweir         {
529cdf0e10cSrcweir             rToFill = ((SwTableLine*)aRowArr[0])->GetFrmFmt()->GetBackground();
530cdf0e10cSrcweir 
531cdf0e10cSrcweir             bRet = sal_True;
532cdf0e10cSrcweir             for ( sal_uInt16 i = 1; i < aRowArr.Count(); ++i )
533cdf0e10cSrcweir                 if ( rToFill != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetBackground() )
534cdf0e10cSrcweir                 {
535cdf0e10cSrcweir                     bRet = sal_False;
536cdf0e10cSrcweir                     break;
537cdf0e10cSrcweir                 }
538cdf0e10cSrcweir         }
539cdf0e10cSrcweir     }
540cdf0e10cSrcweir     return bRet;
541cdf0e10cSrcweir }
542cdf0e10cSrcweir 
543cdf0e10cSrcweir /***********************************************************************
544cdf0e10cSrcweir #*  Class      :  SwDoc
545cdf0e10cSrcweir #*  Methoden   :  SetTabBorders(), GetTabBorders()
546cdf0e10cSrcweir #*  Datum      :  MA 18. May. 93
547cdf0e10cSrcweir #*  Update     :  JP 29.04.98
548cdf0e10cSrcweir #***********************************************************************/
InsertCell(SvPtrarr & rCellArr,SwCellFrm * pCellFrm)549cdf0e10cSrcweir inline void InsertCell( SvPtrarr& rCellArr, SwCellFrm* pCellFrm )
550cdf0e10cSrcweir {
551cdf0e10cSrcweir     if( USHRT_MAX == rCellArr.GetPos( pCellFrm ) )
552cdf0e10cSrcweir         rCellArr.Insert( pCellFrm, rCellArr.Count() );
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir //-----------------------------------------------------------------------------
lcl_CollectCells(SvPtrarr & rArr,const SwRect & rUnion,SwTabFrm * pTab)556cdf0e10cSrcweir void lcl_CollectCells( SvPtrarr &rArr, const SwRect &rUnion,
557cdf0e10cSrcweir                           SwTabFrm *pTab )
558cdf0e10cSrcweir {
559cdf0e10cSrcweir     SwLayoutFrm *pCell = pTab->FirstCell();
560cdf0e10cSrcweir     do
561cdf0e10cSrcweir     {
562cdf0e10cSrcweir         // Wenn in der Zelle ein spaltiger Bereich sitzt, muessen wir
563cdf0e10cSrcweir         // uns erst wieder zur Zelle hochhangeln
564cdf0e10cSrcweir         while ( !pCell->IsCellFrm() )
565cdf0e10cSrcweir             pCell = pCell->GetUpper();
566cdf0e10cSrcweir         ASSERT( pCell, "Frame ist keine Zelle." );
567cdf0e10cSrcweir         if ( rUnion.IsOver( pCell->Frm() ) )
568cdf0e10cSrcweir             ::InsertCell( rArr, (SwCellFrm*)pCell );
569cdf0e10cSrcweir         //Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche)
570cdf0e10cSrcweir         SwLayoutFrm *pTmp = pCell;
571cdf0e10cSrcweir         do
572cdf0e10cSrcweir         {   pTmp = pTmp->GetNextLayoutLeaf();
573cdf0e10cSrcweir         } while ( pCell->IsAnLower( pTmp ) );
574cdf0e10cSrcweir         pCell = pTmp;
575cdf0e10cSrcweir     } while( pCell && pTab->IsAnLower( pCell ) );
576cdf0e10cSrcweir }
577cdf0e10cSrcweir 
SetTabBorders(const SwCursor & rCursor,const SfxItemSet & rSet)578cdf0e10cSrcweir void SwDoc::SetTabBorders( const SwCursor& rCursor, const SfxItemSet& rSet )
579cdf0e10cSrcweir {
580cdf0e10cSrcweir     SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
581cdf0e10cSrcweir     SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
582cdf0e10cSrcweir     if( !pTblNd )
583cdf0e10cSrcweir         return ;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir     SwLayoutFrm *pStart, *pEnd;
586cdf0e10cSrcweir     ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
587cdf0e10cSrcweir 
588cdf0e10cSrcweir     SwSelUnions aUnions;
589cdf0e10cSrcweir     ::MakeSelUnions( aUnions, pStart, pEnd );
590cdf0e10cSrcweir 
591cdf0e10cSrcweir     if( aUnions.Count() )
592cdf0e10cSrcweir     {
593cdf0e10cSrcweir         SwTable& rTable = pTblNd->GetTable();
594cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
595cdf0e10cSrcweir         {
596cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( new SwUndoAttrTbl(*pTblNd) );
597cdf0e10cSrcweir         }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir         SvPtrarr aFmtCmp( 255, 255 );
600cdf0e10cSrcweir         const SvxBoxItem* pSetBox;
601cdf0e10cSrcweir         const SvxBoxInfoItem *pSetBoxInfo;
602cdf0e10cSrcweir 
603cdf0e10cSrcweir         const SvxBorderLine* pLeft = 0;
604cdf0e10cSrcweir         const SvxBorderLine* pRight = 0;
605cdf0e10cSrcweir         const SvxBorderLine* pTop = 0;
606cdf0e10cSrcweir         const SvxBorderLine* pBottom = 0;
607cdf0e10cSrcweir         const SvxBorderLine* pHori = 0;
608cdf0e10cSrcweir         const SvxBorderLine* pVert = 0;
609cdf0e10cSrcweir         sal_Bool bHoriValid = sal_True, bVertValid = sal_True,
610cdf0e10cSrcweir              bTopValid = sal_True, bBottomValid = sal_True,
611cdf0e10cSrcweir              bLeftValid = sal_True, bRightValid = sal_True;
612cdf0e10cSrcweir 
613cdf0e10cSrcweir         // JP 21.07.95: die Flags im BoxInfo-Item entscheiden, wann eine
614cdf0e10cSrcweir         //              BorderLine gueltig ist!!
615cdf0e10cSrcweir         if( SFX_ITEM_SET == rSet.GetItemState( SID_ATTR_BORDER_INNER, sal_False,
616cdf0e10cSrcweir             (const SfxPoolItem**)&pSetBoxInfo) )
617cdf0e10cSrcweir         {
618cdf0e10cSrcweir             pHori = pSetBoxInfo->GetHori();
619cdf0e10cSrcweir             pVert = pSetBoxInfo->GetVert();
620cdf0e10cSrcweir 
621cdf0e10cSrcweir             bHoriValid = pSetBoxInfo->IsValid(VALID_HORI);
622cdf0e10cSrcweir             bVertValid = pSetBoxInfo->IsValid(VALID_VERT);
623cdf0e10cSrcweir 
624cdf0e10cSrcweir             // wollen wir die auswerten ??
625cdf0e10cSrcweir             bTopValid = pSetBoxInfo->IsValid(VALID_TOP);
626cdf0e10cSrcweir             bBottomValid = pSetBoxInfo->IsValid(VALID_BOTTOM);
627cdf0e10cSrcweir             bLeftValid = pSetBoxInfo->IsValid(VALID_LEFT);
628cdf0e10cSrcweir             bRightValid = pSetBoxInfo->IsValid(VALID_RIGHT);
629cdf0e10cSrcweir         }
630cdf0e10cSrcweir 
631cdf0e10cSrcweir         if( SFX_ITEM_SET == rSet.GetItemState( RES_BOX, sal_False,
632cdf0e10cSrcweir             (const SfxPoolItem**)&pSetBox) )
633cdf0e10cSrcweir         {
634cdf0e10cSrcweir             pLeft = pSetBox->GetLeft();
635cdf0e10cSrcweir             pRight = pSetBox->GetRight();
636cdf0e10cSrcweir             pTop = pSetBox->GetTop();
637cdf0e10cSrcweir             pBottom = pSetBox->GetBottom();
638cdf0e10cSrcweir         }
639cdf0e10cSrcweir         else
640cdf0e10cSrcweir         {
641cdf0e10cSrcweir             // nicht gesetzt, also keine gueltigen Werte
642cdf0e10cSrcweir             bTopValid = bBottomValid = bLeftValid = bRightValid = sal_False;
643cdf0e10cSrcweir             pSetBox = 0;
644cdf0e10cSrcweir         }
645cdf0e10cSrcweir 
646cdf0e10cSrcweir         sal_Bool bFirst = sal_True;
647cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
648cdf0e10cSrcweir         {
649cdf0e10cSrcweir             SwSelUnion *pUnion = aUnions[i];
650cdf0e10cSrcweir             SwTabFrm *pTab = pUnion->GetTable();
651cdf0e10cSrcweir             const SwRect &rUnion = pUnion->GetUnion();
652cdf0e10cSrcweir             const sal_Bool bLast  = i == aUnions.Count() - 1 ? sal_True : sal_False;
653cdf0e10cSrcweir 
654cdf0e10cSrcweir             SvPtrarr aCellArr( 255, 255 );
655cdf0e10cSrcweir             ::lcl_CollectCells( aCellArr, pUnion->GetUnion(), pTab );
656cdf0e10cSrcweir 
657cdf0e10cSrcweir             //Alle Zellenkanten, die mit dem UnionRect uebereinstimmen oder
658cdf0e10cSrcweir             //darueber hinausragen sind Aussenkanten. Alle anderen sind
659cdf0e10cSrcweir             //Innenkanten.
660cdf0e10cSrcweir             //neu: Die Aussenkanten koennen abhaengig davon, ob es sich um eine
661cdf0e10cSrcweir             //Start/Mittlere/Folge -Tabelle (bei Selektionen ueber FollowTabs)
662cdf0e10cSrcweir             //handelt doch keine Aussenkanten sein.
663cdf0e10cSrcweir             //Aussenkanten werden links, rechts, oben und unten gesetzt.
664cdf0e10cSrcweir             //Innenkanten werden nur oben und links gesetzt.
665cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < aCellArr.Count(); ++j )
666cdf0e10cSrcweir             {
667cdf0e10cSrcweir                 SwCellFrm *pCell = (SwCellFrm*)aCellArr[j];
668cdf0e10cSrcweir                 const sal_Bool bVert = pTab->IsVertical();
669cdf0e10cSrcweir                 const sal_Bool bRTL = pTab->IsRightToLeft();
670cdf0e10cSrcweir                 sal_Bool bTopOver, bLeftOver, bRightOver, bBottomOver;
671cdf0e10cSrcweir                 if ( bVert )
672cdf0e10cSrcweir                 {
673cdf0e10cSrcweir                     bTopOver = pCell->Frm().Right() >= rUnion.Right();
674cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Top() <= rUnion.Top();
675cdf0e10cSrcweir                     bRightOver = pCell->Frm().Bottom() >= rUnion.Bottom();
676cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Left() <= rUnion.Left();
677cdf0e10cSrcweir                 }
678cdf0e10cSrcweir                 else
679cdf0e10cSrcweir                 {
680cdf0e10cSrcweir                     bTopOver = pCell->Frm().Top() <= rUnion.Top();
681cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Left() <= rUnion.Left();
682cdf0e10cSrcweir                     bRightOver = pCell->Frm().Right() >= rUnion.Right();
683cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Bottom() >= rUnion.Bottom();
684cdf0e10cSrcweir                 }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir                 if ( bRTL )
687cdf0e10cSrcweir                 {
688cdf0e10cSrcweir                     sal_Bool bTmp = bRightOver;
689cdf0e10cSrcweir                     bRightOver = bLeftOver;
690cdf0e10cSrcweir                     bLeftOver = bTmp;
691cdf0e10cSrcweir                 }
692cdf0e10cSrcweir 
693cdf0e10cSrcweir                 //Grundsaetzlich nichts setzen in HeadlineRepeats.
694cdf0e10cSrcweir                 if ( pTab->IsFollow() &&
695cdf0e10cSrcweir                      ( pTab->IsInHeadline( *pCell ) ||
696cdf0e10cSrcweir                        // --> FME 2006-02-07 #126092# Same holds for follow flow rows.
697cdf0e10cSrcweir                        pCell->IsInFollowFlowRow() ) )
698cdf0e10cSrcweir                        // <--
699cdf0e10cSrcweir                     continue;
700cdf0e10cSrcweir 
701cdf0e10cSrcweir                 SvxBoxItem aBox( pCell->GetFmt()->GetBox() );
702cdf0e10cSrcweir 
703cdf0e10cSrcweir                 sal_Int16 nType = 0;
704cdf0e10cSrcweir 
705cdf0e10cSrcweir                 //Obere Kante
706cdf0e10cSrcweir                 if( bTopValid )
707cdf0e10cSrcweir                 {
708cdf0e10cSrcweir                     if ( bFirst && bTopOver )
709cdf0e10cSrcweir                     {
710cdf0e10cSrcweir                         aBox.SetLine( pTop, BOX_LINE_TOP );
711cdf0e10cSrcweir                         nType |= 0x0001;
712cdf0e10cSrcweir                     }
713cdf0e10cSrcweir                     else if ( bHoriValid )
714cdf0e10cSrcweir                     {
715cdf0e10cSrcweir                         aBox.SetLine( 0, BOX_LINE_TOP );
716cdf0e10cSrcweir                         nType |= 0x0002;
717cdf0e10cSrcweir                     }
718cdf0e10cSrcweir                 }
719cdf0e10cSrcweir 
720cdf0e10cSrcweir                 //Linke Kante
721cdf0e10cSrcweir                 if ( bLeftOver )
722cdf0e10cSrcweir                 {
723cdf0e10cSrcweir                     if( bLeftValid )
724cdf0e10cSrcweir                     {
725cdf0e10cSrcweir                         aBox.SetLine( pLeft, BOX_LINE_LEFT );
726cdf0e10cSrcweir                         nType |= 0x0004;
727cdf0e10cSrcweir                     }
728cdf0e10cSrcweir                 }
729cdf0e10cSrcweir                 else if( bVertValid )
730cdf0e10cSrcweir                 {
731cdf0e10cSrcweir                     aBox.SetLine( pVert, BOX_LINE_LEFT );
732cdf0e10cSrcweir                     nType |= 0x0008;
733cdf0e10cSrcweir                 }
734cdf0e10cSrcweir 
735cdf0e10cSrcweir                 //Rechte Kante
736cdf0e10cSrcweir                 if( bRightValid )
737cdf0e10cSrcweir                 {
738cdf0e10cSrcweir                     if ( bRightOver )
739cdf0e10cSrcweir                     {
740cdf0e10cSrcweir                         aBox.SetLine( pRight, BOX_LINE_RIGHT );
741cdf0e10cSrcweir                         nType |= 0x0010;
742cdf0e10cSrcweir                     }
743cdf0e10cSrcweir                     else if ( bVertValid )
744cdf0e10cSrcweir                     {
745cdf0e10cSrcweir                         aBox.SetLine( 0, BOX_LINE_RIGHT );
746cdf0e10cSrcweir                         nType |= 0x0020;
747cdf0e10cSrcweir                     }
748cdf0e10cSrcweir                 }
749cdf0e10cSrcweir 
750cdf0e10cSrcweir                 //Untere Kante
751cdf0e10cSrcweir                 if ( bLast && bBottomOver )
752cdf0e10cSrcweir                 {
753cdf0e10cSrcweir                     if( bBottomValid )
754cdf0e10cSrcweir                     {
755cdf0e10cSrcweir                         aBox.SetLine( pBottom, BOX_LINE_BOTTOM );
756cdf0e10cSrcweir                         nType |= 0x0040;
757cdf0e10cSrcweir                     }
758cdf0e10cSrcweir                 }
759cdf0e10cSrcweir                 else if( bHoriValid )
760cdf0e10cSrcweir                 {
761cdf0e10cSrcweir                     aBox.SetLine( pHori, BOX_LINE_BOTTOM );
762cdf0e10cSrcweir                     nType |= 0x0080;
763cdf0e10cSrcweir                 }
764cdf0e10cSrcweir 
765cdf0e10cSrcweir                 if( pSetBox )
766cdf0e10cSrcweir                 {
767cdf0e10cSrcweir                     static sal_uInt16 __READONLY_DATA aBorders[] = {
768cdf0e10cSrcweir                         BOX_LINE_BOTTOM, BOX_LINE_TOP,
769cdf0e10cSrcweir                         BOX_LINE_RIGHT, BOX_LINE_LEFT };
770cdf0e10cSrcweir                     const sal_uInt16* pBrd = aBorders;
771cdf0e10cSrcweir                     for( int k = 0; k < 4; ++k, ++pBrd )
772cdf0e10cSrcweir                         aBox.SetDistance( pSetBox->GetDistance( *pBrd ), *pBrd );
773cdf0e10cSrcweir                 }
774cdf0e10cSrcweir 
775cdf0e10cSrcweir                 SwTableBox *pBox = (SwTableBox*)pCell->GetTabBox();
776cdf0e10cSrcweir                 SwFrmFmt *pNewFmt;
777cdf0e10cSrcweir                 if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( aFmtCmp, pBox->GetFrmFmt(), nType )))
778cdf0e10cSrcweir                     pBox->ChgFrmFmt( (SwTableBoxFmt*)pNewFmt );
779cdf0e10cSrcweir                 else
780cdf0e10cSrcweir                 {
781cdf0e10cSrcweir                     SwFrmFmt *pOld = pBox->GetFrmFmt();
782cdf0e10cSrcweir                     SwFrmFmt *pNew = pBox->ClaimFrmFmt();
783cdf0e10cSrcweir                     pNew->SetFmtAttr( aBox );
784cdf0e10cSrcweir                     aFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, nType ), aFmtCmp.Count());
785cdf0e10cSrcweir                 }
786cdf0e10cSrcweir             }
787cdf0e10cSrcweir 
788cdf0e10cSrcweir             bFirst = sal_False;
789cdf0e10cSrcweir         }
790cdf0e10cSrcweir 
791cdf0e10cSrcweir         SwHTMLTableLayout *pTableLayout = rTable.GetHTMLTableLayout();
792cdf0e10cSrcweir         if( pTableLayout )
793cdf0e10cSrcweir         {
794cdf0e10cSrcweir             SwCntntFrm* pFrm = rCursor.GetCntntNode()->getLayoutFrm( rCursor.GetCntntNode()->GetDoc()->GetCurrentLayout() );
795cdf0e10cSrcweir             SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
796cdf0e10cSrcweir 
797cdf0e10cSrcweir             pTableLayout->BordersChanged(
798cdf0e10cSrcweir                 pTableLayout->GetBrowseWidthByTabFrm( *pTabFrm ), sal_True );
799cdf0e10cSrcweir         }
800cdf0e10cSrcweir         SwTblFmtCmp::Delete( aFmtCmp );
801cdf0e10cSrcweir         ::ClearFEShellTabCols();
802cdf0e10cSrcweir         SetModified();
803cdf0e10cSrcweir     }
804cdf0e10cSrcweir }
805cdf0e10cSrcweir 
lcl_SetLineStyle(SvxBorderLine * pToSet,const Color * pColor,const SvxBorderLine * pBorderLine)806cdf0e10cSrcweir void lcl_SetLineStyle( SvxBorderLine *pToSet,
807cdf0e10cSrcweir                           const Color *pColor, const SvxBorderLine *pBorderLine)
808cdf0e10cSrcweir {
809cdf0e10cSrcweir     if ( pBorderLine )
810cdf0e10cSrcweir     {
811cdf0e10cSrcweir         if ( !pColor )
812cdf0e10cSrcweir         {
813cdf0e10cSrcweir             Color aTmp( pToSet->GetColor() );
814cdf0e10cSrcweir             *pToSet = *pBorderLine;
815cdf0e10cSrcweir             pToSet->SetColor( aTmp );
816cdf0e10cSrcweir         }
817cdf0e10cSrcweir         else
818cdf0e10cSrcweir             *pToSet = *pBorderLine;
819cdf0e10cSrcweir     }
820cdf0e10cSrcweir     if ( pColor )
821cdf0e10cSrcweir         pToSet->SetColor( *pColor );
822cdf0e10cSrcweir }
823cdf0e10cSrcweir 
SetTabLineStyle(const SwCursor & rCursor,const Color * pColor,sal_Bool bSetLine,const SvxBorderLine * pBorderLine)824cdf0e10cSrcweir void SwDoc::SetTabLineStyle( const SwCursor& rCursor,
825cdf0e10cSrcweir                              const Color* pColor, sal_Bool bSetLine,
826cdf0e10cSrcweir                              const SvxBorderLine* pBorderLine )
827cdf0e10cSrcweir {
828cdf0e10cSrcweir     SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
829cdf0e10cSrcweir     SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
830cdf0e10cSrcweir     if( !pTblNd )
831cdf0e10cSrcweir         return ;
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     SwLayoutFrm *pStart, *pEnd;
834cdf0e10cSrcweir     ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
835cdf0e10cSrcweir 
836cdf0e10cSrcweir     SwSelUnions aUnions;
837cdf0e10cSrcweir     ::MakeSelUnions( aUnions, pStart, pEnd );
838cdf0e10cSrcweir 
839cdf0e10cSrcweir     if( aUnions.Count() )
840cdf0e10cSrcweir     {
841cdf0e10cSrcweir         SwTable& rTable = pTblNd->GetTable();
842cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
843cdf0e10cSrcweir         {
844cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
845cdf0e10cSrcweir         }
846cdf0e10cSrcweir 
847cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
848cdf0e10cSrcweir         {
849cdf0e10cSrcweir             SwSelUnion *pUnion = aUnions[i];
850cdf0e10cSrcweir             SwTabFrm *pTab = pUnion->GetTable();
851cdf0e10cSrcweir             SvPtrarr aCellArr( 255, 255 );
852cdf0e10cSrcweir             ::lcl_CollectCells( aCellArr, pUnion->GetUnion(), pTab );
853cdf0e10cSrcweir 
854cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < aCellArr.Count(); ++j )
855cdf0e10cSrcweir             {
856cdf0e10cSrcweir                 SwCellFrm *pCell = ( SwCellFrm* )aCellArr[j];
857cdf0e10cSrcweir 
858cdf0e10cSrcweir                 //Grundsaetzlich nichts setzen in HeadlineRepeats.
859cdf0e10cSrcweir                 if ( pTab->IsFollow() && pTab->IsInHeadline( *pCell ) )
860cdf0e10cSrcweir                     continue;
861cdf0e10cSrcweir 
862cdf0e10cSrcweir                 ((SwTableBox*)pCell->GetTabBox())->ClaimFrmFmt();
863cdf0e10cSrcweir                 SwFrmFmt *pFmt = pCell->GetFmt();
864cdf0e10cSrcweir                 SvxBoxItem aBox( pFmt->GetBox() );
865cdf0e10cSrcweir 
866cdf0e10cSrcweir                 if ( !pBorderLine && bSetLine )
867cdf0e10cSrcweir                     aBox = *(SvxBoxItem*)::GetDfltAttr( RES_BOX );
868cdf0e10cSrcweir                 else
869cdf0e10cSrcweir                 {
870cdf0e10cSrcweir                     if ( aBox.GetTop() )
871cdf0e10cSrcweir                         ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetTop(),
872cdf0e10cSrcweir                                         pColor, pBorderLine );
873cdf0e10cSrcweir                     if ( aBox.GetBottom() )
874cdf0e10cSrcweir                         ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetBottom(),
875cdf0e10cSrcweir                                         pColor, pBorderLine );
876cdf0e10cSrcweir                     if ( aBox.GetLeft() )
877cdf0e10cSrcweir                         ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetLeft(),
878cdf0e10cSrcweir                                         pColor, pBorderLine );
879cdf0e10cSrcweir                     if ( aBox.GetRight() )
880cdf0e10cSrcweir                         ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetRight(),
881cdf0e10cSrcweir                                         pColor, pBorderLine );
882cdf0e10cSrcweir                 }
883cdf0e10cSrcweir                 pFmt->SetFmtAttr( aBox );
884cdf0e10cSrcweir             }
885cdf0e10cSrcweir         }
886cdf0e10cSrcweir 
887cdf0e10cSrcweir         SwHTMLTableLayout *pTableLayout = rTable.GetHTMLTableLayout();
888cdf0e10cSrcweir         if( pTableLayout )
889cdf0e10cSrcweir         {
890cdf0e10cSrcweir             SwCntntFrm* pFrm = rCursor.GetCntntNode()->getLayoutFrm( rCursor.GetCntntNode()->GetDoc()->GetCurrentLayout() );
891cdf0e10cSrcweir             SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
892cdf0e10cSrcweir 
893cdf0e10cSrcweir             pTableLayout->BordersChanged(
894cdf0e10cSrcweir                 pTableLayout->GetBrowseWidthByTabFrm( *pTabFrm ), sal_True );
895cdf0e10cSrcweir         }
896cdf0e10cSrcweir         ::ClearFEShellTabCols();
897cdf0e10cSrcweir         SetModified();
898cdf0e10cSrcweir     }
899cdf0e10cSrcweir }
900cdf0e10cSrcweir 
GetTabBorders(const SwCursor & rCursor,SfxItemSet & rSet) const901cdf0e10cSrcweir void SwDoc::GetTabBorders( const SwCursor& rCursor, SfxItemSet& rSet ) const
902cdf0e10cSrcweir {
903cdf0e10cSrcweir     SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
904cdf0e10cSrcweir     SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
905cdf0e10cSrcweir     if( !pTblNd )
906cdf0e10cSrcweir         return ;
907cdf0e10cSrcweir 
908cdf0e10cSrcweir     SwLayoutFrm *pStart, *pEnd;
909cdf0e10cSrcweir     ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
910cdf0e10cSrcweir 
911cdf0e10cSrcweir     SwSelUnions aUnions;
912cdf0e10cSrcweir     ::MakeSelUnions( aUnions, pStart, pEnd );
913cdf0e10cSrcweir 
914cdf0e10cSrcweir     if( aUnions.Count() )
915cdf0e10cSrcweir     {
916cdf0e10cSrcweir         SvxBoxItem     aSetBox    ((const SvxBoxItem    &) rSet.Get(RES_BOX    ));
917cdf0e10cSrcweir         SvxBoxInfoItem aSetBoxInfo((const SvxBoxInfoItem&) rSet.Get(SID_ATTR_BORDER_INNER));
918cdf0e10cSrcweir 
919cdf0e10cSrcweir         sal_Bool bTopSet      = sal_False,
920cdf0e10cSrcweir              bBottomSet   = sal_False,
921cdf0e10cSrcweir              bLeftSet     = sal_False,
922cdf0e10cSrcweir              bRightSet    = sal_False,
923cdf0e10cSrcweir              bHoriSet     = sal_False,
924cdf0e10cSrcweir              bVertSet     = sal_False,
925cdf0e10cSrcweir              bDistanceSet = sal_False;
926cdf0e10cSrcweir 
927cdf0e10cSrcweir         aSetBoxInfo.ResetFlags();
928cdf0e10cSrcweir 
929cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
930cdf0e10cSrcweir         {
931cdf0e10cSrcweir             SwSelUnion *pUnion = aUnions[i];
932cdf0e10cSrcweir             const SwTabFrm *pTab = pUnion->GetTable();
933cdf0e10cSrcweir             const SwRect &rUnion = pUnion->GetUnion();
934cdf0e10cSrcweir             const sal_Bool bFirst = i == 0 ? sal_True : sal_False;
935cdf0e10cSrcweir             const sal_Bool bLast  = i == aUnions.Count() - 1 ? sal_True : sal_False;
936cdf0e10cSrcweir 
937cdf0e10cSrcweir             SvPtrarr aCellArr( 255, 255 );
938cdf0e10cSrcweir             ::lcl_CollectCells( aCellArr, rUnion, (SwTabFrm*)pTab );
939cdf0e10cSrcweir 
940cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < aCellArr.Count(); ++j )
941cdf0e10cSrcweir             {
942cdf0e10cSrcweir                 const SwCellFrm *pCell = (const SwCellFrm*)aCellArr[j];
943cdf0e10cSrcweir                 const sal_Bool bVert = pTab->IsVertical();
944cdf0e10cSrcweir                 const sal_Bool bRTL = pTab->IsRightToLeft();
945cdf0e10cSrcweir                 sal_Bool bTopOver, bLeftOver, bRightOver, bBottomOver;
946cdf0e10cSrcweir                 if ( bVert )
947cdf0e10cSrcweir                 {
948cdf0e10cSrcweir                     bTopOver = pCell->Frm().Right() >= rUnion.Right();
949cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Top() <= rUnion.Top();
950cdf0e10cSrcweir                     bRightOver = pCell->Frm().Bottom() >= rUnion.Bottom();
951cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Left() <= rUnion.Left();
952cdf0e10cSrcweir                 }
953cdf0e10cSrcweir                 else
954cdf0e10cSrcweir                 {
955cdf0e10cSrcweir                     bTopOver = pCell->Frm().Top() <= rUnion.Top();
956cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Left() <= rUnion.Left();
957cdf0e10cSrcweir                     bRightOver = pCell->Frm().Right() >= rUnion.Right();
958cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Bottom() >= rUnion.Bottom();
959cdf0e10cSrcweir                 }
960cdf0e10cSrcweir 
961cdf0e10cSrcweir                 if ( bRTL )
962cdf0e10cSrcweir                 {
963cdf0e10cSrcweir                     sal_Bool bTmp = bRightOver;
964cdf0e10cSrcweir                     bRightOver = bLeftOver;
965cdf0e10cSrcweir                     bLeftOver = bTmp;
966cdf0e10cSrcweir                 }
967cdf0e10cSrcweir 
968cdf0e10cSrcweir                 const SwFrmFmt  *pFmt  = pCell->GetFmt();
969cdf0e10cSrcweir                 const SvxBoxItem  &rBox  = pFmt->GetBox();
970cdf0e10cSrcweir 
971cdf0e10cSrcweir                 //Obere Kante
972cdf0e10cSrcweir                 if ( bFirst && bTopOver )
973cdf0e10cSrcweir                 {
974cdf0e10cSrcweir                     if (aSetBoxInfo.IsValid(VALID_TOP))
975cdf0e10cSrcweir                     {
976cdf0e10cSrcweir                         if ( !bTopSet )
977cdf0e10cSrcweir                         {   bTopSet = sal_True;
978cdf0e10cSrcweir                             aSetBox.SetLine( rBox.GetTop(), BOX_LINE_TOP );
979cdf0e10cSrcweir                         }
980cdf0e10cSrcweir                         else if ((aSetBox.GetTop() && rBox.GetTop() &&
981cdf0e10cSrcweir                                  !(*aSetBox.GetTop() == *rBox.GetTop())) ||
982cdf0e10cSrcweir                                  ((!aSetBox.GetTop()) ^ (!rBox.GetTop()))) // XOR-Ausdruck ist sal_True, wenn genau einer der beiden Pointer 0 ist
983cdf0e10cSrcweir                         {
984cdf0e10cSrcweir                             aSetBoxInfo.SetValid(VALID_TOP, sal_False );
985cdf0e10cSrcweir                             aSetBox.SetLine( 0, BOX_LINE_TOP );
986cdf0e10cSrcweir                         }
987cdf0e10cSrcweir                     }
988cdf0e10cSrcweir                 }
989cdf0e10cSrcweir 
990cdf0e10cSrcweir                 //Linke Kante
991cdf0e10cSrcweir                 if ( bLeftOver )
992cdf0e10cSrcweir                 {
993cdf0e10cSrcweir                     if (aSetBoxInfo.IsValid(VALID_LEFT))
994cdf0e10cSrcweir                     {
995cdf0e10cSrcweir                         if ( !bLeftSet )
996cdf0e10cSrcweir                         {   bLeftSet = sal_True;
997cdf0e10cSrcweir                             aSetBox.SetLine( rBox.GetLeft(), BOX_LINE_LEFT );
998cdf0e10cSrcweir                         }
999cdf0e10cSrcweir                         else if ((aSetBox.GetLeft() && rBox.GetLeft() &&
1000cdf0e10cSrcweir                                  !(*aSetBox.GetLeft() == *rBox.GetLeft())) ||
1001cdf0e10cSrcweir                                  ((!aSetBox.GetLeft()) ^ (!rBox.GetLeft())))
1002cdf0e10cSrcweir                         {
1003cdf0e10cSrcweir                             aSetBoxInfo.SetValid(VALID_LEFT, sal_False );
1004cdf0e10cSrcweir                             aSetBox.SetLine( 0, BOX_LINE_LEFT );
1005cdf0e10cSrcweir                         }
1006cdf0e10cSrcweir                     }
1007cdf0e10cSrcweir                 }
1008cdf0e10cSrcweir                 else
1009cdf0e10cSrcweir                 {
1010cdf0e10cSrcweir                     if (aSetBoxInfo.IsValid(VALID_VERT))
1011cdf0e10cSrcweir                     {
1012cdf0e10cSrcweir                         if ( !bVertSet )
1013cdf0e10cSrcweir                         {   bVertSet = sal_True;
1014cdf0e10cSrcweir                             aSetBoxInfo.SetLine( rBox.GetLeft(), BOXINFO_LINE_VERT );
1015cdf0e10cSrcweir                         }
1016cdf0e10cSrcweir                         else if ((aSetBoxInfo.GetVert() && rBox.GetLeft() &&
1017cdf0e10cSrcweir                                  !(*aSetBoxInfo.GetVert() == *rBox.GetLeft())) ||
1018cdf0e10cSrcweir                                  ((!aSetBoxInfo.GetVert()) ^ (!rBox.GetLeft())))
1019cdf0e10cSrcweir                         {   aSetBoxInfo.SetValid( VALID_VERT, sal_False );
1020cdf0e10cSrcweir                             aSetBoxInfo.SetLine( 0, BOXINFO_LINE_VERT );
1021cdf0e10cSrcweir                         }
1022cdf0e10cSrcweir                     }
1023cdf0e10cSrcweir                 }
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir                 //Rechte Kante
1026cdf0e10cSrcweir                 if ( aSetBoxInfo.IsValid(VALID_RIGHT) && bRightOver )
1027cdf0e10cSrcweir                 {
1028cdf0e10cSrcweir                     if ( !bRightSet )
1029cdf0e10cSrcweir                     {   bRightSet = sal_True;
1030cdf0e10cSrcweir                         aSetBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
1031cdf0e10cSrcweir                     }
1032cdf0e10cSrcweir                     else if ((aSetBox.GetRight() && rBox.GetRight() &&
1033cdf0e10cSrcweir                              !(*aSetBox.GetRight() == *rBox.GetRight())) ||
1034cdf0e10cSrcweir                              (!aSetBox.GetRight() ^ !rBox.GetRight()))
1035cdf0e10cSrcweir                     {   aSetBoxInfo.SetValid( VALID_RIGHT, sal_False );
1036cdf0e10cSrcweir                         aSetBox.SetLine( 0, BOX_LINE_RIGHT );
1037cdf0e10cSrcweir                     }
1038cdf0e10cSrcweir                 }
1039cdf0e10cSrcweir 
1040cdf0e10cSrcweir                 //Untere Kante
1041cdf0e10cSrcweir                 if ( bLast && bBottomOver )
1042cdf0e10cSrcweir                 {
1043cdf0e10cSrcweir                     if ( aSetBoxInfo.IsValid(VALID_BOTTOM) )
1044cdf0e10cSrcweir                     {
1045cdf0e10cSrcweir                         if ( !bBottomSet )
1046cdf0e10cSrcweir                         {   bBottomSet = sal_True;
1047cdf0e10cSrcweir                             aSetBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
1048cdf0e10cSrcweir                         }
1049cdf0e10cSrcweir                         else if ((aSetBox.GetBottom() && rBox.GetBottom() &&
1050cdf0e10cSrcweir                                  !(*aSetBox.GetBottom() == *rBox.GetBottom())) ||
1051cdf0e10cSrcweir                                  (!aSetBox.GetBottom() ^ !rBox.GetBottom()))
1052cdf0e10cSrcweir                         {   aSetBoxInfo.SetValid( VALID_BOTTOM, sal_False );
1053cdf0e10cSrcweir                             aSetBox.SetLine( 0, BOX_LINE_BOTTOM );
1054cdf0e10cSrcweir                         }
1055cdf0e10cSrcweir                     }
1056cdf0e10cSrcweir                 }
1057cdf0e10cSrcweir                 //in allen Zeilen ausser der letzten werden die
1058cdf0e10cSrcweir                 // horiz. Linien aus der Bottom-Linie entnommen
1059cdf0e10cSrcweir                 else
1060cdf0e10cSrcweir                 {
1061cdf0e10cSrcweir                     if (aSetBoxInfo.IsValid(VALID_HORI))
1062cdf0e10cSrcweir                     {
1063cdf0e10cSrcweir                         if ( !bHoriSet )
1064cdf0e10cSrcweir                         {   bHoriSet = sal_True;
1065cdf0e10cSrcweir                             aSetBoxInfo.SetLine( rBox.GetBottom(), BOXINFO_LINE_HORI );
1066cdf0e10cSrcweir                         }
1067cdf0e10cSrcweir                         else if ((aSetBoxInfo.GetHori() && rBox.GetBottom() &&
1068cdf0e10cSrcweir                                  !(*aSetBoxInfo.GetHori() == *rBox.GetBottom())) ||
1069cdf0e10cSrcweir                                  ((!aSetBoxInfo.GetHori()) ^ (!rBox.GetBottom())))
1070cdf0e10cSrcweir                         {
1071cdf0e10cSrcweir                             aSetBoxInfo.SetValid( VALID_HORI, sal_False );
1072cdf0e10cSrcweir                             aSetBoxInfo.SetLine( 0, BOXINFO_LINE_HORI );
1073cdf0e10cSrcweir                         }
1074cdf0e10cSrcweir                     }
1075cdf0e10cSrcweir                 }
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir                 // Abstand zum Text
1078cdf0e10cSrcweir                 if (aSetBoxInfo.IsValid(VALID_DISTANCE))
1079cdf0e10cSrcweir                 {
1080cdf0e10cSrcweir                     static sal_uInt16 __READONLY_DATA aBorders[] = {
1081cdf0e10cSrcweir                         BOX_LINE_BOTTOM, BOX_LINE_TOP,
1082cdf0e10cSrcweir                         BOX_LINE_RIGHT, BOX_LINE_LEFT };
1083cdf0e10cSrcweir                     const sal_uInt16* pBrd = aBorders;
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir                     if( !bDistanceSet )     // bei 1. Durchlauf erstmal setzen
1086cdf0e10cSrcweir                     {
1087cdf0e10cSrcweir                         bDistanceSet = sal_True;
1088cdf0e10cSrcweir                         for( int k = 0; k < 4; ++k, ++pBrd )
1089cdf0e10cSrcweir                             aSetBox.SetDistance( rBox.GetDistance( *pBrd ),
1090cdf0e10cSrcweir                                                 *pBrd );
1091cdf0e10cSrcweir                     }
1092cdf0e10cSrcweir                     else
1093cdf0e10cSrcweir                     {
1094cdf0e10cSrcweir                         for( int k = 0; k < 4; ++k, ++pBrd )
1095cdf0e10cSrcweir                             if( aSetBox.GetDistance( *pBrd ) !=
1096cdf0e10cSrcweir                                 rBox.GetDistance( *pBrd ) )
1097cdf0e10cSrcweir                             {
1098cdf0e10cSrcweir                                 aSetBoxInfo.SetValid( VALID_DISTANCE, sal_False );
1099cdf0e10cSrcweir                                 aSetBox.SetDistance( (sal_uInt16) 0 );
1100cdf0e10cSrcweir                                 break;
1101cdf0e10cSrcweir                             }
1102cdf0e10cSrcweir                     }
1103cdf0e10cSrcweir                 }
1104cdf0e10cSrcweir             }
1105cdf0e10cSrcweir         }
1106cdf0e10cSrcweir         rSet.Put( aSetBox );
1107cdf0e10cSrcweir         rSet.Put( aSetBoxInfo );
1108cdf0e10cSrcweir     }
1109cdf0e10cSrcweir }
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir /***********************************************************************
1112cdf0e10cSrcweir #*  Class      :  SwDoc
1113cdf0e10cSrcweir #*  Methoden   :  SetBoxAttr
1114cdf0e10cSrcweir #*  Datum      :  MA 18. Dec. 96
1115cdf0e10cSrcweir #*  Update     :  JP 29.04.98
1116cdf0e10cSrcweir #***********************************************************************/
SetBoxAttr(const SwCursor & rCursor,const SfxPoolItem & rNew)1117cdf0e10cSrcweir void SwDoc::SetBoxAttr( const SwCursor& rCursor, const SfxPoolItem &rNew )
1118cdf0e10cSrcweir {
1119cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
1120cdf0e10cSrcweir     SwSelBoxes aBoxes;
1121cdf0e10cSrcweir     if( pTblNd && ::lcl_GetBoxSel( rCursor, aBoxes, sal_True ) )
1122cdf0e10cSrcweir     {
1123cdf0e10cSrcweir         SwTable& rTable = pTblNd->GetTable();
1124cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
1125cdf0e10cSrcweir         {
1126cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( new SwUndoAttrTbl(*pTblNd) );
1127cdf0e10cSrcweir         }
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir         SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aBoxes.Count()) ), 255 );
1130cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < aBoxes.Count(); ++i )
1131cdf0e10cSrcweir         {
1132cdf0e10cSrcweir             SwTableBox *pBox = aBoxes[i];
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir             SwFrmFmt *pNewFmt;
1135cdf0e10cSrcweir             if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( aFmtCmp, pBox->GetFrmFmt(), 0 )))
1136cdf0e10cSrcweir                 pBox->ChgFrmFmt( (SwTableBoxFmt*)pNewFmt );
1137cdf0e10cSrcweir             else
1138cdf0e10cSrcweir             {
1139cdf0e10cSrcweir                 SwFrmFmt *pOld = pBox->GetFrmFmt();
1140cdf0e10cSrcweir                 SwFrmFmt *pNew = pBox->ClaimFrmFmt();
1141cdf0e10cSrcweir                 pNew->SetFmtAttr( rNew );
1142cdf0e10cSrcweir                 aFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, 0 ), aFmtCmp.Count());
1143cdf0e10cSrcweir             }
1144cdf0e10cSrcweir         }
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir         SwHTMLTableLayout *pTableLayout = rTable.GetHTMLTableLayout();
1147cdf0e10cSrcweir         if( pTableLayout )
1148cdf0e10cSrcweir         {
1149cdf0e10cSrcweir             SwCntntFrm* pFrm = rCursor.GetCntntNode()->getLayoutFrm( rCursor.GetCntntNode()->GetDoc()->GetCurrentLayout() );
1150cdf0e10cSrcweir             SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir             pTableLayout->Resize(
1153cdf0e10cSrcweir                 pTableLayout->GetBrowseWidthByTabFrm( *pTabFrm ), sal_True );
1154cdf0e10cSrcweir         }
1155cdf0e10cSrcweir         SwTblFmtCmp::Delete( aFmtCmp );
1156cdf0e10cSrcweir         SetModified();
1157cdf0e10cSrcweir     }
1158cdf0e10cSrcweir }
1159cdf0e10cSrcweir 
1160cdf0e10cSrcweir /***********************************************************************
1161cdf0e10cSrcweir #*  Class      :  SwDoc
1162cdf0e10cSrcweir #*  Methoden   :  GetBoxAttr()
1163cdf0e10cSrcweir #*  Datum      :  MA 01. Jun. 93
1164cdf0e10cSrcweir #*  Update     :  JP 29.04.98
1165cdf0e10cSrcweir #***********************************************************************/
1166cdf0e10cSrcweir 
GetBoxAttr(const SwCursor & rCursor,SfxPoolItem & rToFill) const1167cdf0e10cSrcweir sal_Bool SwDoc::GetBoxAttr( const SwCursor& rCursor, SfxPoolItem& rToFill ) const
1168cdf0e10cSrcweir {
1169cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1170cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
1171cdf0e10cSrcweir     SwSelBoxes aBoxes;
1172cdf0e10cSrcweir     if( pTblNd && lcl_GetBoxSel( rCursor, aBoxes ))
1173cdf0e10cSrcweir     {
1174cdf0e10cSrcweir         bRet = sal_True;
1175cdf0e10cSrcweir         sal_Bool bOneFound = sal_False;
1176cdf0e10cSrcweir         const sal_uInt16 nWhich = rToFill.Which();
1177cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < aBoxes.Count(); ++i )
1178cdf0e10cSrcweir         {
1179cdf0e10cSrcweir             switch ( nWhich )
1180cdf0e10cSrcweir             {
1181cdf0e10cSrcweir                 case RES_BACKGROUND:
1182cdf0e10cSrcweir                 {
1183cdf0e10cSrcweir                     const SvxBrushItem &rBack =
1184cdf0e10cSrcweir                                     aBoxes[i]->GetFrmFmt()->GetBackground();
1185cdf0e10cSrcweir                     if( !bOneFound )
1186cdf0e10cSrcweir                     {
1187cdf0e10cSrcweir                         (SvxBrushItem&)rToFill = rBack;
1188cdf0e10cSrcweir                         bOneFound = sal_True;
1189cdf0e10cSrcweir                     }
1190cdf0e10cSrcweir                     else if( rToFill != rBack )
1191cdf0e10cSrcweir                         bRet = sal_False;
1192cdf0e10cSrcweir                 }
1193cdf0e10cSrcweir                 break;
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir                 case RES_FRAMEDIR:
1196cdf0e10cSrcweir                 {
1197cdf0e10cSrcweir                     const SvxFrameDirectionItem& rDir =
1198cdf0e10cSrcweir                                     aBoxes[i]->GetFrmFmt()->GetFrmDir();
1199cdf0e10cSrcweir                     if( !bOneFound )
1200cdf0e10cSrcweir                     {
1201cdf0e10cSrcweir                         (SvxFrameDirectionItem&)rToFill = rDir;
1202cdf0e10cSrcweir                         bOneFound = sal_True;
1203cdf0e10cSrcweir                     }
1204cdf0e10cSrcweir                     else if( rToFill != rDir )
1205cdf0e10cSrcweir                         bRet = sal_False;
1206cdf0e10cSrcweir                 }
1207cdf0e10cSrcweir             }
1208cdf0e10cSrcweir 
1209cdf0e10cSrcweir             if ( sal_False == bRet )
1210cdf0e10cSrcweir                 break;
1211cdf0e10cSrcweir         }
1212cdf0e10cSrcweir     }
1213cdf0e10cSrcweir     return bRet;
1214cdf0e10cSrcweir }
1215cdf0e10cSrcweir 
1216cdf0e10cSrcweir /***********************************************************************
1217cdf0e10cSrcweir #*  Class      :  SwDoc
1218cdf0e10cSrcweir #*  Methoden   :  SetBoxAlign, SetBoxAlign
1219cdf0e10cSrcweir #*  Datum      :  MA 18. Dec. 96
1220cdf0e10cSrcweir #*  Update     :  JP 29.04.98
1221cdf0e10cSrcweir #***********************************************************************/
SetBoxAlign(const SwCursor & rCursor,sal_uInt16 nAlign)1222cdf0e10cSrcweir void SwDoc::SetBoxAlign( const SwCursor& rCursor, sal_uInt16 nAlign )
1223cdf0e10cSrcweir {
1224cdf0e10cSrcweir     ASSERT( nAlign == text::VertOrientation::NONE   ||
1225cdf0e10cSrcweir             nAlign == text::VertOrientation::CENTER ||
1226cdf0e10cSrcweir             nAlign == text::VertOrientation::BOTTOM, "wrong alignment" );
1227cdf0e10cSrcweir     SwFmtVertOrient aVertOri( 0, nAlign );
1228cdf0e10cSrcweir     SetBoxAttr( rCursor, aVertOri );
1229cdf0e10cSrcweir }
1230cdf0e10cSrcweir 
GetBoxAlign(const SwCursor & rCursor) const1231cdf0e10cSrcweir sal_uInt16 SwDoc::GetBoxAlign( const SwCursor& rCursor ) const
1232cdf0e10cSrcweir {
1233cdf0e10cSrcweir     sal_uInt16 nAlign = USHRT_MAX;
1234cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
1235cdf0e10cSrcweir     SwSelBoxes aBoxes;
1236cdf0e10cSrcweir     if( pTblNd && ::lcl_GetBoxSel( rCursor, aBoxes ))
1237cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < aBoxes.Count(); ++i )
1238cdf0e10cSrcweir         {
1239cdf0e10cSrcweir             const SwFmtVertOrient &rOri =
1240cdf0e10cSrcweir                             aBoxes[i]->GetFrmFmt()->GetVertOrient();
1241cdf0e10cSrcweir             if( USHRT_MAX == nAlign )
1242cdf0e10cSrcweir                 nAlign = static_cast<sal_uInt16>(rOri.GetVertOrient());
1243cdf0e10cSrcweir             else if( rOri.GetVertOrient() != nAlign )
1244cdf0e10cSrcweir             {
1245cdf0e10cSrcweir                 nAlign = USHRT_MAX;
1246cdf0e10cSrcweir                 break;
1247cdf0e10cSrcweir             }
1248cdf0e10cSrcweir         }
1249cdf0e10cSrcweir     return nAlign;
1250cdf0e10cSrcweir }
1251cdf0e10cSrcweir 
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir /***********************************************************************
1254cdf0e10cSrcweir #*  Class      :  SwDoc
1255cdf0e10cSrcweir #*  Methoden   :  AdjustCellWidth()
1256cdf0e10cSrcweir #*  Datum      :  MA 20. Feb. 95
1257cdf0e10cSrcweir #*  Update     :  JP 29.04.98
1258cdf0e10cSrcweir #***********************************************************************/
lcl_CalcCellFit(const SwLayoutFrm * pCell)1259cdf0e10cSrcweir sal_uInt16 lcl_CalcCellFit( const SwLayoutFrm *pCell )
1260cdf0e10cSrcweir {
1261cdf0e10cSrcweir     SwTwips nRet = 0;
1262cdf0e10cSrcweir     const SwFrm *pFrm = pCell->Lower(); //Die ganze Zelle.
1263cdf0e10cSrcweir     SWRECTFN( pCell )
1264cdf0e10cSrcweir     while ( pFrm )
1265cdf0e10cSrcweir     {
1266cdf0e10cSrcweir         const SwTwips nAdd = (pFrm->Frm().*fnRect->fnGetWidth)() -
1267cdf0e10cSrcweir                              (pFrm->Prt().*fnRect->fnGetWidth)();
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir         // --> FME 2005-12-02 #127801# pFrm does not necessarily have to be a SwTxtFrm!
1270cdf0e10cSrcweir         const SwTwips nCalcFitToContent = pFrm->IsTxtFrm() ?
1271cdf0e10cSrcweir                                           ((SwTxtFrm*)pFrm)->CalcFitToContent() :
1272cdf0e10cSrcweir                                           (pFrm->Prt().*fnRect->fnGetWidth)();
1273cdf0e10cSrcweir         // <--
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir         nRet = Max( nRet, nCalcFitToContent + nAdd );
1276cdf0e10cSrcweir         pFrm = pFrm->GetNext();
1277cdf0e10cSrcweir     }
1278cdf0e10cSrcweir     //Umrandung und linker/rechter Rand wollen mit kalkuliert werden.
1279cdf0e10cSrcweir     nRet += (pCell->Frm().*fnRect->fnGetWidth)() -
1280cdf0e10cSrcweir             (pCell->Prt().*fnRect->fnGetWidth)();
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir     //Um Rechenungenauikeiten, die spaeter bei SwTable::SetTabCols enstehen,
1283cdf0e10cSrcweir     //auszugleichen, addieren wir noch ein bischen.
1284cdf0e10cSrcweir     nRet += COLFUZZY;
1285cdf0e10cSrcweir     return (sal_uInt16)Max( long(MINLAY), nRet );
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir /*Die Zelle ist in der Selektion, wird aber nicht von den TabCols beschrieben.
1289cdf0e10cSrcweir  *Das bedeutet, dass die Zelle aufgrund der zweidimensionalen Darstellung von
1290cdf0e10cSrcweir  *anderen Zellen "geteilt" wurde. Wir muessen also den Wunsch- bzw. Minimalwert
1291cdf0e10cSrcweir  *der Zelle auf die Spalten, durch die sie geteilt wurde verteilen.
1292cdf0e10cSrcweir  *
1293cdf0e10cSrcweir  *Dazu sammeln wir zuerst die Spalten - nicht die Spaltentrenner! - ein, die
1294cdf0e10cSrcweir  *sich mit der Zelle ueberschneiden. Den Wunschwert der Zelle verteilen wir
1295cdf0e10cSrcweir  *dann anhand des Betrages der Ueberschneidung auf die Zellen.
1296cdf0e10cSrcweir  *Wenn eine Zelle bereits einen groesseren Wunschwert angemeldet hat, so bleibt
1297cdf0e10cSrcweir  *dieser erhalten, kleinere Wuensche werden ueberschrieben.
1298cdf0e10cSrcweir  */
1299cdf0e10cSrcweir 
lcl_CalcSubColValues(SvUShorts & rToFill,const SwTabCols & rCols,const SwLayoutFrm * pCell,const SwLayoutFrm * pTab,sal_Bool bWishValues)1300cdf0e10cSrcweir void lcl_CalcSubColValues( SvUShorts &rToFill, const SwTabCols &rCols,
1301cdf0e10cSrcweir                               const SwLayoutFrm *pCell, const SwLayoutFrm *pTab,
1302cdf0e10cSrcweir                               sal_Bool bWishValues )
1303cdf0e10cSrcweir {
1304cdf0e10cSrcweir     const sal_uInt16 nWish = bWishValues ?
1305cdf0e10cSrcweir                     ::lcl_CalcCellFit( pCell ) :
1306cdf0e10cSrcweir                     MINLAY + sal_uInt16(pCell->Frm().Width() - pCell->Prt().Width());
1307cdf0e10cSrcweir 
1308cdf0e10cSrcweir     SWRECTFN( pTab )
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir     for ( sal_uInt16 i = 0 ; i <= rCols.Count(); ++i )
1311cdf0e10cSrcweir     {
1312cdf0e10cSrcweir         long nColLeft  = i == 0             ? rCols.GetLeft()  : rCols[i-1];
1313cdf0e10cSrcweir         long nColRight = i == rCols.Count() ? rCols.GetRight() : rCols[i];
1314cdf0e10cSrcweir         nColLeft  += rCols.GetLeftMin();
1315cdf0e10cSrcweir         nColRight += rCols.GetLeftMin();
1316cdf0e10cSrcweir 
1317cdf0e10cSrcweir         //Werte auf die Verhaeltnisse der Tabelle (Follows) anpassen.
1318cdf0e10cSrcweir         if ( rCols.GetLeftMin() !=  sal_uInt16((pTab->Frm().*fnRect->fnGetLeft)()) )
1319cdf0e10cSrcweir         {
1320cdf0e10cSrcweir             const long nDiff = (pTab->Frm().*fnRect->fnGetLeft)() - rCols.GetLeftMin();
1321cdf0e10cSrcweir             nColLeft  += nDiff;
1322cdf0e10cSrcweir             nColRight += nDiff;
1323cdf0e10cSrcweir         }
1324cdf0e10cSrcweir         const long nCellLeft  = (pCell->Frm().*fnRect->fnGetLeft)();
1325cdf0e10cSrcweir         const long nCellRight = (pCell->Frm().*fnRect->fnGetRight)();
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir         //Ueberschneidungsbetrag ermitteln.
1328cdf0e10cSrcweir         long nWidth = 0;
1329cdf0e10cSrcweir         if ( nColLeft <= nCellLeft && nColRight >= (nCellLeft+COLFUZZY) )
1330cdf0e10cSrcweir             nWidth = nColRight - nCellLeft;
1331cdf0e10cSrcweir         else if ( nColLeft <= (nCellRight-COLFUZZY) && nColRight >= nCellRight )
1332cdf0e10cSrcweir             nWidth = nCellRight - nColLeft;
1333cdf0e10cSrcweir         else if ( nColLeft >= nCellLeft && nColRight <= nCellRight )
1334cdf0e10cSrcweir             nWidth = nColRight - nColLeft;
1335cdf0e10cSrcweir         if ( nWidth && pCell->Frm().Width() )
1336cdf0e10cSrcweir         {
1337cdf0e10cSrcweir             long nTmp = nWidth * nWish / pCell->Frm().Width();
1338cdf0e10cSrcweir             if ( sal_uInt16(nTmp) > rToFill[i] )
1339cdf0e10cSrcweir                 rToFill[i] = sal_uInt16(nTmp);
1340cdf0e10cSrcweir         }
1341cdf0e10cSrcweir     }
1342cdf0e10cSrcweir }
1343cdf0e10cSrcweir 
1344cdf0e10cSrcweir /*Besorgt neue Werte zu Einstellung der TabCols.
1345cdf0e10cSrcweir  *Es wird nicht ueber die Eintrage in den TabCols itereriert, sondern
1346cdf0e10cSrcweir  *quasi ueber die Zwischenraeume, die ja die Zellen beschreiben.
1347cdf0e10cSrcweir  *
1348cdf0e10cSrcweir  *bWishValues == sal_True:  Es werden zur aktuellen Selektion bzw. zur aktuellen
1349cdf0e10cSrcweir  *                      Zelle die Wunschwerte aller betroffen Zellen ermittelt.
1350cdf0e10cSrcweir  *                      Sind mehrere Zellen in einer Spalte, so wird der
1351cdf0e10cSrcweir  *                      groesste Wunschwert als Ergebnis geliefert.
1352cdf0e10cSrcweir  *                      Fuer die TabCol-Eintraege, zu denen keine Zellen
1353cdf0e10cSrcweir  *                      ermittelt wurden, werden 0-en eingetragen.
1354cdf0e10cSrcweir  *
1355cdf0e10cSrcweir  *bWishValues == sal_False: Die Selektion wird senkrecht ausgedehnt. Zu jeder
1356cdf0e10cSrcweir  *                      Spalte in den TabCols, die sich mit der Selektion
1357cdf0e10cSrcweir  *                      schneidet wird der Minimalwert ermittelt.
1358cdf0e10cSrcweir  */
1359cdf0e10cSrcweir 
lcl_CalcColValues(SvUShorts & rToFill,const SwTabCols & rCols,const SwLayoutFrm * pStart,const SwLayoutFrm * pEnd,sal_Bool bWishValues)1360cdf0e10cSrcweir void lcl_CalcColValues( SvUShorts &rToFill, const SwTabCols &rCols,
1361cdf0e10cSrcweir                            const SwLayoutFrm *pStart, const SwLayoutFrm *pEnd,
1362cdf0e10cSrcweir                            sal_Bool bWishValues )
1363cdf0e10cSrcweir {
1364cdf0e10cSrcweir     SwSelUnions aUnions;
1365cdf0e10cSrcweir     ::MakeSelUnions( aUnions, pStart, pEnd,
1366cdf0e10cSrcweir                     bWishValues ? nsSwTblSearchType::TBLSEARCH_NONE : nsSwTblSearchType::TBLSEARCH_COL );
1367cdf0e10cSrcweir 
1368cdf0e10cSrcweir     for ( sal_uInt16 i2 = 0; i2 < aUnions.Count(); ++i2 )
1369cdf0e10cSrcweir     {
1370cdf0e10cSrcweir         SwSelUnion *pSelUnion = aUnions[i2];
1371cdf0e10cSrcweir         const SwTabFrm *pTab = pSelUnion->GetTable();
1372cdf0e10cSrcweir         const SwRect &rUnion = pSelUnion->GetUnion();
1373cdf0e10cSrcweir 
1374cdf0e10cSrcweir         SWRECTFN( pTab )
1375cdf0e10cSrcweir         sal_Bool bRTL = pTab->IsRightToLeft();
1376cdf0e10cSrcweir 
1377cdf0e10cSrcweir         const SwLayoutFrm *pCell = pTab->FirstCell();
1378cdf0e10cSrcweir         do
1379cdf0e10cSrcweir         {
1380cdf0e10cSrcweir             if ( pCell->IsCellFrm() && pCell->FindTabFrm() == pTab && ::IsFrmInTblSel( rUnion, pCell ) )
1381cdf0e10cSrcweir             {
1382cdf0e10cSrcweir                 const long nCLeft  = (pCell->Frm().*fnRect->fnGetLeft)();
1383cdf0e10cSrcweir                 const long nCRight = (pCell->Frm().*fnRect->fnGetRight)();
1384cdf0e10cSrcweir 
1385cdf0e10cSrcweir                 sal_Bool bNotInCols = sal_True;
1386cdf0e10cSrcweir 
1387cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i <= rCols.Count(); ++i )
1388cdf0e10cSrcweir                 {
1389cdf0e10cSrcweir                     sal_uInt16 nFit = rToFill[i];
1390cdf0e10cSrcweir                     long nColLeft  = i == 0             ? rCols.GetLeft()  : rCols[i-1];
1391cdf0e10cSrcweir                     long nColRight = i == rCols.Count() ? rCols.GetRight() : rCols[i];
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir                     if ( bRTL )
1394cdf0e10cSrcweir                     {
1395cdf0e10cSrcweir                         long nTmpRight = nColRight;
1396cdf0e10cSrcweir                         nColRight = rCols.GetRight() - nColLeft;
1397cdf0e10cSrcweir                         nColLeft = rCols.GetRight() - nTmpRight;
1398cdf0e10cSrcweir                     }
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir                     nColLeft  += rCols.GetLeftMin();
1401cdf0e10cSrcweir                     nColRight += rCols.GetLeftMin();
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir                     //Werte auf die Verhaeltnisse der Tabelle (Follows) anpassen.
1404cdf0e10cSrcweir                     long nLeftA  = nColLeft;
1405cdf0e10cSrcweir                     long nRightA = nColRight;
1406cdf0e10cSrcweir                     if ( rCols.GetLeftMin() !=  sal_uInt16((pTab->Frm().*fnRect->fnGetLeft)()) )
1407cdf0e10cSrcweir                     {
1408cdf0e10cSrcweir                         const long nDiff = (pTab->Frm().*fnRect->fnGetLeft)() - rCols.GetLeftMin();
1409cdf0e10cSrcweir                         nLeftA  += nDiff;
1410cdf0e10cSrcweir                         nRightA += nDiff;
1411cdf0e10cSrcweir                     }
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir                     //Wir wollen nicht allzu genau hinsehen.
1414cdf0e10cSrcweir                     if ( ::IsSame(nCLeft, nLeftA) && ::IsSame(nCRight, nRightA))
1415cdf0e10cSrcweir                     {
1416cdf0e10cSrcweir                         bNotInCols = sal_False;
1417cdf0e10cSrcweir                         if ( bWishValues )
1418cdf0e10cSrcweir                         {
1419cdf0e10cSrcweir                             const sal_uInt16 nWish = ::lcl_CalcCellFit( pCell );
1420cdf0e10cSrcweir                             if ( nWish > nFit )
1421cdf0e10cSrcweir                                 nFit = nWish;
1422cdf0e10cSrcweir                         }
1423cdf0e10cSrcweir                         else
1424cdf0e10cSrcweir                         {   const sal_uInt16 nMin = MINLAY + sal_uInt16(pCell->Frm().Width() -
1425cdf0e10cSrcweir                                                                 pCell->Prt().Width());
1426cdf0e10cSrcweir                             if ( !nFit || nMin < nFit )
1427cdf0e10cSrcweir                                 nFit = nMin;
1428cdf0e10cSrcweir                         }
1429cdf0e10cSrcweir                         if ( rToFill[i] < nFit )
1430cdf0e10cSrcweir                             rToFill[i] = nFit;
1431cdf0e10cSrcweir                     }
1432cdf0e10cSrcweir                 }
1433cdf0e10cSrcweir                 if ( bNotInCols )
1434cdf0e10cSrcweir                     ::lcl_CalcSubColValues( rToFill, rCols, pCell, pTab, bWishValues );
1435cdf0e10cSrcweir             }
1436cdf0e10cSrcweir             do {
1437cdf0e10cSrcweir                 pCell = pCell->GetNextLayoutLeaf();
1438cdf0e10cSrcweir             }while( pCell && pCell->Frm().Width() == 0 );
1439cdf0e10cSrcweir         } while ( pCell && pTab->IsAnLower( pCell ) );
1440cdf0e10cSrcweir     }
1441cdf0e10cSrcweir }
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir 
AdjustCellWidth(const SwCursor & rCursor,sal_Bool bBalance)1444cdf0e10cSrcweir void SwDoc::AdjustCellWidth( const SwCursor& rCursor, sal_Bool bBalance )
1445cdf0e10cSrcweir {
1446cdf0e10cSrcweir     // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
1447cdf0e10cSrcweir     SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
1448cdf0e10cSrcweir     SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
1449cdf0e10cSrcweir     if( !pTblNd )
1450cdf0e10cSrcweir         return ;
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir     SwLayoutFrm *pStart, *pEnd;
1453cdf0e10cSrcweir     ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir     //TabCols besorgen, den ueber diese stellen wir die Tabelle neu ein.
1456cdf0e10cSrcweir     SwFrm* pBoxFrm = pStart;
1457cdf0e10cSrcweir     while( pBoxFrm && !pBoxFrm->IsCellFrm() )
1458cdf0e10cSrcweir         pBoxFrm = pBoxFrm->GetUpper();
1459cdf0e10cSrcweir 
1460cdf0e10cSrcweir     if ( !pBoxFrm )
1461cdf0e10cSrcweir         return; // robust
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir     SwTabCols aTabCols;
1464cdf0e10cSrcweir     GetTabCols( aTabCols, 0, (SwCellFrm*)pBoxFrm );
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir     if ( ! aTabCols.Count() )
1467cdf0e10cSrcweir         return;
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir     const sal_uInt8 nTmp = (sal_uInt8)Max( sal_uInt16(255), sal_uInt16(aTabCols.Count() + 1) );
1470cdf0e10cSrcweir     SvUShorts aWish( nTmp, nTmp ),
1471cdf0e10cSrcweir               aMins( nTmp, nTmp );
1472cdf0e10cSrcweir     sal_uInt16 i;
1473cdf0e10cSrcweir 
1474cdf0e10cSrcweir     for ( i = 0; i <= aTabCols.Count(); ++i )
1475cdf0e10cSrcweir     {
1476cdf0e10cSrcweir         aWish.Insert( sal_uInt16(0), aWish.Count() );
1477cdf0e10cSrcweir         aMins.Insert( sal_uInt16(0), aMins.Count() );
1478cdf0e10cSrcweir     }
1479cdf0e10cSrcweir     ::lcl_CalcColValues( aWish, aTabCols, pStart, pEnd, sal_True  );
1480cdf0e10cSrcweir 
1481cdf0e10cSrcweir     //Es ist Robuster wenn wir die Min-Werte fuer die ganze Tabelle berechnen.
1482cdf0e10cSrcweir     const SwTabFrm *pTab = pStart->ImplFindTabFrm();
1483cdf0e10cSrcweir     pStart = (SwLayoutFrm*)pTab->FirstCell();
1484cdf0e10cSrcweir     pEnd   = (SwLayoutFrm*)pTab->FindLastCntnt()->GetUpper();
1485cdf0e10cSrcweir     while( !pEnd->IsCellFrm() )
1486cdf0e10cSrcweir         pEnd = pEnd->GetUpper();
1487cdf0e10cSrcweir     ::lcl_CalcColValues( aMins, aTabCols, pStart, pEnd, sal_False );
1488cdf0e10cSrcweir 
1489cdf0e10cSrcweir     if( bBalance )
1490cdf0e10cSrcweir     {
1491cdf0e10cSrcweir         //Alle Spalten, die makiert sind haben jetzt einen Wunschwert
1492cdf0e10cSrcweir         //eingtragen. Wir addieren die aktuellen Werte, teilen das Ergebnis
1493cdf0e10cSrcweir         //durch die Anzahl und haben eine Wunschwert fuer den ausgleich.
1494cdf0e10cSrcweir         sal_uInt16 nWish = 0, nCnt = 0;
1495cdf0e10cSrcweir         for ( i = 0; i <= aTabCols.Count(); ++i )
1496cdf0e10cSrcweir         {
1497cdf0e10cSrcweir             int nDiff = aWish[i];
1498cdf0e10cSrcweir             if ( nDiff )
1499cdf0e10cSrcweir             {
1500cdf0e10cSrcweir                 if ( i == 0 )
1501cdf0e10cSrcweir                     nWish = static_cast<sal_uInt16>( nWish + aTabCols[i] - aTabCols.GetLeft() );
1502cdf0e10cSrcweir                 else if ( i == aTabCols.Count() )
1503cdf0e10cSrcweir                     nWish = static_cast<sal_uInt16>(nWish + aTabCols.GetRight() - aTabCols[i-1] );
1504cdf0e10cSrcweir                 else
1505cdf0e10cSrcweir                     nWish = static_cast<sal_uInt16>(nWish + aTabCols[i] - aTabCols[i-1] );
1506cdf0e10cSrcweir                 ++nCnt;
1507cdf0e10cSrcweir             }
1508cdf0e10cSrcweir         }
1509cdf0e10cSrcweir         nWish = nWish / nCnt;
1510cdf0e10cSrcweir         for ( i = 0; i < aWish.Count(); ++i )
1511cdf0e10cSrcweir             if ( aWish[i] )
1512cdf0e10cSrcweir                 aWish[i] = nWish;
1513cdf0e10cSrcweir     }
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir     const sal_uInt16 nOldRight = static_cast<sal_uInt16>(aTabCols.GetRight());
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir     //Um die Impl. einfach zu gestalten, aber trotzdem in den meissten Faellen
1518cdf0e10cSrcweir     //den Platz richtig auszunutzen laufen wir zweimal.
1519cdf0e10cSrcweir     //Problem: Erste Spalte wird breiter, die anderen aber erst danach
1520cdf0e10cSrcweir     //schmaler. Die Wunschbreite der ersten Spalte wuerde abgelehnt, weil
1521cdf0e10cSrcweir     //mit ihr die max. Breite der Tabelle ueberschritten wuerde.
1522cdf0e10cSrcweir     for ( sal_uInt16 k= 0; k < 2; ++k )
1523cdf0e10cSrcweir     {
1524cdf0e10cSrcweir         for ( i = 0; i <= aTabCols.Count(); ++i )
1525cdf0e10cSrcweir         {
1526cdf0e10cSrcweir             int nDiff = aWish[i];
1527cdf0e10cSrcweir             if ( nDiff )
1528cdf0e10cSrcweir             {
1529cdf0e10cSrcweir                 int nMin = aMins[i];
1530cdf0e10cSrcweir                 if ( nMin > nDiff )
1531cdf0e10cSrcweir                     nDiff = nMin;
1532cdf0e10cSrcweir 
1533cdf0e10cSrcweir                 if ( i == 0 )
1534cdf0e10cSrcweir                 {
1535cdf0e10cSrcweir                     if( aTabCols.Count() )
1536cdf0e10cSrcweir                         nDiff -= aTabCols[0] - aTabCols.GetLeft();
1537cdf0e10cSrcweir                     else
1538cdf0e10cSrcweir                         nDiff -= aTabCols.GetRight() - aTabCols.GetLeft();
1539cdf0e10cSrcweir                 }
1540cdf0e10cSrcweir                 else if ( i == aTabCols.Count() )
1541cdf0e10cSrcweir                     nDiff -= aTabCols.GetRight() - aTabCols[i-1];
1542cdf0e10cSrcweir                 else
1543cdf0e10cSrcweir                     nDiff -= aTabCols[i] - aTabCols[i-1];
1544cdf0e10cSrcweir 
1545cdf0e10cSrcweir                 long nTabRight = aTabCols.GetRight() + nDiff;
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir                 //Wenn die Tabelle zu breit wuerde begrenzen wir die Anpassung
1548cdf0e10cSrcweir                 //auf das erlaubte Maximum.
1549cdf0e10cSrcweir                 if ( !bBalance && nTabRight > aTabCols.GetRightMax() )
1550cdf0e10cSrcweir                 {
1551cdf0e10cSrcweir                     const long nTmpD = nTabRight - aTabCols.GetRightMax();
1552cdf0e10cSrcweir                     nDiff     -= nTmpD;
1553cdf0e10cSrcweir                     nTabRight -= nTmpD;
1554cdf0e10cSrcweir                 }
1555cdf0e10cSrcweir                 for ( sal_uInt16 i2 = i; i2 < aTabCols.Count(); ++i2 )
1556cdf0e10cSrcweir                     aTabCols[i2] += nDiff;
1557cdf0e10cSrcweir                 aTabCols.SetRight( nTabRight );
1558cdf0e10cSrcweir             }
1559cdf0e10cSrcweir         }
1560cdf0e10cSrcweir     }
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir     const sal_uInt16 nNewRight = static_cast<sal_uInt16>(aTabCols.GetRight());
1563cdf0e10cSrcweir 
1564cdf0e10cSrcweir     SwFrmFmt *pFmt = pTblNd->GetTable().GetFrmFmt();
1565cdf0e10cSrcweir     const sal_Int16 nOriHori = pFmt->GetHoriOrient().GetHoriOrient();
1566cdf0e10cSrcweir 
1567cdf0e10cSrcweir     //So, die richtige Arbeit koennen wir jetzt der SwTable ueberlassen.
1568cdf0e10cSrcweir     SetTabCols( aTabCols, sal_False, 0, (SwCellFrm*)pBoxFrm );
1569cdf0e10cSrcweir 
1570cdf0e10cSrcweir     // i54248: lijian/fme
1571cdf0e10cSrcweir     // alignment might have been changed in SetTabCols, restore old value:
1572cdf0e10cSrcweir     const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
1573cdf0e10cSrcweir     SwFmtHoriOrient aHori( rHori );
1574cdf0e10cSrcweir     if ( aHori.GetHoriOrient() != nOriHori )
1575cdf0e10cSrcweir     {
1576cdf0e10cSrcweir         aHori.SetHoriOrient( nOriHori );
1577cdf0e10cSrcweir         pFmt->SetFmtAttr( aHori );
1578cdf0e10cSrcweir     }
1579cdf0e10cSrcweir 
1580cdf0e10cSrcweir     //Bei Automatischer Breite wird auf Linksbuendig umgeschaltet.
1581cdf0e10cSrcweir     //Bei Randattributen wird der Rechte Rand angepasst.
1582cdf0e10cSrcweir     if( !bBalance && nNewRight < nOldRight )
1583cdf0e10cSrcweir     {
1584cdf0e10cSrcweir         if( aHori.GetHoriOrient() == text::HoriOrientation::FULL )
1585cdf0e10cSrcweir         {
1586cdf0e10cSrcweir             aHori.SetHoriOrient( text::HoriOrientation::LEFT );
1587cdf0e10cSrcweir             pFmt->SetFmtAttr( aHori );
1588cdf0e10cSrcweir         }
1589cdf0e10cSrcweir     }
1590cdf0e10cSrcweir 
1591cdf0e10cSrcweir     SetModified();
1592cdf0e10cSrcweir }
1593