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