update dev300-m58
[ooovba.git] / sc / source / core / data / table2.cxx
blob773cf8b666ac99ace779036113883024d8f759ce
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: table2.cxx,v $
10 * $Revision: 1.40.124.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include "scitems.hxx"
37 #include <svx/boxitem.hxx>
38 #include <tools/urlobj.hxx>
39 #include <svtools/poolcach.hxx>
40 #include <unotools/charclass.hxx>
41 #include <math.h>
42 #include <svtools/PasswordHelper.hxx>
43 #include <unotools/transliterationwrapper.hxx>
45 #include "patattr.hxx"
46 #include "docpool.hxx"
47 #include "cell.hxx"
48 #include "document.hxx"
49 #include "drwlayer.hxx"
50 #include "olinetab.hxx"
51 #include "rechead.hxx"
52 #include "stlpool.hxx"
53 #include "attarray.hxx" // Iterator
54 #include "markdata.hxx"
55 #include "progress.hxx"
56 #include "dociter.hxx"
57 #include "conditio.hxx"
58 #include "chartlis.hxx"
59 #include "fillinfo.hxx"
60 #include "bcaslot.hxx"
61 #include "postit.hxx"
62 #include "globstr.hrc"
63 #include "segmenttree.hxx"
65 #include <math.h>
67 // STATIC DATA -----------------------------------------------------------
70 BOOL ScTable::SetOutlineTable( const ScOutlineTable* pNewOutline )
72 USHORT nOldSizeX = 0;
73 USHORT nOldSizeY = 0;
74 USHORT nNewSizeX = 0;
75 USHORT nNewSizeY = 0;
77 if (pOutlineTable)
79 nOldSizeX = pOutlineTable->GetColArray()->GetDepth();
80 nOldSizeY = pOutlineTable->GetRowArray()->GetDepth();
81 delete pOutlineTable;
84 if (pNewOutline)
86 pOutlineTable = new ScOutlineTable( *pNewOutline );
87 nNewSizeX = pOutlineTable->GetColArray()->GetDepth();
88 nNewSizeY = pOutlineTable->GetRowArray()->GetDepth();
90 else
91 pOutlineTable = NULL;
93 return ( nNewSizeX != nOldSizeX || nNewSizeY != nOldSizeY ); // Groesse geaendert ?
97 void ScTable::StartOutlineTable()
99 if (!pOutlineTable)
100 pOutlineTable = new ScOutlineTable;
104 BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize )
106 BOOL bTest = TRUE;
108 if ( nStartCol==0 && nEndCol==MAXCOL && pOutlineTable )
109 bTest = pOutlineTable->TestInsertRow(nSize);
111 for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
112 bTest = aCol[i].TestInsertRow( nSize );
114 return bTest;
118 void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize )
120 nRecalcLvl++;
121 InitializeNoteCaptions();
122 if (nStartCol==0 && nEndCol==MAXCOL)
124 if (pRowHeight && pRowFlags)
126 pRowHeight->Insert( nStartRow, nSize);
127 BYTE nNewFlags = pRowFlags->Insert( nStartRow, nSize);
128 // only copy manual size flag, clear all others
129 if (nNewFlags && (nNewFlags != CR_MANUALSIZE))
130 pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1,
131 nNewFlags & CR_MANUALSIZE);
133 if (pOutlineTable)
134 pOutlineTable->InsertRow( nStartRow, nSize );
136 mpFilteredRows->insertSegment(nStartRow, nSize, true);
137 mpHiddenRows->insertSegment(nStartRow, nSize, true);
140 for (SCCOL j=nStartCol; j<=nEndCol; j++)
141 aCol[j].InsertRow( nStartRow, nSize );
142 if( !--nRecalcLvl )
143 SetDrawPageSize();
145 InvalidatePageBreaks();
149 void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
150 BOOL* pUndoOutline )
152 nRecalcLvl++;
153 InitializeNoteCaptions();
154 if (nStartCol==0 && nEndCol==MAXCOL)
156 if (pRowHeight && pRowFlags)
158 pRowHeight->Remove( nStartRow, nSize);
159 pRowFlags->Remove( nStartRow, nSize);
161 if (pOutlineTable)
162 if (pOutlineTable->DeleteRow( nStartRow, nSize ))
163 if (pUndoOutline)
164 *pUndoOutline = TRUE;
166 mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
167 mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
170 { // scope for bulk broadcast
171 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
172 for (SCCOL j=nStartCol; j<=nEndCol; j++)
173 aCol[j].DeleteRow( nStartRow, nSize );
175 if( !--nRecalcLvl )
176 SetDrawPageSize();
178 InvalidatePageBreaks();
182 BOOL ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
184 BOOL bTest = TRUE;
186 if ( nStartRow==0 && nEndRow==MAXROW && pOutlineTable )
187 bTest = pOutlineTable->TestInsertCol(nSize);
189 if ( nSize > static_cast<SCSIZE>(MAXCOL) )
190 bTest = FALSE;
192 for (SCCOL i=MAXCOL; (i+static_cast<SCCOL>(nSize)>MAXCOL) && bTest; i--)
193 bTest = aCol[i].TestInsertCol(nStartRow, nEndRow);
195 return bTest;
199 void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
201 nRecalcLvl++;
202 InitializeNoteCaptions();
203 if (nStartRow==0 && nEndRow==MAXROW)
205 if (pColWidth && pColFlags)
207 memmove( &pColWidth[nStartCol+nSize], &pColWidth[nStartCol],
208 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
209 memmove( &pColFlags[nStartCol+nSize], &pColFlags[nStartCol],
210 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
212 if (pOutlineTable)
213 pOutlineTable->InsertCol( nStartCol, nSize );
215 mpHiddenCols->insertSegment(nStartCol, nSize, true);
216 mpFilteredCols->insertSegment(nStartCol, nSize, true);
220 if ((nStartRow == 0) && (nEndRow == MAXROW))
222 for (SCSIZE i=0; i < nSize; i++)
223 for (SCCOL nCol = MAXCOL; nCol > nStartCol; nCol--)
224 aCol[nCol].SwapCol(aCol[nCol-1]);
226 else
228 for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
229 aCol[MAXCOL - nSize - i].MoveTo(nStartRow, nEndRow, aCol[MAXCOL - i]);
232 if (nStartCol>0) // copy old attributes
234 USHORT nWhichArray[2];
235 nWhichArray[0] = ATTR_MERGE;
236 nWhichArray[1] = 0;
238 for (SCSIZE i=0; i<nSize; i++)
240 aCol[nStartCol-1].CopyToColumn( nStartRow, nEndRow, IDF_ATTRIB,
241 FALSE, aCol[nStartCol+i] );
242 aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
243 SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
244 aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray );
247 if( !--nRecalcLvl )
248 SetDrawPageSize();
250 InvalidatePageBreaks();
254 void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize,
255 BOOL* pUndoOutline )
257 nRecalcLvl++;
258 InitializeNoteCaptions();
259 if (nStartRow==0 && nEndRow==MAXROW)
261 if (pColWidth && pColFlags)
263 memmove( &pColWidth[nStartCol], &pColWidth[nStartCol+nSize],
264 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
265 memmove( &pColFlags[nStartCol], &pColFlags[nStartCol+nSize],
266 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
268 if (pOutlineTable)
269 if (pOutlineTable->DeleteCol( nStartCol, nSize ))
270 if (pUndoOutline)
271 *pUndoOutline = TRUE;
273 mpHiddenCols->removeSegment(nStartCol, nStartCol+nSize);
274 mpFilteredCols->removeSegment(nStartCol, nStartCol+nSize);
278 { // scope for bulk broadcast
279 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
280 for (SCSIZE i = 0; i < nSize; i++)
281 aCol[nStartCol + i].DeleteArea(nStartRow, nEndRow, IDF_ALL);
284 if ((nStartRow == 0) && (nEndRow == MAXROW))
286 for (SCSIZE i=0; i < nSize; i++)
287 for (SCCOL nCol = nStartCol; nCol < MAXCOL; nCol++)
288 aCol[nCol].SwapCol(aCol[nCol+1]);
290 else
292 for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
293 aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
295 if( !--nRecalcLvl )
296 SetDrawPageSize();
298 InvalidatePageBreaks();
302 void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nDelFlag)
304 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
305 if (nRow2 > MAXROW) nRow2 = MAXROW;
306 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
308 // nRecalcLvl++;
310 { // scope for bulk broadcast
311 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
312 for (SCCOL i = nCol1; i <= nCol2; i++)
313 aCol[i].DeleteArea(nRow1, nRow2, nDelFlag);
317 // Zellschutz auf geschuetzter Tabelle nicht setzen
320 if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
322 ScPatternAttr aPattern(pDocument->GetPool());
323 aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
324 ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
327 /* if( !--nRecalcLvl )
328 SetDrawPageSize();
334 void ScTable::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
336 { // scope for bulk broadcast
337 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
338 for (SCCOL i=0; i<=MAXCOL; i++)
339 aCol[i].DeleteSelection( nDelFlag, rMark );
343 // Zellschutz auf geschuetzter Tabelle nicht setzen
346 if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
348 ScDocumentPool* pPool = pDocument->GetPool();
349 SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
350 aSet.Put( ScProtectionAttr( FALSE ) );
351 SfxItemPoolCache aCache( pPool, &aSet );
352 ApplySelectionCache( &aCache, rMark );
357 // pTable = Clipboard
358 void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
359 ScTable* pTable, BOOL bKeepScenarioFlags, BOOL bCloneNoteCaptions)
361 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
363 // Inhalte kopieren
364 SCCOL i;
366 for ( i = nCol1; i <= nCol2; i++)
367 aCol[i].CopyToClip(nRow1, nRow2, pTable->aCol[i], bKeepScenarioFlags, bCloneNoteCaptions);
369 // copy widths/heights, and only "hidden", "filtered" and "manual" flags
370 // also for all preceding columns/rows, to have valid positions for drawing objects
372 if (pColWidth && pTable->pColWidth)
373 for (i=0; i<=nCol2; i++)
374 pTable->pColWidth[i] = pColWidth[i];
376 pTable->CopyColHidden(*this, 0, nCol2);
377 pTable->CopyColFiltered(*this, 0, nCol2);
379 if (pRowFlags && pTable->pRowFlags && pRowHeight && pTable->pRowHeight)
381 pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
382 pTable->pRowHeight->CopyFrom( *pRowHeight, 0, nRow2);
385 pTable->CopyRowHidden(*this, 0, nRow2);
386 pTable->CopyRowFiltered(*this, 0, nRow2);
388 // ggf. Formeln durch Werte ersetzen
390 if ( IsProtected() )
391 for (i = nCol1; i <= nCol2; i++)
392 pTable->aCol[i].RemoveProtected(nRow1, nRow2);
396 void ScTable::CopyToClip(const ScRangeList& rRanges, ScTable* pTable,
397 bool bKeepScenarioFlags, bool bCloneNoteCaptions)
399 ScRangeList aRanges(rRanges);
400 for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
402 CopyToClip(p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(),
403 pTable, bKeepScenarioFlags, bCloneNoteCaptions);
407 void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
408 SCsCOL nDx, SCsROW nDy, USHORT nInsFlag,
409 BOOL bAsLink, BOOL bSkipAttrForEmpty, ScTable* pTable)
411 SCCOL i;
413 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
414 if (nRow2 > MAXROW) nRow2 = MAXROW;
415 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
417 nRecalcLvl++;
418 for ( i = nCol1; i <= nCol2; i++)
419 aCol[i].CopyFromClip(nRow1, nRow2, nDy, nInsFlag, bAsLink, bSkipAttrForEmpty, pTable->aCol[i - nDx]);
421 if ((nInsFlag & IDF_ATTRIB) != 0)
423 if (nRow1==0 && nRow2==MAXROW && pColWidth && pTable->pColWidth)
424 for (i=nCol1; i<=nCol2; i++)
425 pColWidth[i] = pTable->pColWidth[i-nDx];
427 if (nCol1==0 && nCol2==MAXCOL && pRowHeight && pTable->pRowHeight &&
428 pRowFlags && pTable->pRowFlags)
430 pRowHeight->CopyFrom( *pTable->pRowHeight, nRow1, nRow2, -nDy);
431 // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
432 for (SCROW j=nRow1; j<=nRow2; j++)
434 if ( pTable->pRowFlags->GetValue(j-nDy) & CR_MANUALSIZE )
435 pRowFlags->OrValue( j, CR_MANUALSIZE);
436 else
437 pRowFlags->AndValue( j, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
442 // Zellschutz auf geschuetzter Tabelle nicht setzen
445 if ( IsProtected() && (nInsFlag & IDF_ATTRIB) )
447 ScPatternAttr aPattern(pDocument->GetPool());
448 aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
449 ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
452 if( !--nRecalcLvl )
453 SetDrawPageSize();
458 void ScTable::MixData( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
459 USHORT nFunction, BOOL bSkipEmpty, ScTable* pSrcTab )
461 for (SCCOL i=nCol1; i<=nCol2; i++)
462 aCol[i].MixData( nRow1, nRow2, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
466 // Markierung von diesem Dokument
467 void ScTable::MixMarked( const ScMarkData& rMark, USHORT nFunction,
468 BOOL bSkipEmpty, ScTable* pSrcTab )
470 for (SCCOL i=0; i<=MAXCOL; i++)
471 aCol[i].MixMarked( rMark, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
475 void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
476 ScTable* pTransClip, USHORT nFlags, BOOL bAsLink )
478 BOOL bWasCut = pDocument->IsCutMode();
480 ScDocument* pDestDoc = pTransClip->pDocument;
482 for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
484 SCROW nRow;
485 ScBaseCell* pCell;
487 if ( bAsLink && nFlags == IDF_ALL )
489 // #68989# with IDF_ALL, also create links (formulas) for empty cells
491 for ( nRow=nRow1; nRow<=nRow2; nRow++ )
493 // create simple formula, as in ScColumn::CreateRefCell
495 ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
496 ScSingleRefData aRef;
497 aRef.nCol = nCol;
498 aRef.nRow = nRow;
499 aRef.nTab = nTab;
500 aRef.InitFlags(); // -> all absolute
501 aRef.SetFlag3D(TRUE);
502 aRef.CalcRelFromAbs( aDestPos );
503 ScTokenArray aArr;
504 aArr.AddSingleReference( aRef );
506 ScBaseCell* pNew = new ScFormulaCell( pDestDoc, aDestPos, &aArr );
507 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
510 else
512 ScColumnIterator aIter( &aCol[nCol], nRow1, nRow2 );
513 while (aIter.Next( nRow, pCell ))
515 ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
516 ScBaseCell* pNew;
517 if ( bAsLink ) // Referenz erzeugen ?
519 pNew = aCol[nCol].CreateRefCell( pDestDoc, aDestPos, aIter.GetIndex(), nFlags );
521 else // kopieren
523 ScAddress aOwnPos( nCol, nRow, nTab );
524 if (pCell->GetCellType() == CELLTYPE_FORMULA)
526 pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
528 // Referenzen drehen
529 // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
531 if (!bWasCut)
532 ((ScFormulaCell*)pNew)->TransposeReference();
534 else
536 pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos );
539 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
543 // Attribute
545 SCROW nAttrRow1;
546 SCROW nAttrRow2;
547 const ScPatternAttr* pPattern;
548 ScAttrIterator* pAttrIter = aCol[nCol].CreateAttrIterator( nRow1, nRow2 );
549 while ( (pPattern = pAttrIter->Next( nAttrRow1, nAttrRow2 )) != 0 )
551 if ( !IsDefaultItem( pPattern ) )
553 const SfxItemSet& rSet = pPattern->GetItemSet();
554 if ( rSet.GetItemState( ATTR_MERGE, FALSE ) == SFX_ITEM_DEFAULT &&
555 rSet.GetItemState( ATTR_MERGE_FLAG, FALSE ) == SFX_ITEM_DEFAULT &&
556 rSet.GetItemState( ATTR_BORDER, FALSE ) == SFX_ITEM_DEFAULT )
558 // no borders or merge items involved - use pattern as-is
559 for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
560 pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern, TRUE );
562 else
564 // transpose borders and merge values, remove merge flags (refreshed after pasting)
565 ScPatternAttr aNewPattern( *pPattern );
566 SfxItemSet& rNewSet = aNewPattern.GetItemSet();
568 const SvxBoxItem& rOldBox = (const SvxBoxItem&)rSet.Get(ATTR_BORDER);
569 if ( rOldBox.GetTop() || rOldBox.GetBottom() || rOldBox.GetLeft() || rOldBox.GetRight() )
571 SvxBoxItem aNew( ATTR_BORDER );
572 aNew.SetLine( rOldBox.GetLine( BOX_LINE_TOP ), BOX_LINE_LEFT );
573 aNew.SetLine( rOldBox.GetLine( BOX_LINE_LEFT ), BOX_LINE_TOP );
574 aNew.SetLine( rOldBox.GetLine( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
575 aNew.SetLine( rOldBox.GetLine( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
576 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_TOP ), BOX_LINE_LEFT );
577 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_LEFT ), BOX_LINE_TOP );
578 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
579 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
580 rNewSet.Put( aNew );
583 const ScMergeAttr& rOldMerge = (const ScMergeAttr&)rSet.Get(ATTR_MERGE);
584 if (rOldMerge.IsMerged())
585 rNewSet.Put( ScMergeAttr( Min(
586 static_cast<SCsCOL>(rOldMerge.GetRowMerge()),
587 static_cast<SCsCOL>(MAXCOL+1 - (nAttrRow2-nRow1))),
588 Min(
589 static_cast<SCsROW>(rOldMerge.GetColMerge()),
590 static_cast<SCsROW>(MAXROW+1 - (nCol-nCol1)))));
591 const ScMergeFlagAttr& rOldFlag = (const ScMergeFlagAttr&)rSet.Get(ATTR_MERGE_FLAG);
592 if (rOldFlag.IsOverlapped())
594 INT16 nNewFlags = rOldFlag.GetValue() & ~( SC_MF_HOR | SC_MF_VER );
595 if ( nNewFlags )
596 rNewSet.Put( ScMergeFlagAttr( nNewFlags ) );
597 else
598 rNewSet.ClearItem( ATTR_MERGE_FLAG );
601 for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
602 pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
603 static_cast<SCROW>(nCol-nCol1), aNewPattern, TRUE);
608 delete pAttrIter;
613 void ScTable::StartAllListeners()
615 for (SCCOL i=0; i<=MAXCOL; i++)
616 aCol[i].StartAllListeners();
620 void ScTable::StartNeededListeners()
622 for (SCCOL i=0; i<=MAXCOL; i++)
623 aCol[i].StartNeededListeners();
627 void ScTable::BroadcastInArea( SCCOL nCol1, SCROW nRow1,
628 SCCOL nCol2, SCROW nRow2 )
630 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
631 if (nRow2 > MAXROW) nRow2 = MAXROW;
632 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
633 for (SCCOL i = nCol1; i <= nCol2; i++)
634 aCol[i].BroadcastInArea( nRow1, nRow2 );
638 void ScTable::StartListeningInArea( SCCOL nCol1, SCROW nRow1,
639 SCCOL nCol2, SCROW nRow2 )
641 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
642 if (nRow2 > MAXROW) nRow2 = MAXROW;
643 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
644 for (SCCOL i = nCol1; i <= nCol2; i++)
645 aCol[i].StartListeningInArea( nRow1, nRow2 );
649 void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
650 USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
651 const ScMarkData* pMarkData,
652 BOOL bAsLink, BOOL bColRowFlags)
654 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
656 if (nFlags)
657 for (SCCOL i = nCol1; i <= nCol2; i++)
658 aCol[i].CopyToColumn(nRow1, nRow2, nFlags, bMarked,
659 pDestTab->aCol[i], pMarkData, bAsLink);
661 if (bColRowFlags) // Spaltenbreiten/Zeilenhoehen/Flags
663 // Charts muessen beim Ein-/Ausblenden angepasst werden
664 ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection();
666 bool bFlagChange = false;
668 BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
669 BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight);
671 if (bWidth||bHeight)
673 pDestTab->IncRecalcLevel();
675 if (bWidth)
676 for (SCCOL i=nCol1; i<=nCol2; i++)
678 bool bThisHidden = ColHidden(i);
679 bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden);
680 bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]);
681 pDestTab->pColWidth[i] = pColWidth[i];
682 pDestTab->pColFlags[i] = pColFlags[i];
683 pDestTab->SetColHidden(i, i, bThisHidden);
684 //! Aenderungen zusammenfassen?
685 if (bHiddenChange && pCharts)
686 pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
688 if (bChange)
689 bFlagChange = true;
692 if (bHeight)
694 bool bChange = pDestTab->pRowHeight->SumValues(nRow1, nRow2) != pRowHeight->SumValues(nRow1, nRow2);
696 if (bChange)
697 bFlagChange = true;
699 pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
700 pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
702 for (SCROW i = nRow1; i <= nRow2; ++i)
704 SCROW nThisLastRow, nDestLastRow;
705 bool bThisHidden = RowHidden(i, nThisLastRow);
706 bool bDestHidden = pDestTab->RowHidden(i, nDestLastRow);
708 // If the segment sizes differ, we take the shorter segment of the two.
709 SCROW nLastRow = ::std::min(nThisLastRow, nDestLastRow);
710 if (nLastRow >= nRow2)
711 // the last row shouldn't exceed the upper bound the caller specified.
712 nLastRow = nRow2;
714 pDestTab->SetRowHidden(i, nLastRow, bThisHidden);
716 bool bThisHiddenChange = (bThisHidden != bDestHidden);
717 if (bThisHiddenChange && pCharts)
719 // Hidden flags differ.
720 pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab));
723 if (bThisHiddenChange)
724 bFlagChange = true;
726 // Jump to the last row of the identical flag segment.
727 i = nLastRow;
730 pDestTab->DecRecalcLevel();
733 if (bFlagChange)
734 pDestTab->InvalidatePageBreaks();
736 pDestTab->SetOutlineTable( pOutlineTable ); // auch nur wenn bColRowFlags
742 void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
743 USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
744 const ScMarkData* pMarkData)
746 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
748 BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
749 BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight);
751 if (bWidth||bHeight)
752 nRecalcLvl++;
754 for ( SCCOL i = 0; i <= MAXCOL; i++)
756 if ( i >= nCol1 && i <= nCol2 )
757 aCol[i].UndoToColumn(nRow1, nRow2, nFlags, bMarked, pDestTab->aCol[i],
758 pMarkData);
759 else
760 aCol[i].CopyToColumn(0, MAXROW, IDF_FORMULA, FALSE, pDestTab->aCol[i]);
763 if (bWidth||bHeight)
765 if (bWidth)
766 for (SCCOL i=nCol1; i<=nCol2; i++)
767 pDestTab->pColWidth[i] = pColWidth[i];
768 if (bHeight)
769 pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
770 if( !--nRecalcLvl )
771 SetDrawPageSize();
777 void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
779 for (SCCOL i=0; i<=MAXCOL; i++)
780 aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
783 void ScTable::InvalidateTableArea()
785 bTableAreaValid = FALSE;
788 void ScTable::InvalidatePageBreaks()
790 mbPageBreaksValid = false;
793 void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
795 DBG_ASSERT( bScenario, "bScenario == FALSE" );
797 for (SCCOL i=0; i<=MAXCOL; i++)
798 aCol[i].CopyScenarioTo( pDestTab->aCol[i] );
801 void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
803 DBG_ASSERT( bScenario, "bScenario == FALSE" );
805 for (SCCOL i=0; i<=MAXCOL; i++)
806 aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
809 void ScTable::MarkScenarioIn( ScMarkData& rDestMark, USHORT nNeededBits ) const
811 DBG_ASSERT( bScenario, "bScenario == FALSE" );
813 if ( ( nScenarioFlags & nNeededBits ) != nNeededBits ) // alle Bits gesetzt?
814 return;
816 for (SCCOL i=0; i<=MAXCOL; i++)
817 aCol[i].MarkScenarioIn( rDestMark );
820 BOOL ScTable::HasScenarioRange( const ScRange& rRange ) const
822 DBG_ASSERT( bScenario, "bScenario == FALSE" );
824 // ScMarkData aMark;
825 // MarkScenarioIn( aMark, 0 ); //! Bits als Parameter von HasScenarioRange?
826 // return aMark.IsAllMarked( rRange );
828 ScRange aTabRange = rRange;
829 aTabRange.aStart.SetTab( nTab );
830 aTabRange.aEnd.SetTab( nTab );
832 const ScRangeList* pList = GetScenarioRanges();
833 // return ( pList && pList->Find( aTabRange ) );
835 if (pList)
837 ULONG nCount = pList->Count();
838 for ( ULONG j = 0; j < nCount; j++ )
840 ScRange* pR = pList->GetObject( j );
841 if ( pR->Intersects( aTabRange ) )
842 return TRUE;
846 return FALSE;
849 void ScTable::InvalidateScenarioRanges()
851 delete pScenarioRanges;
852 pScenarioRanges = NULL;
855 const ScRangeList* ScTable::GetScenarioRanges() const
857 DBG_ASSERT( bScenario, "bScenario == FALSE" );
859 if (!pScenarioRanges)
861 ((ScTable*)this)->pScenarioRanges = new ScRangeList;
862 ScMarkData aMark;
863 MarkScenarioIn( aMark, 0 ); // immer
864 aMark.FillRangeListWithMarks( pScenarioRanges, FALSE );
866 return pScenarioRanges;
869 BOOL ScTable::TestCopyScenarioTo( const ScTable* pDestTab ) const
871 DBG_ASSERT( bScenario, "bScenario == FALSE" );
873 if (!pDestTab->IsProtected())
874 return TRUE;
876 BOOL bOk = TRUE;
877 for (SCCOL i=0; i<=MAXCOL && bOk; i++)
878 bOk = aCol[i].TestCopyScenarioTo( pDestTab->aCol[i] );
879 return bOk;
882 void ScTable::PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell )
884 if (ValidColRow(nCol,nRow))
886 if (pCell)
887 aCol[nCol].Insert( nRow, pCell );
888 else
889 aCol[nCol].Delete( nRow );
894 void ScTable::PutCell( SCCOL nCol, SCROW nRow, ULONG nFormatIndex, ScBaseCell* pCell )
896 if (ValidColRow(nCol,nRow))
898 if (pCell)
899 aCol[nCol].Insert( nRow, nFormatIndex, pCell );
900 else
901 aCol[nCol].Delete( nRow );
906 void ScTable::PutCell( const ScAddress& rPos, ScBaseCell* pCell )
908 if (pCell)
909 aCol[rPos.Col()].Insert( rPos.Row(), pCell );
910 else
911 aCol[rPos.Col()].Delete( rPos.Row() );
915 //UNUSED2009-05 void ScTable::PutCell( const ScAddress& rPos, ULONG nFormatIndex, ScBaseCell* pCell )
916 //UNUSED2009-05 {
917 //UNUSED2009-05 if (pCell)
918 //UNUSED2009-05 aCol[rPos.Col()].Insert( rPos.Row(), nFormatIndex, pCell );
919 //UNUSED2009-05 else
920 //UNUSED2009-05 aCol[rPos.Col()].Delete( rPos.Row() );
921 //UNUSED2009-05 }
924 BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString,
925 ScSetStringParam* pParam )
927 if (ValidColRow(nCol,nRow))
928 return aCol[nCol].SetString(
929 nRow, nTabP, rString, pDocument->GetAddressConvention(), pParam );
930 else
931 return FALSE;
935 void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
937 if (ValidColRow(nCol, nRow))
938 aCol[nCol].SetValue( nRow, rVal );
942 void ScTable::GetString( SCCOL nCol, SCROW nRow, String& rString )
944 if (ValidColRow(nCol,nRow))
945 aCol[nCol].GetString( nRow, rString );
946 else
947 rString.Erase();
951 void ScTable::GetInputString( SCCOL nCol, SCROW nRow, String& rString )
953 if (ValidColRow(nCol,nRow))
954 aCol[nCol].GetInputString( nRow, rString );
955 else
956 rString.Erase();
960 double ScTable::GetValue( SCCOL nCol, SCROW nRow )
962 if (ValidColRow( nCol, nRow ))
963 return aCol[nCol].GetValue( nRow );
964 return 0.0;
968 void ScTable::GetFormula( SCCOL nCol, SCROW nRow, String& rFormula,
969 BOOL bAsciiExport )
971 if (ValidColRow(nCol,nRow))
972 aCol[nCol].GetFormula( nRow, rFormula, bAsciiExport );
973 else
974 rFormula.Erase();
978 ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
980 return ValidColRow( nCol, nRow ) ? aCol[ nCol ].GetNote( nRow ) : 0;
984 void ScTable::TakeNote( SCCOL nCol, SCROW nRow, ScPostIt*& rpNote )
986 if( ValidColRow( nCol, nRow ) )
988 aCol[ nCol ].TakeNote( nRow, rpNote );
989 if( rpNote && rpNote->GetNoteData().mxInitData.get() )
991 if( !mxUninitNotes.get() )
992 mxUninitNotes.reset( new ScAddress2DVec );
993 mxUninitNotes->push_back( ScAddress2D( nCol, nRow ) );
996 else
997 DELETEZ( rpNote );
1001 ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
1003 return ValidColRow( nCol, nRow ) ? aCol[ nCol ].ReleaseNote( nRow ) : 0;
1007 void ScTable::DeleteNote( SCCOL nCol, SCROW nRow )
1009 if( ValidColRow( nCol, nRow ) )
1010 aCol[ nCol ].DeleteNote( nRow );
1014 void ScTable::InitializeNoteCaptions( bool bForced )
1016 if( mxUninitNotes.get() && (bForced || pDocument->IsUndoEnabled()) )
1018 for( ScAddress2DVec::iterator aIt = mxUninitNotes->begin(), aEnd = mxUninitNotes->end(); aIt != aEnd; ++aIt )
1019 if( ScPostIt* pNote = GetNote( aIt->first, aIt->second ) )
1020 pNote->GetOrCreateCaption( ScAddress( aIt->first, aIt->second, nTab ) );
1021 mxUninitNotes.reset();
1025 CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
1027 if (ValidColRow( nCol, nRow ))
1028 return aCol[nCol].GetCellType( nRow );
1029 return CELLTYPE_NONE;
1033 ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
1035 if (ValidColRow( nCol, nRow ))
1036 return aCol[nCol].GetCell( nRow );
1038 DBG_ERROR("GetCell ausserhalb");
1039 return NULL;
1042 void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
1044 rCol = 0;
1045 rRow = 0;
1046 while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
1047 ++rCol;
1048 rRow = aCol[rCol].GetFirstDataPos();
1051 void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
1053 rCol = MAXCOL;
1054 rRow = 0;
1055 while (aCol[rCol].IsEmptyData() && (rCol > 0))
1056 rCol--;
1057 SCCOL nCol = rCol;
1058 while ((SCsCOL)nCol >= 0)
1060 rRow = Max(rRow, aCol[nCol].GetLastDataPos());
1061 nCol--;
1066 BOOL ScTable::HasData( SCCOL nCol, SCROW nRow )
1068 if (ValidColRow(nCol,nRow))
1069 return aCol[nCol].HasDataAt( nRow );
1070 else
1071 return FALSE;
1075 BOOL ScTable::HasStringData( SCCOL nCol, SCROW nRow )
1077 if (ValidColRow(nCol,nRow))
1078 return aCol[nCol].HasStringData( nRow );
1079 else
1080 return FALSE;
1084 BOOL ScTable::HasValueData( SCCOL nCol, SCROW nRow )
1086 if (ValidColRow(nCol,nRow))
1087 return aCol[nCol].HasValueData( nRow );
1088 else
1089 return FALSE;
1093 BOOL ScTable::HasStringCells( SCCOL nStartCol, SCROW nStartRow,
1094 SCCOL nEndCol, SCROW nEndRow ) const
1096 if ( ValidCol(nEndCol) )
1097 for ( SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++ )
1098 if (aCol[nCol].HasStringCells(nStartRow, nEndRow))
1099 return TRUE;
1101 return FALSE;
1105 //UNUSED2008-05 USHORT ScTable::GetErrCode( SCCOL nCol, SCROW nRow ) const
1106 //UNUSED2008-05 {
1107 //UNUSED2008-05 if (ValidColRow( nCol, nRow ))
1108 //UNUSED2008-05 return aCol[nCol].GetErrCode( nRow );
1109 //UNUSED2008-05 return 0;
1110 //UNUSED2008-05 }
1113 void ScTable::SetDirtyVar()
1115 for (SCCOL i=0; i<=MAXCOL; i++)
1116 aCol[i].SetDirtyVar();
1120 void ScTable::SetDirty()
1122 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1123 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1124 for (SCCOL i=0; i<=MAXCOL; i++)
1125 aCol[i].SetDirty();
1126 pDocument->SetAutoCalc( bOldAutoCalc );
1130 void ScTable::SetDirty( const ScRange& rRange )
1132 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1133 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1134 SCCOL nCol2 = rRange.aEnd.Col();
1135 for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1136 aCol[i].SetDirty( rRange );
1137 pDocument->SetAutoCalc( bOldAutoCalc );
1141 void ScTable::SetTableOpDirty( const ScRange& rRange )
1143 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1144 pDocument->SetAutoCalc( FALSE ); // no multiple recalculation
1145 SCCOL nCol2 = rRange.aEnd.Col();
1146 for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1147 aCol[i].SetTableOpDirty( rRange );
1148 pDocument->SetAutoCalc( bOldAutoCalc );
1152 void ScTable::SetDirtyAfterLoad()
1154 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1155 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1156 for (SCCOL i=0; i<=MAXCOL; i++)
1157 aCol[i].SetDirtyAfterLoad();
1158 pDocument->SetAutoCalc( bOldAutoCalc );
1162 void ScTable::SetRelNameDirty()
1164 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1165 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1166 for (SCCOL i=0; i<=MAXCOL; i++)
1167 aCol[i].SetRelNameDirty();
1168 pDocument->SetAutoCalc( bOldAutoCalc );
1172 void ScTable::CalcAll()
1174 for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll();
1178 void ScTable::CompileAll()
1180 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CompileAll();
1184 void ScTable::CompileXML( ScProgress& rProgress )
1186 for (SCCOL i=0; i <= MAXCOL; i++)
1188 aCol[i].CompileXML( rProgress );
1192 void ScTable::CalcAfterLoad()
1194 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CalcAfterLoad();
1198 bool ScTable::MarkUsedExternalReferences()
1200 bool bAllMarked = false;
1201 for (SCCOL i=0; i <= MAXCOL && !bAllMarked; ++i)
1203 bAllMarked = aCol[i].MarkUsedExternalReferences();
1205 return bAllMarked;
1209 void ScTable::ResetChanged( const ScRange& rRange )
1211 SCCOL nStartCol = rRange.aStart.Col();
1212 SCROW nStartRow = rRange.aStart.Row();
1213 SCCOL nEndCol = rRange.aEnd.Col();
1214 SCROW nEndRow = rRange.aEnd.Row();
1216 for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
1217 aCol[nCol].ResetChanged(nStartRow, nEndRow);
1220 // Attribute
1222 const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, USHORT nWhich ) const
1224 if (ValidColRow(nCol,nRow))
1225 return aCol[nCol].GetAttr( nRow, nWhich );
1226 else
1227 return NULL;
1231 ULONG ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
1233 if (ValidColRow(nCol,nRow))
1234 return aCol[nCol].GetNumberFormat( nRow );
1235 else
1236 return 0;
1239 sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1241 if (!ValidCol(nCol) || !ValidRow(nStartRow) || !ValidRow(nEndRow))
1242 return 0;
1244 return aCol[nCol].GetNumberFormat(nStartRow, nEndRow);
1248 const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
1250 if (ValidColRow(nCol,nRow))
1251 return aCol[nCol].GetPattern( nRow );
1252 else
1254 DBG_ERROR("wrong column or row");
1255 return pDocument->GetDefPattern(); // for safety
1260 const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1262 if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) )
1263 return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
1264 else
1265 return NULL;
1269 BOOL ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const
1271 BOOL bFound=FALSE;
1272 for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++)
1273 bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask );
1274 return bFound;
1278 //UNUSED2009-05 BOOL ScTable::HasLines( const ScRange& rRange, Rectangle& rSizes ) const
1279 //UNUSED2009-05 {
1280 //UNUSED2009-05 SCCOL nCol1 = rRange.aStart.Col();
1281 //UNUSED2009-05 SCROW nRow1 = rRange.aStart.Row();
1282 //UNUSED2009-05 SCCOL nCol2 = rRange.aEnd.Col();
1283 //UNUSED2009-05 SCROW nRow2 = rRange.aEnd.Row();
1284 //UNUSED2009-05 PutInOrder( nCol1, nCol2 );
1285 //UNUSED2009-05 PutInOrder( nRow1, nRow2 );
1286 //UNUSED2009-05
1287 //UNUSED2009-05 BOOL bFound = FALSE;
1288 //UNUSED2009-05 for (SCCOL i=nCol1; i<=nCol2; i++)
1289 //UNUSED2009-05 if (aCol[i].HasLines( nRow1, nRow2, rSizes, (i==nCol1), (i==nCol2) ))
1290 //UNUSED2009-05 bFound = TRUE;
1291 //UNUSED2009-05
1292 //UNUSED2009-05 return bFound;
1293 //UNUSED2009-05 }
1296 BOOL ScTable::HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const
1298 BOOL bFound=FALSE;
1299 for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
1300 bFound |= aCol[i].HasAttribSelection( rMark, nMask );
1301 return bFound;
1305 BOOL ScTable::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
1306 SCCOL& rEndCol, SCROW& rEndRow,
1307 BOOL bRefresh, BOOL bAttrs )
1309 if (!(ValidCol(nStartCol) && ValidCol(rEndCol)))
1311 DBG_ERRORFILE("ScTable::ExtendMerge: invalid column number");
1312 return FALSE;
1314 BOOL bFound=FALSE;
1315 SCCOL nOldEndX = rEndCol;
1316 SCROW nOldEndY = rEndRow;
1317 for (SCCOL i=nStartCol; i<=nOldEndX; i++)
1318 bFound |= aCol[i].ExtendMerge( i, nStartRow, nOldEndY, rEndCol, rEndRow, bRefresh, bAttrs );
1319 return bFound;
1323 BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const
1325 if (!(ValidCol(nCol1) && ValidCol(nCol2)))
1327 DBG_ERRORFILE("ScTable::IsBlockEmpty: invalid column number");
1328 return FALSE;
1330 BOOL bEmpty = TRUE;
1331 for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
1332 bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2, bIgnoreNotes );
1333 return bEmpty;
1336 SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
1337 SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
1338 const ScPatternAttr* pPattern, const SfxItemSet* pCondSet )
1340 // Rueckgabe = neues nArrY
1342 BYTE nRotDir = pPattern->GetRotateDir( pCondSet );
1343 if ( nRotDir != SC_ROTDIR_NONE )
1345 BOOL bHit = TRUE;
1346 if ( nCol+1 < nX1 ) // column to the left
1347 bHit = ( nRotDir != SC_ROTDIR_LEFT );
1348 else if ( nCol > nX2+1 ) // column to the right
1349 bHit = ( nRotDir != SC_ROTDIR_RIGHT ); // SC_ROTDIR_STANDARD may now also be extended to the left
1351 if ( bHit )
1353 double nFactor = 0.0;
1354 if ( nCol > nX2+1 )
1356 long nRotVal = ((const SfxInt32Item&) pPattern->
1357 GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue();
1358 double nRealOrient = nRotVal * F_PI18000; // 1/100 Grad
1359 double nCos = cos( nRealOrient );
1360 double nSin = sin( nRealOrient );
1361 //! begrenzen !!!
1362 //! zusaetzlich Faktor fuer unterschiedliche PPT X/Y !!!
1364 // bei SC_ROTDIR_LEFT kommt immer ein negativer Wert heraus,
1365 // wenn der Modus beruecksichtigt wird
1366 nFactor = -fabs( nCos / nSin );
1369 for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
1371 if (!RowHidden(nRow))
1373 BOOL bHitOne = TRUE;
1374 if ( nCol > nX2+1 )
1376 // reicht die gedrehte Zelle bis in den sichtbaren Bereich?
1378 SCCOL nTouchedCol = nCol;
1379 long nWidth = (long) ( pRowHeight->GetValue(nRow) * nFactor );
1380 DBG_ASSERT(nWidth <= 0, "Richtung falsch");
1381 while ( nWidth < 0 && nTouchedCol > 0 )
1383 --nTouchedCol;
1384 nWidth += GetColWidth( nTouchedCol );
1386 if ( nTouchedCol > nX2 )
1387 bHitOne = FALSE;
1390 if (bHitOne)
1392 while ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo < nRow )
1393 ++nArrY;
1394 if ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo == nRow )
1395 pRowInfo[nArrY].nRotMaxCol = nCol;
1402 return nArrY;
1405 void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 )
1407 if ( !pColWidth || !pRowHeight || !pColFlags || !pRowFlags )
1409 DBG_ERROR( "Spalten-/Zeileninfo fehlt" );
1410 return;
1413 // nRotMaxCol ist auf SC_ROTMAX_NONE initialisiert, nRowNo ist schon gesetzt
1415 SCROW nY1 = pRowInfo[0].nRowNo;
1416 SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
1418 for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
1420 if (!ColHidden(nCol))
1422 SCSIZE nArrY = 0;
1423 ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
1424 SCCOL nAttrCol;
1425 SCROW nAttrRow1, nAttrRow2;
1426 const ScPatternAttr* pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
1427 while ( pPattern )
1429 const SfxPoolItem* pCondItem;
1430 if ( pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, TRUE, &pCondItem )
1431 == SFX_ITEM_SET )
1433 // alle Formate durchgehen, damit die Zellen nicht einzeln
1434 // angeschaut werden muessen
1436 ULONG nIndex = ((const SfxUInt32Item*)pCondItem)->GetValue();
1437 ScConditionalFormatList* pList = pDocument->GetCondFormList();
1438 ScStyleSheetPool* pStylePool = pDocument->GetStyleSheetPool();
1439 if (pList && pStylePool && nIndex)
1441 const ScConditionalFormat* pFormat = pList->GetFormat(nIndex);
1442 if ( pFormat )
1444 USHORT nEntryCount = pFormat->Count();
1445 for (USHORT nEntry=0; nEntry<nEntryCount; nEntry++)
1447 String aStyleName = pFormat->GetEntry(nEntry)->GetStyle();
1448 if (aStyleName.Len())
1450 SfxStyleSheetBase* pStyleSheet =
1451 pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
1452 if ( pStyleSheet )
1454 FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
1455 nCol, nAttrRow1, nAttrRow2,
1456 nArrY, pPattern, &pStyleSheet->GetItemSet() );
1457 // nArrY nicht veraendern
1465 nArrY = FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
1466 nCol, nAttrRow1, nAttrRow2,
1467 nArrY, pPattern, NULL );
1469 pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
1475 BOOL ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
1477 // nix:0, mitte:1, unten:2, links:4, oben:8, rechts:16, offen:32
1478 USHORT nEdges;
1480 if ( nCol1 == nCol2 )
1481 { // linke und rechte Spalte
1482 const USHORT n = 4 | 16;
1483 nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n );
1484 // nicht (4 und 16) oder 1 oder 32
1485 if ( nEdges && (((nEdges & n) != n) || (nEdges & 33)) )
1486 return TRUE; // linke oder rechte Kante fehlt oder offen
1488 else
1489 { // linke Spalte
1490 nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, 4 );
1491 // nicht 4 oder 1 oder 32
1492 if ( nEdges && (((nEdges & 4) != 4) || (nEdges & 33)) )
1493 return TRUE; // linke Kante fehlt oder offen
1494 // rechte Spalte
1495 nEdges = aCol[nCol2].GetBlockMatrixEdges( nRow1, nRow2, 16 );
1496 // nicht 16 oder 1 oder 32
1497 if ( nEdges && (((nEdges & 16) != 16) || (nEdges & 33)) )
1498 return TRUE; // rechte Kante fehlt oder offen
1501 if ( nRow1 == nRow2 )
1502 { // obere und untere Zeile
1503 BOOL bOpen = FALSE;
1504 const USHORT n = 2 | 8;
1505 for ( SCCOL i=nCol1; i<=nCol2; i++)
1507 nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n );
1508 if ( nEdges )
1510 if ( (nEdges & n) != n )
1511 return TRUE; // obere oder untere Kante fehlt
1512 if ( nEdges & 4 )
1513 bOpen = TRUE; // linke Kante oeffnet, weitersehen
1514 else if ( !bOpen )
1515 return TRUE; // es gibt was, was nicht geoeffnet wurde
1516 if ( nEdges & 16 )
1517 bOpen = FALSE; // rechte Kante schliesst
1520 if ( bOpen )
1521 return TRUE; // es geht noch weiter
1523 else
1525 USHORT j, n;
1526 SCROW nR;
1527 // erst obere Zeile, dann untere Zeile
1528 for ( j=0, nR=nRow1, n=8; j<2; j++, nR=nRow2, n=2 )
1530 BOOL bOpen = FALSE;
1531 for ( SCCOL i=nCol1; i<=nCol2; i++)
1533 nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n );
1534 if ( nEdges )
1536 // in oberere Zeile keine obere Kante bzw.
1537 // in unterer Zeile keine untere Kante
1538 if ( (nEdges & n) != n )
1539 return TRUE;
1540 if ( nEdges & 4 )
1541 bOpen = TRUE; // linke Kante oeffnet, weitersehen
1542 else if ( !bOpen )
1543 return TRUE; // es gibt was, was nicht geoeffnet wurde
1544 if ( nEdges & 16 )
1545 bOpen = FALSE; // rechte Kante schliesst
1548 if ( bOpen )
1549 return TRUE; // es geht noch weiter
1552 return FALSE;
1556 BOOL ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
1558 BOOL bFound=FALSE;
1559 for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
1560 bFound |= aCol[i].HasSelectionMatrixFragment(rMark);
1561 return bFound;
1565 BOOL ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
1566 SCROW nRow2, BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
1568 if ( !ValidColRow( nCol2, nRow2 ) )
1570 DBG_ERRORFILE("IsBlockEditable: invalid column or row");
1571 if (pOnlyNotBecauseOfMatrix)
1572 *pOnlyNotBecauseOfMatrix = FALSE;
1573 return FALSE;
1576 BOOL bIsEditable = TRUE;
1577 if ( nLockCount )
1578 bIsEditable = FALSE;
1579 else if ( IsProtected() && !pDocument->IsScenario(nTab) )
1581 if((bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED )) != FALSE)
1583 // If Sheet is protected and cells are not protected then
1584 // check the active scenario protect flag if this range is
1585 // on the active scenario range. Note the 'copy back' must also
1586 // be set to apply protection.
1587 USHORT nScenTab = nTab+1;
1588 while(pDocument->IsScenario(nScenTab))
1590 ScRange aEditRange(nCol1, nRow1, nScenTab, nCol2, nRow2, nScenTab);
1591 if(pDocument->IsActiveScenario(nScenTab) && pDocument->HasScenarioRange(nScenTab, aEditRange))
1593 USHORT nFlags;
1594 pDocument->GetScenarioFlags(nScenTab,nFlags);
1595 bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
1596 break;
1598 nScenTab++;
1602 else if (pDocument->IsScenario(nTab))
1604 // Determine if the preceding sheet is protected
1605 SCTAB nActualTab = nTab;
1608 nActualTab--;
1610 while(pDocument->IsScenario(nActualTab));
1612 if(pDocument->IsTabProtected(nActualTab))
1614 ScRange aEditRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
1615 if(pDocument->HasScenarioRange(nTab, aEditRange))
1617 USHORT nFlags;
1618 pDocument->GetScenarioFlags(nTab,nFlags);
1619 bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
1623 if ( bIsEditable )
1625 if ( HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2 ) )
1627 bIsEditable = FALSE;
1628 if ( pOnlyNotBecauseOfMatrix )
1629 *pOnlyNotBecauseOfMatrix = TRUE;
1631 else if ( pOnlyNotBecauseOfMatrix )
1632 *pOnlyNotBecauseOfMatrix = FALSE;
1634 else if ( pOnlyNotBecauseOfMatrix )
1635 *pOnlyNotBecauseOfMatrix = FALSE;
1636 return bIsEditable;
1640 BOOL ScTable::IsSelectionEditable( const ScMarkData& rMark,
1641 BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
1643 BOOL bIsEditable = TRUE;
1644 if ( nLockCount )
1645 bIsEditable = FALSE;
1646 else if ( IsProtected() && !pDocument->IsScenario(nTab) )
1648 if((bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED )) != FALSE)
1650 // If Sheet is protected and cells are not protected then
1651 // check the active scenario protect flag if this area is
1652 // in the active scenario range.
1653 ScRangeList aRanges;
1654 rMark.FillRangeListWithMarks( &aRanges, FALSE );
1655 ULONG nRangeCount = aRanges.Count();
1656 SCTAB nScenTab = nTab+1;
1657 while(pDocument->IsScenario(nScenTab) && bIsEditable)
1659 if(pDocument->IsActiveScenario(nScenTab))
1661 for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
1663 ScRange aRange = *aRanges.GetObject(i);
1664 if(pDocument->HasScenarioRange(nScenTab, aRange))
1666 USHORT nFlags;
1667 pDocument->GetScenarioFlags(nScenTab,nFlags);
1668 bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
1672 nScenTab++;
1676 else if (pDocument->IsScenario(nTab))
1678 // Determine if the preceding sheet is protected
1679 SCTAB nActualTab = nTab;
1682 nActualTab--;
1684 while(pDocument->IsScenario(nActualTab));
1686 if(pDocument->IsTabProtected(nActualTab))
1688 ScRangeList aRanges;
1689 rMark.FillRangeListWithMarks( &aRanges, FALSE );
1690 ULONG nRangeCount = aRanges.Count();
1691 for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
1693 ScRange aRange = *aRanges.GetObject(i);
1694 if(pDocument->HasScenarioRange(nTab, aRange))
1696 USHORT nFlags;
1697 pDocument->GetScenarioFlags(nTab,nFlags);
1698 bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
1703 if ( bIsEditable )
1705 if ( HasSelectionMatrixFragment( rMark ) )
1707 bIsEditable = FALSE;
1708 if ( pOnlyNotBecauseOfMatrix )
1709 *pOnlyNotBecauseOfMatrix = TRUE;
1711 else if ( pOnlyNotBecauseOfMatrix )
1712 *pOnlyNotBecauseOfMatrix = FALSE;
1714 else if ( pOnlyNotBecauseOfMatrix )
1715 *pOnlyNotBecauseOfMatrix = FALSE;
1716 return bIsEditable;
1721 void ScTable::LockTable()
1723 ++nLockCount;
1727 void ScTable::UnlockTable()
1729 if (nLockCount)
1730 --nLockCount;
1731 else
1733 DBG_ERROR("UnlockTable ohne LockTable");
1738 void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, BOOL bDeep ) const
1740 for (SCCOL i=0; i<=MAXCOL; i++)
1741 aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
1745 void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1,
1746 SCCOL nCol2, SCROW nRow2, BOOL bDeep ) const
1748 for (SCCOL i=nCol1; i<=nCol2; i++)
1749 aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
1753 void ScTable::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
1754 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
1756 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1758 PutInOrder(nStartCol, nEndCol);
1759 PutInOrder(nStartRow, nEndRow);
1760 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1761 aCol[i].MergeBlockFrame( pLineOuter, pLineInner, rFlags,
1762 nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
1767 void ScTable::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
1768 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
1770 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1772 PutInOrder(nStartCol, nEndCol);
1773 PutInOrder(nStartRow, nEndRow);
1774 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1775 aCol[i].ApplyBlockFrame( pLineOuter, pLineInner,
1776 nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
1781 void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
1783 if (ValidColRow(nCol,nRow))
1784 aCol[nCol].ApplyPattern( nRow, rAttr );
1788 void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1789 const ScPatternAttr& rAttr, ScEditDataArray* pDataArray )
1791 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1793 PutInOrder(nStartCol, nEndCol);
1794 PutInOrder(nStartRow, nEndRow);
1795 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1796 aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray);
1800 void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
1801 const ScPatternAttr& rPattern, short nNewType )
1803 SCCOL nEndCol = rRange.aEnd.Col();
1804 for ( SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; nCol++ )
1806 aCol[nCol].ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
1812 void ScTable::ApplyStyle( SCCOL nCol, SCROW nRow, const ScStyleSheet& rStyle )
1814 if (ValidColRow(nCol,nRow))
1815 aCol[nCol].ApplyStyle( nRow, rStyle );
1819 void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
1821 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1823 PutInOrder(nStartCol, nEndCol);
1824 PutInOrder(nStartRow, nEndRow);
1825 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1826 aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
1831 void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
1833 for (SCCOL i=0; i<=MAXCOL; i++)
1834 aCol[i].ApplySelectionStyle( rStyle, rMark );
1838 void ScTable::ApplySelectionLineStyle( const ScMarkData& rMark,
1839 const SvxBorderLine* pLine, BOOL bColorOnly )
1841 if ( bColorOnly && !pLine )
1842 return;
1844 for (SCCOL i=0; i<=MAXCOL; i++)
1845 aCol[i].ApplySelectionLineStyle( rMark, pLine, bColorOnly );
1849 const ScStyleSheet* ScTable::GetStyle( SCCOL nCol, SCROW nRow ) const
1851 if (ValidColRow(nCol, nRow))
1852 return aCol[nCol].GetStyle(nRow);
1853 else
1854 return NULL;
1858 const ScStyleSheet* ScTable::GetSelectionStyle( const ScMarkData& rMark, BOOL& rFound ) const
1860 rFound = FALSE;
1862 BOOL bEqual = TRUE;
1863 BOOL bColFound;
1865 const ScStyleSheet* pStyle = NULL;
1866 const ScStyleSheet* pNewStyle;
1868 for (SCCOL i=0; i<=MAXCOL && bEqual; i++)
1869 if (rMark.HasMultiMarks(i))
1871 pNewStyle = aCol[i].GetSelectionStyle( rMark, bColFound );
1872 if (bColFound)
1874 rFound = TRUE;
1875 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
1876 bEqual = FALSE; // unterschiedliche
1877 pStyle = pNewStyle;
1881 return bEqual ? pStyle : NULL;
1885 const ScStyleSheet* ScTable::GetAreaStyle( BOOL& rFound, SCCOL nCol1, SCROW nRow1,
1886 SCCOL nCol2, SCROW nRow2 ) const
1888 rFound = FALSE;
1890 BOOL bEqual = TRUE;
1891 BOOL bColFound;
1893 const ScStyleSheet* pStyle = NULL;
1894 const ScStyleSheet* pNewStyle;
1896 for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
1898 pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
1899 if (bColFound)
1901 rFound = TRUE;
1902 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
1903 bEqual = FALSE; // unterschiedliche
1904 pStyle = pNewStyle;
1908 return bEqual ? pStyle : NULL;
1912 BOOL ScTable::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const
1914 BOOL bIsUsed = FALSE;
1916 for ( SCCOL i=0; i<=MAXCOL; i++ )
1918 if ( aCol[i].IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
1920 if ( !bGatherAllStyles )
1921 return TRUE;
1922 bIsUsed = TRUE;
1926 return bIsUsed;
1930 void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRemoved,
1931 OutputDevice* pDev,
1932 double nPPTX, double nPPTY,
1933 const Fraction& rZoomX, const Fraction& rZoomY )
1935 ScFlatBoolRowSegments aUsedRows;
1936 for (SCCOL i = 0; i <= MAXCOL; ++i)
1937 aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
1939 SCROW nRow = 0;
1940 while (nRow <= MAXROW)
1942 ScFlatBoolRowSegments::RangeData aData;
1943 if (!aUsedRows.getRangeData(nRow, aData))
1944 // search failed!
1945 return;
1947 SCROW nEndRow = aData.mnRow2;
1948 if (aData.mbValue)
1949 SetOptimalHeight(nRow, nEndRow, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE);
1951 nRow = nEndRow + 1;
1956 BOOL ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1957 INT16 nFlags )
1959 BOOL bChanged = FALSE;
1960 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1961 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1962 bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags);
1963 return bChanged;
1967 BOOL ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1968 INT16 nFlags )
1970 BOOL bChanged = FALSE;
1971 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1972 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1973 bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
1974 return bChanged;
1978 void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr, BOOL bPutToPool )
1980 if (ValidColRow(nCol,nRow))
1981 aCol[nCol].SetPattern( nRow, rAttr, bPutToPool );
1985 void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
1987 if (ValidColRow(nCol,nRow))
1988 aCol[nCol].ApplyAttr( nRow, rAttr );
1992 void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark,
1993 ScEditDataArray* pDataArray )
1995 for (SCCOL i=0; i<=MAXCOL; i++)
1996 aCol[i].ApplySelectionCache( pCache, rMark, pDataArray );
2000 void ScTable::ChangeSelectionIndent( BOOL bIncrement, const ScMarkData& rMark )
2002 for (SCCOL i=0; i<=MAXCOL; i++)
2003 aCol[i].ChangeSelectionIndent( bIncrement, rMark );
2007 void ScTable::ClearSelectionItems( const USHORT* pWhich, const ScMarkData& rMark )
2009 for (SCCOL i=0; i<=MAXCOL; i++)
2010 aCol[i].ClearSelectionItems( pWhich, rMark );
2014 // Spaltenbreiten / Zeilenhoehen
2016 void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
2018 if (VALIDCOL(nCol) && pColWidth)
2020 if (!nNewWidth)
2022 // DBG_ERROR("Spaltenbreite 0 in SetColWidth");
2023 nNewWidth = STD_COL_WIDTH;
2026 if ( nNewWidth != pColWidth[nCol] )
2028 nRecalcLvl++;
2029 InitializeNoteCaptions();
2030 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2031 if (pDrawLayer)
2032 pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
2033 pColWidth[nCol] = nNewWidth;
2034 if( !--nRecalcLvl )
2035 SetDrawPageSize();
2037 InvalidatePageBreaks();
2040 else
2042 DBG_ERROR("Falsche Spaltennummer oder keine Breiten");
2047 void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
2049 if (VALIDROW(nRow) && pRowHeight)
2051 if (!nNewHeight)
2053 DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
2054 nNewHeight = ScGlobal::nStdRowHeight;
2057 USHORT nOldHeight = pRowHeight->GetValue(nRow);
2058 if ( nNewHeight != nOldHeight )
2060 nRecalcLvl++;
2061 InitializeNoteCaptions();
2062 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2063 if (pDrawLayer)
2064 pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
2065 pRowHeight->SetValue( nRow, nNewHeight);
2066 if( !--nRecalcLvl )
2067 SetDrawPageSize();
2069 InvalidatePageBreaks();
2072 else
2074 DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
2079 BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight,
2080 double /* nPPTX */, double nPPTY )
2082 BOOL bChanged = FALSE;
2083 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
2085 nRecalcLvl++;
2086 InitializeNoteCaptions();
2087 if (!nNewHeight)
2089 DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
2090 nNewHeight = ScGlobal::nStdRowHeight;
2093 long nNewPix = (long) ( nNewHeight * nPPTY );
2095 BOOL bSingle = FALSE; // TRUE = process every row for its own
2096 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2097 if (pDrawLayer)
2098 if (pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ))
2099 bSingle = TRUE;
2101 if (bSingle)
2103 size_t nIndex;
2104 SCROW nRegionEndRow;
2105 USHORT nOldHeight = pRowHeight->GetValue( nStartRow, nIndex, nRegionEndRow);
2106 if (nNewHeight == nOldHeight && nEndRow <= nRegionEndRow)
2107 bSingle = FALSE; // no difference in this range
2109 if (bSingle)
2111 if (nEndRow-nStartRow < 20)
2113 // Whether new pixel size will differ from old pixel size in any row.
2114 ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight,
2115 nStartRow, nEndRow);
2118 if (*aIter != nNewHeight)
2119 bChanged = (nNewPix != (long) (*aIter * nPPTY));
2120 } while (!bChanged && aIter.NextRange());
2122 /* #i94028# #i94991# If drawing objects are involved, each row
2123 has to be changed for its own, because each call to
2124 ScDrawLayer::HeightChanged expects correct row heights
2125 above passed row in the document. Cannot use array iterator
2126 because array changes in every cycle. */
2127 if( pDrawLayer )
2129 for( SCROW nRow = nStartRow; nRow <= nEndRow ; ++nRow )
2131 pDrawLayer->HeightChanged( nTab, nRow,
2132 ((long) nNewHeight) - ((long) pRowHeight->GetValue( nRow )));
2133 pRowHeight->SetValue( nRow, nNewHeight );
2136 else
2137 pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
2139 else
2141 SCROW nMid = (nStartRow+nEndRow) / 2;
2142 if (SetRowHeightRange( nStartRow, nMid, nNewHeight, 1.0, 1.0 ))
2143 bChanged = TRUE;
2144 if (SetRowHeightRange( nMid+1, nEndRow, nNewHeight, 1.0, 1.0 ))
2145 bChanged = TRUE;
2148 else
2150 if (pDrawLayer)
2152 unsigned long nOldHeights = pRowHeight->SumValues( nStartRow, nEndRow);
2153 // FIXME: should we test for overflows?
2154 long nHeightDif = (long) (unsigned long) nNewHeight *
2155 (nEndRow - nStartRow + 1) - nOldHeights;
2156 pDrawLayer->HeightChanged( nTab, nEndRow, nHeightDif );
2158 // Whether new pixel size will differ from old pixel size in any row.
2159 ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight,
2160 nStartRow, nEndRow);
2163 if (*aIter != nNewHeight)
2164 bChanged = (nNewPix != (long) (*aIter * nPPTY));
2165 } while (!bChanged && aIter.NextRange());
2166 pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
2168 if( !--nRecalcLvl )
2169 SetDrawPageSize();
2171 if (bChanged)
2172 InvalidatePageBreaks();
2174 else
2176 DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
2179 return bChanged;
2183 void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
2185 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
2187 if (bManual)
2188 pRowFlags->OrValue( nStartRow, nEndRow, CR_MANUALSIZE);
2189 else
2190 pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
2192 else
2194 DBG_ERROR("Falsche Zeilennummer oder keine Zeilenflags");
2199 USHORT ScTable::GetColWidth( SCCOL nCol )
2201 DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
2203 if (VALIDCOL(nCol) && pColFlags && pColWidth)
2205 if (ColHidden(nCol))
2206 return 0;
2207 else
2208 return pColWidth[nCol];
2210 else
2211 return (USHORT) STD_COL_WIDTH;
2215 USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingestellte
2217 DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
2219 if (VALIDCOL(nCol) && pColWidth)
2220 return pColWidth[nCol];
2221 else
2222 return (USHORT) STD_COL_WIDTH;
2226 USHORT ScTable::GetCommonWidth( SCCOL nEndCol )
2228 // get the width that is used in the largest continuous column range (up to nEndCol)
2230 if ( !ValidCol(nEndCol) )
2232 DBG_ERROR("wrong column");
2233 nEndCol = MAXCOL;
2236 USHORT nMaxWidth = 0;
2237 USHORT nMaxCount = 0;
2238 SCCOL nRangeStart = 0;
2239 while ( nRangeStart <= nEndCol )
2241 // skip hidden columns
2242 while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) )
2243 ++nRangeStart;
2244 if ( nRangeStart <= nEndCol )
2246 USHORT nThisCount = 0;
2247 USHORT nThisWidth = pColWidth[nRangeStart];
2248 SCCOL nRangeEnd = nRangeStart;
2249 while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth )
2251 ++nThisCount;
2252 ++nRangeEnd;
2254 // skip hidden columns
2255 while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) )
2256 ++nRangeEnd;
2259 if ( nThisCount > nMaxCount )
2261 nMaxCount = nThisCount;
2262 nMaxWidth = nThisWidth;
2265 nRangeStart = nRangeEnd; // next range
2269 return nMaxWidth;
2273 USHORT ScTable::GetRowHeight( SCROW nRow )
2275 DBG_ASSERT(VALIDROW(nRow),"Falsche Zeilennummer");
2277 if (VALIDROW(nRow) && pRowHeight)
2279 if (RowHidden(nRow))
2280 return 0;
2281 else
2282 return pRowHeight->GetValue(nRow);
2284 else
2285 return (USHORT) ScGlobal::nStdRowHeight;
2289 ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow )
2291 DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
2293 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
2295 ULONG nHeight = 0;
2296 SCROW nRow = nStartRow;
2297 while (nRow <= nEndRow)
2299 SCROW nLastRow = -1;
2300 if (!RowHidden(nRow, nLastRow))
2302 if (nLastRow > nEndRow)
2303 nLastRow = nEndRow;
2304 nHeight += pRowFlags->SumCoupledArrayForCondition(nRow, nLastRow, 0, 0, *pRowHeight);
2306 nRow = nLastRow + 1;
2308 return nHeight;
2310 else
2311 return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight);
2315 ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale )
2317 DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
2319 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
2321 ULONG nHeight = 0;
2322 SCROW nRow = nStartRow;
2323 while (nRow <= nEndRow)
2325 SCROW nLastRow = -1;
2326 if (!RowHidden(nRow, nLastRow))
2328 if (nLastRow > nEndRow)
2329 nLastRow = nEndRow;
2330 nHeight += pRowFlags->SumScaledCoupledArrayForCondition(
2331 nRow, nLastRow, 0, 0, *pRowHeight, fScale);
2333 nRow = nLastRow + 1;
2335 return nHeight;
2337 else
2338 return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
2342 USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hidden
2344 DBG_ASSERT(VALIDROW(nRow),"wrong row number");
2346 if (VALIDROW(nRow) && pRowHeight)
2347 return pRowHeight->GetValue(nRow);
2348 else
2349 return (USHORT) ScGlobal::nStdRowHeight;
2353 // Spalten-/Zeilen-Flags
2356 SCROW ScTable::GetHiddenRowCount( SCROW nRow )
2358 if (!ValidRow(nRow))
2359 return 0;
2361 SCROW nLastRow = -1;
2362 if (!RowHidden(nRow, nLastRow) || !ValidRow(nLastRow))
2363 return 0;
2365 return nLastRow - nRow + 1;
2369 //! ShowRows / DBShowRows zusammenfassen
2371 void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
2373 if (VALIDCOL(nCol))
2375 bool bWasVis = !ColHidden(nCol);
2376 if (bWasVis != bShow)
2378 nRecalcLvl++;
2379 InitializeNoteCaptions();
2380 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2381 if (pDrawLayer)
2383 if (bShow)
2384 pDrawLayer->WidthChanged( nTab, nCol, (long) pColWidth[nCol] );
2385 else
2386 pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] );
2389 SetColHidden(nCol, nCol, !bShow);
2391 if( !--nRecalcLvl )
2392 SetDrawPageSize();
2394 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2395 if ( pCharts )
2396 pCharts->SetRangeDirty(ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ));
2399 else
2401 DBG_ERROR("Falsche Spaltennummer oder keine Flags");
2406 void ScTable::ShowRow(SCROW nRow, BOOL bShow)
2408 if (VALIDROW(nRow) && pRowFlags)
2410 bool bWasVis = !RowHidden(nRow);
2411 if (bWasVis != bShow)
2413 nRecalcLvl++;
2414 InitializeNoteCaptions();
2415 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2416 if (pDrawLayer)
2418 if (bShow)
2419 pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
2420 else
2421 pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
2424 SetRowHidden(nRow, nRow, !bShow);
2425 if (bShow)
2426 SetRowFiltered(nRow, nRow, false);
2428 if( !--nRecalcLvl )
2429 SetDrawPageSize();
2431 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2432 if ( pCharts )
2433 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
2435 InvalidatePageBreaks();
2438 else
2440 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2445 void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
2447 if (VALIDROW(nRow) && pRowFlags)
2449 bool bWasVis = !RowHidden(nRow);
2450 nRecalcLvl++;
2451 InitializeNoteCaptions();
2452 if (bWasVis != bShow)
2454 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2455 if (pDrawLayer)
2457 if (bShow)
2458 pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
2459 else
2460 pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
2464 // Filter-Flag immer setzen, auch wenn Hidden unveraendert
2466 SetRowHidden(nRow, nRow, !bShow);
2467 SetRowFiltered(nRow, nRow, !bShow);
2469 if( !--nRecalcLvl )
2470 SetDrawPageSize();
2472 if (bWasVis != bShow)
2474 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2475 if ( pCharts )
2476 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
2478 if (pOutlineTable)
2479 UpdateOutlineRow( nRow, nRow, bShow );
2481 InvalidatePageBreaks();
2484 else
2486 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2491 void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
2493 SCROW nStartRow = nRow1;
2494 nRecalcLvl++;
2495 InitializeNoteCaptions();
2496 while (nStartRow <= nRow2)
2498 SCROW nEndRow = -1;
2499 bool bWasVis = !RowHidden(nStartRow, nEndRow);
2500 if (nEndRow > nRow2)
2501 nEndRow = nRow2;
2503 BOOL bChanged = ( bWasVis != bShow );
2504 if ( bChanged )
2506 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2507 if (pDrawLayer)
2509 long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
2510 if (bShow)
2511 pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
2512 else
2513 pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
2517 SetRowHidden(nStartRow, nEndRow, !bShow);
2518 SetRowFiltered(nStartRow, nEndRow, !bShow);
2520 if ( bChanged )
2522 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2523 if ( pCharts )
2524 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
2527 nStartRow = nEndRow + 1;
2530 // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
2531 // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
2532 // to be done here.
2533 if (pOutlineTable)
2534 UpdateOutlineRow( nRow1, nRow2, bShow );
2536 if( !--nRecalcLvl )
2537 SetDrawPageSize();
2541 void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
2543 SCROW nStartRow = nRow1;
2544 nRecalcLvl++;
2545 InitializeNoteCaptions();
2546 while (nStartRow <= nRow2)
2548 SCROW nEndRow = -1;
2549 bool bWasVis = !RowHidden(nStartRow, nEndRow);
2550 if (nEndRow > nRow2)
2551 nEndRow = nRow2;
2553 BOOL bChanged = ( bWasVis != bShow );
2554 if ( bChanged )
2556 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2557 if (pDrawLayer)
2559 long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
2560 if (bShow)
2561 pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
2562 else
2563 pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
2567 SetRowHidden(nStartRow, nEndRow, !bShow);
2568 if (bShow)
2569 SetRowFiltered(nStartRow, nEndRow, false);
2571 if ( bChanged )
2573 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2574 if ( pCharts )
2575 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
2577 InvalidatePageBreaks();
2580 nStartRow = nEndRow + 1;
2582 if( !--nRecalcLvl )
2583 SetDrawPageSize();
2587 void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags )
2589 if (VALIDCOL(nCol) && pColFlags)
2590 pColFlags[nCol] = nNewFlags;
2591 else
2593 DBG_ERROR("Falsche Spaltennummer oder keine Flags");
2598 void ScTable::SetRowFlags( SCROW nRow, BYTE nNewFlags )
2600 if (VALIDROW(nRow) && pRowFlags)
2601 pRowFlags->SetValue( nRow, nNewFlags);
2602 else
2604 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2609 void ScTable::SetRowFlags( SCROW nStartRow, SCROW nEndRow, BYTE nNewFlags )
2611 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
2612 pRowFlags->SetValue( nStartRow, nEndRow, nNewFlags);
2613 else
2615 DBG_ERROR("Falsche Zeilennummer(n) oder keine Flags");
2620 BYTE ScTable::GetColFlags( SCCOL nCol ) const
2622 if (VALIDCOL(nCol) && pColFlags)
2623 return pColFlags[nCol];
2624 else
2625 return 0;
2629 BYTE ScTable::GetRowFlags( SCROW nRow ) const
2631 if (VALIDROW(nRow) && pRowFlags)
2632 return pRowFlags->GetValue(nRow);
2633 else
2634 return 0;
2638 SCROW ScTable::GetLastFlaggedRow() const
2640 if ( !pRowFlags )
2641 return 0;
2643 SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
2644 return ValidRow(nLastFound) ? nLastFound : 0;
2648 SCCOL ScTable::GetLastChangedCol() const
2650 if ( !pColFlags )
2651 return 0;
2653 SCCOL nLastFound = 0;
2654 for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
2655 if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH))
2656 nLastFound = nCol;
2658 return nLastFound;
2662 SCROW ScTable::GetLastChangedRow() const
2664 if ( !pRowFlags )
2665 return 0;
2667 SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
2668 if (!ValidRow(nLastFlags))
2669 nLastFlags = 0;
2671 SCROW nLastHeight = pRowHeight->GetLastUnequalAccess( 0, ScGlobal::nStdRowHeight);
2672 if (!ValidRow(nLastHeight))
2673 nLastHeight = 0;
2675 return std::max( nLastFlags, nLastHeight);
2679 BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
2681 if (pOutlineTable && pColFlags)
2683 ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
2684 return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, *this, true );
2686 else
2687 return FALSE;
2691 BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
2693 if (pOutlineTable && pRowFlags)
2694 return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *this, false );
2695 else
2696 return FALSE;
2700 void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
2702 // Column-wise expansion
2704 while (rX1 > 0 && ColHidden(rX1-1))
2705 --rX1;
2707 while (rX2 < MAXCOL && ColHidden(rX2+1))
2708 ++rX2;
2710 // Row-wise expansion
2712 if (rY1 > 0)
2714 ScFlatBoolRowSegments::RangeData aData;
2715 if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
2717 SCROW nStartRow = aData.mnRow1;
2718 if (ValidRow(nStartRow))
2719 rY1 = nStartRow;
2722 if (rY2 < MAXROW)
2724 SCROW nEndRow = -1;
2725 if (RowHidden(rY2+1, nEndRow) && ValidRow(nEndRow))
2726 rY2 = nEndRow;
2731 void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
2733 while ( rX2>rX1 && ColHidden(rX2) )
2734 --rX2;
2735 while ( rX2>rX1 && ColHidden(rX1) )
2736 ++rX1;
2738 if (rY1 < rY2)
2740 ScFlatBoolRowSegments::RangeData aData;
2741 if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
2743 SCROW nStartRow = aData.mnRow1;
2744 if (ValidRow(nStartRow) && nStartRow >= rY1)
2745 rY2 = nStartRow;
2749 if (rY1 < rY2)
2751 SCROW nEndRow = -1;
2752 if (RowHidden(rY1, nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2)
2753 rY1 = nEndRow;
2758 // Auto-Outline
2760 template< typename T >
2761 short DiffSign( T a, T b )
2763 return (a<b) ? -1 :
2764 (a>b) ? 1 : 0;
2768 void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
2770 BOOL bSizeChanged = FALSE;
2771 BOOL bMissed = FALSE;
2773 SCCOL nCol;
2774 SCROW nRow;
2775 SCROW i;
2776 BOOL bFound;
2777 ScOutlineArray* pArray;
2778 ScBaseCell* pCell;
2779 ScRange aRef;
2780 /* ScPatternAttr aBoldPattern( pDocument->GetPool() ); //! spezielle Format-Vorlage
2781 aBoldPattern.GetItemSet().Put( SvxWeightItem( WEIGHT_BOLD ) );
2784 StartOutlineTable();
2786 // Zeilen
2788 SCROW nCount = nEndRow-nStartRow+1;
2789 BOOL* pUsed = new BOOL[nCount];
2790 for (i=0; i<nCount; i++)
2791 pUsed[i] = FALSE;
2792 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
2793 if (!aCol[nCol].IsEmptyData())
2794 aCol[nCol].FindUsed( nStartRow, nEndRow, pUsed );
2796 pArray = pOutlineTable->GetRowArray();
2797 for (nRow=nStartRow; nRow<=nEndRow; nRow++)
2798 if (pUsed[nRow-nStartRow])
2800 bFound = FALSE;
2801 for (nCol=nStartCol; nCol<=nEndCol && !bFound; nCol++)
2802 if (!aCol[nCol].IsEmptyData())
2804 pCell = aCol[nCol].GetCell( nRow );
2805 if (pCell)
2806 if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2807 if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
2808 if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
2809 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
2810 DiffSign( aRef.aStart.Row(), nRow ) ==
2811 DiffSign( aRef.aEnd.Row(), nRow ) )
2813 if (pArray->Insert( aRef.aStart.Row(), aRef.aEnd.Row(), bSizeChanged ))
2815 // ApplyPatternArea( nStartCol, nRow, nEndCol, nRow, aBoldPattern );
2816 bFound = TRUE;
2818 else
2819 bMissed = TRUE;
2824 delete[] pUsed;
2826 // Spalten
2828 pArray = pOutlineTable->GetColArray();
2829 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
2831 if (!aCol[nCol].IsEmptyData())
2833 bFound = FALSE;
2834 ScColumnIterator aIter( &aCol[nCol], nStartRow, nEndRow );
2835 while ( aIter.Next( nRow, pCell ) && !bFound )
2837 if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2838 if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
2839 if ( aRef.aStart.Row() == nRow && aRef.aEnd.Row() == nRow &&
2840 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
2841 DiffSign( aRef.aStart.Col(), nCol ) ==
2842 DiffSign( aRef.aEnd.Col(), nCol ) )
2844 if (pArray->Insert( aRef.aStart.Col(), aRef.aEnd.Col(), bSizeChanged ))
2846 // ApplyPatternArea( nCol, nStartRow, nCol, nEndRow, aBoldPattern );
2847 bFound = TRUE;
2849 else
2850 bMissed = TRUE;
2857 // CopyData - fuer Query in anderen Bereich
2859 void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2860 SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab )
2862 //! wenn fuer mehrere Zeilen benutzt, nach Spalten optimieren!
2864 ScAddress aSrc( nStartCol, nStartRow, nTab );
2865 ScAddress aDest( nDestCol, nDestRow, nDestTab );
2866 ScRange aRange( aSrc, aDest );
2867 BOOL bThisTab = ( nDestTab == nTab );
2868 SCROW nDestY = nDestRow;
2869 for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
2871 aSrc.SetRow( nRow );
2872 aDest.SetRow( nDestY );
2873 SCCOL nDestX = nDestCol;
2874 for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
2876 aSrc.SetCol( nCol );
2877 aDest.SetCol( nDestX );
2878 ScBaseCell* pCell = GetCell( nCol, nRow );
2879 if (pCell)
2881 pCell = pCell->CloneWithoutNote( *pDocument );
2882 if (pCell->GetCellType() == CELLTYPE_FORMULA)
2884 ((ScFormulaCell*)pCell)->UpdateReference( URM_COPY, aRange,
2885 ((SCsCOL) nDestCol) - ((SCsCOL) nStartCol),
2886 ((SCsROW) nDestRow) - ((SCsROW) nStartRow),
2887 ((SCsTAB) nDestTab) - ((SCsTAB) nTab) );
2888 ((ScFormulaCell*)pCell)->aPos = aDest;
2891 if (bThisTab)
2893 PutCell( nDestX, nDestY, pCell );
2894 SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ), TRUE );
2896 else
2898 pDocument->PutCell( aDest, pCell );
2899 pDocument->SetPattern( aDest, *GetPattern( nCol, nRow ), TRUE );
2902 ++nDestX;
2904 ++nDestY;
2909 BOOL ScTable::RefVisible(ScFormulaCell* pCell)
2911 ScRange aRef;
2913 if (pCell->HasOneReference(aRef))
2915 if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
2917 SCROW nEndRow;
2918 if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow))
2919 // row not filtered.
2920 nEndRow = ::std::numeric_limits<SCROW>::max();
2922 if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
2923 return TRUE; // at least partly visible
2924 return FALSE; // completely invisible
2928 return TRUE; // irgendwie anders
2932 void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, String& rStr)
2934 GetInputString(nCol, nRow, rStr);
2935 rStr.EraseTrailingChars();
2936 rStr.EraseLeadingChars();
2937 ScGlobal::pCharClass->toUpper(rStr);
2941 // Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
2943 void ScTable::SetDrawPageSize(bool bResetStreamValid)
2945 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2946 if( pDrawLayer )
2948 long x = GetColOffset( MAXCOL + 1 );
2949 long y = GetRowOffset( MAXROW + 1 );
2950 x = (long) ((double) x * HMM_PER_TWIPS);
2951 y = (long) ((double) y * HMM_PER_TWIPS);
2953 if ( IsLayoutRTL() ) // IsNegativePage
2954 x = -x;
2956 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ) );
2959 // #i102616# actions that modify the draw page size count as sheet modification
2960 // (exception: InitDrawLayer)
2961 if (bResetStreamValid && IsStreamValid())
2962 SetStreamValid(FALSE);
2966 ULONG ScTable::GetRowOffset( SCROW nRow )
2968 ULONG n = 0;
2969 if ( pRowFlags && pRowHeight )
2971 if (nRow == 0)
2972 return 0;
2973 else if (nRow == 1)
2974 return GetRowHeight(0);
2976 n = GetTotalRowHeight(0, nRow-1);
2977 #ifdef DBG_UTIL
2978 if (n == ::std::numeric_limits<unsigned long>::max())
2979 DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow");
2980 #endif
2982 else
2984 DBG_ERROR("GetRowOffset: Daten fehlen");
2986 return n;
2989 SCROW ScTable::GetRowForHeight(ULONG nHeight)
2991 sal_uInt32 nSum = 0;
2993 ScFlatBoolRowSegments::RangeData aData;
2994 for (SCROW nRow = 0; nRow <= MAXROW; ++nRow)
2996 if (!mpHiddenRows->getRangeData(nRow, aData))
2997 break;
2999 if (aData.mbValue)
3001 nRow = aData.mnRow2;
3002 continue;
3005 sal_uInt32 nNew = pRowHeight->GetValue(nRow);
3006 nSum += nNew;
3007 if (nSum > nHeight)
3009 return nRow < MAXROW ? nRow + 1 : MAXROW;
3012 return -1;
3016 ULONG ScTable::GetColOffset( SCCOL nCol )
3018 ULONG n = 0;
3019 if ( pColWidth )
3021 SCCOL i;
3022 for( i = 0; i < nCol; i++ )
3023 if (!ColHidden(i))
3024 n += pColWidth[i];
3026 else
3028 DBG_ERROR("GetColumnOffset: Daten fehlen");
3030 return n;