update ooo310-m15
[ooovba.git] / sc / source / core / data / table2.cxx
blob96eceb15b811403dc7be8a77e4dbe25de45bded9
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 if (nStartCol==0 && nEndCol==MAXCOL)
123 if (pRowHeight && pRowFlags)
125 pRowHeight->Insert( nStartRow, nSize);
126 BYTE nNewFlags = pRowFlags->Insert( nStartRow, nSize);
127 // only copy manual size flag, clear all others
128 if (nNewFlags && (nNewFlags != CR_MANUALSIZE))
129 pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1,
130 nNewFlags & CR_MANUALSIZE);
132 if (pOutlineTable)
133 pOutlineTable->InsertRow( nStartRow, nSize );
135 mpFilteredRows->insertSegment(nStartRow, nSize, true);
136 mpHiddenRows->insertSegment(nStartRow, nSize, true);
139 for (SCCOL j=nStartCol; j<=nEndCol; j++)
140 aCol[j].InsertRow( nStartRow, nSize );
141 if( !--nRecalcLvl )
142 SetDrawPageSize();
144 InvalidatePageBreaks();
148 void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
149 BOOL* pUndoOutline )
151 nRecalcLvl++;
152 if (nStartCol==0 && nEndCol==MAXCOL)
154 if (pRowHeight && pRowFlags)
156 pRowHeight->Remove( nStartRow, nSize);
157 pRowFlags->Remove( nStartRow, nSize);
159 if (pOutlineTable)
160 if (pOutlineTable->DeleteRow( nStartRow, nSize ))
161 if (pUndoOutline)
162 *pUndoOutline = TRUE;
164 mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
165 mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
168 { // scope for bulk broadcast
169 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
170 for (SCCOL j=nStartCol; j<=nEndCol; j++)
171 aCol[j].DeleteRow( nStartRow, nSize );
173 if( !--nRecalcLvl )
174 SetDrawPageSize();
176 InvalidatePageBreaks();
180 BOOL ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
182 BOOL bTest = TRUE;
184 if ( nStartRow==0 && nEndRow==MAXROW && pOutlineTable )
185 bTest = pOutlineTable->TestInsertCol(nSize);
187 if ( nSize > static_cast<SCSIZE>(MAXCOL) )
188 bTest = FALSE;
190 for (SCCOL i=MAXCOL; (i+static_cast<SCCOL>(nSize)>MAXCOL) && bTest; i--)
191 bTest = aCol[i].TestInsertCol(nStartRow, nEndRow);
193 return bTest;
197 void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
199 nRecalcLvl++;
200 if (nStartRow==0 && nEndRow==MAXROW)
202 if (pColWidth && pColFlags)
204 memmove( &pColWidth[nStartCol+nSize], &pColWidth[nStartCol],
205 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
206 memmove( &pColFlags[nStartCol+nSize], &pColFlags[nStartCol],
207 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
209 if (pOutlineTable)
210 pOutlineTable->InsertCol( nStartCol, nSize );
212 mpHiddenCols->insertSegment(nStartCol, nSize, true);
213 mpFilteredCols->insertSegment(nStartCol, nSize, true);
217 if ((nStartRow == 0) && (nEndRow == MAXROW))
219 for (SCSIZE i=0; i < nSize; i++)
220 for (SCCOL nCol = MAXCOL; nCol > nStartCol; nCol--)
221 aCol[nCol].SwapCol(aCol[nCol-1]);
223 else
225 for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
226 aCol[MAXCOL - nSize - i].MoveTo(nStartRow, nEndRow, aCol[MAXCOL - i]);
229 if (nStartCol>0) // copy old attributes
231 USHORT nWhichArray[2];
232 nWhichArray[0] = ATTR_MERGE;
233 nWhichArray[1] = 0;
235 for (SCSIZE i=0; i<nSize; i++)
237 aCol[nStartCol-1].CopyToColumn( nStartRow, nEndRow, IDF_ATTRIB,
238 FALSE, aCol[nStartCol+i] );
239 aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
240 SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
241 aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray );
244 if( !--nRecalcLvl )
245 SetDrawPageSize();
247 InvalidatePageBreaks();
251 void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize,
252 BOOL* pUndoOutline )
254 nRecalcLvl++;
255 if (nStartRow==0 && nEndRow==MAXROW)
257 if (pColWidth && pColFlags)
259 memmove( &pColWidth[nStartCol], &pColWidth[nStartCol+nSize],
260 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
261 memmove( &pColFlags[nStartCol], &pColFlags[nStartCol+nSize],
262 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
264 if (pOutlineTable)
265 if (pOutlineTable->DeleteCol( nStartCol, nSize ))
266 if (pUndoOutline)
267 *pUndoOutline = TRUE;
269 mpHiddenCols->removeSegment(nStartCol, nStartCol+nSize);
270 mpFilteredCols->removeSegment(nStartCol, nStartCol+nSize);
274 { // scope for bulk broadcast
275 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
276 for (SCSIZE i = 0; i < nSize; i++)
277 aCol[nStartCol + i].DeleteArea(nStartRow, nEndRow, IDF_ALL);
280 if ((nStartRow == 0) && (nEndRow == MAXROW))
282 for (SCSIZE i=0; i < nSize; i++)
283 for (SCCOL nCol = nStartCol; nCol < MAXCOL; nCol++)
284 aCol[nCol].SwapCol(aCol[nCol+1]);
286 else
288 for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
289 aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
291 if( !--nRecalcLvl )
292 SetDrawPageSize();
294 InvalidatePageBreaks();
298 void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nDelFlag)
300 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
301 if (nRow2 > MAXROW) nRow2 = MAXROW;
302 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
304 // nRecalcLvl++;
306 { // scope for bulk broadcast
307 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
308 for (SCCOL i = nCol1; i <= nCol2; i++)
309 aCol[i].DeleteArea(nRow1, nRow2, nDelFlag);
313 // Zellschutz auf geschuetzter Tabelle nicht setzen
316 if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
318 ScPatternAttr aPattern(pDocument->GetPool());
319 aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
320 ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
323 /* if( !--nRecalcLvl )
324 SetDrawPageSize();
330 void ScTable::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
332 { // scope for bulk broadcast
333 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
334 for (SCCOL i=0; i<=MAXCOL; i++)
335 aCol[i].DeleteSelection( nDelFlag, rMark );
339 // Zellschutz auf geschuetzter Tabelle nicht setzen
342 if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
344 ScDocumentPool* pPool = pDocument->GetPool();
345 SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
346 aSet.Put( ScProtectionAttr( FALSE ) );
347 SfxItemPoolCache aCache( pPool, &aSet );
348 ApplySelectionCache( &aCache, rMark );
353 // pTable = Clipboard
354 void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
355 ScTable* pTable, BOOL bKeepScenarioFlags, BOOL bCloneNoteCaptions)
357 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
359 // Inhalte kopieren
360 SCCOL i;
362 for ( i = nCol1; i <= nCol2; i++)
363 aCol[i].CopyToClip(nRow1, nRow2, pTable->aCol[i], bKeepScenarioFlags, bCloneNoteCaptions);
365 // copy widths/heights, and only "hidden", "filtered" and "manual" flags
366 // also for all preceding columns/rows, to have valid positions for drawing objects
368 if (pColWidth && pTable->pColWidth)
369 for (i=0; i<=nCol2; i++)
370 pTable->pColWidth[i] = pColWidth[i];
372 pTable->CopyColHidden(*this, 0, nCol2);
373 pTable->CopyColFiltered(*this, 0, nCol2);
375 if (pRowFlags && pTable->pRowFlags && pRowHeight && pTable->pRowHeight)
377 pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
378 pTable->pRowHeight->CopyFrom( *pRowHeight, 0, nRow2);
381 pTable->CopyRowHidden(*this, 0, nRow2);
382 pTable->CopyRowFiltered(*this, 0, nRow2);
384 // ggf. Formeln durch Werte ersetzen
386 if ( IsProtected() )
387 for (i = nCol1; i <= nCol2; i++)
388 pTable->aCol[i].RemoveProtected(nRow1, nRow2);
392 void ScTable::CopyToClip(const ScRangeList& rRanges, ScTable* pTable,
393 bool bKeepScenarioFlags, bool bCloneNoteCaptions)
395 ScRangeList aRanges(rRanges);
396 for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
398 CopyToClip(p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(),
399 pTable, bKeepScenarioFlags, bCloneNoteCaptions);
403 void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
404 SCsCOL nDx, SCsROW nDy, USHORT nInsFlag,
405 BOOL bAsLink, BOOL bSkipAttrForEmpty, ScTable* pTable)
407 SCCOL i;
409 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
410 if (nRow2 > MAXROW) nRow2 = MAXROW;
411 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
413 nRecalcLvl++;
414 for ( i = nCol1; i <= nCol2; i++)
415 aCol[i].CopyFromClip(nRow1, nRow2, nDy, nInsFlag, bAsLink, bSkipAttrForEmpty, pTable->aCol[i - nDx]);
417 if ((nInsFlag & IDF_ATTRIB) != 0)
419 if (nRow1==0 && nRow2==MAXROW && pColWidth && pTable->pColWidth)
420 for (i=nCol1; i<=nCol2; i++)
421 pColWidth[i] = pTable->pColWidth[i-nDx];
423 if (nCol1==0 && nCol2==MAXCOL && pRowHeight && pTable->pRowHeight &&
424 pRowFlags && pTable->pRowFlags)
426 pRowHeight->CopyFrom( *pTable->pRowHeight, nRow1, nRow2, -nDy);
427 // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
428 for (SCROW j=nRow1; j<=nRow2; j++)
430 if ( pTable->pRowFlags->GetValue(j-nDy) & CR_MANUALSIZE )
431 pRowFlags->OrValue( j, CR_MANUALSIZE);
432 else
433 pRowFlags->AndValue( j, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
438 // Zellschutz auf geschuetzter Tabelle nicht setzen
441 if ( IsProtected() && (nInsFlag & IDF_ATTRIB) )
443 ScPatternAttr aPattern(pDocument->GetPool());
444 aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
445 ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
448 if( !--nRecalcLvl )
449 SetDrawPageSize();
454 void ScTable::MixData( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
455 USHORT nFunction, BOOL bSkipEmpty, ScTable* pSrcTab )
457 for (SCCOL i=nCol1; i<=nCol2; i++)
458 aCol[i].MixData( nRow1, nRow2, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
462 // Markierung von diesem Dokument
463 void ScTable::MixMarked( const ScMarkData& rMark, USHORT nFunction,
464 BOOL bSkipEmpty, ScTable* pSrcTab )
466 for (SCCOL i=0; i<=MAXCOL; i++)
467 aCol[i].MixMarked( rMark, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
471 void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
472 ScTable* pTransClip, USHORT nFlags, BOOL bAsLink )
474 BOOL bWasCut = pDocument->IsCutMode();
476 ScDocument* pDestDoc = pTransClip->pDocument;
478 for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
480 SCROW nRow;
481 ScBaseCell* pCell;
483 if ( bAsLink && nFlags == IDF_ALL )
485 // #68989# with IDF_ALL, also create links (formulas) for empty cells
487 for ( nRow=nRow1; nRow<=nRow2; nRow++ )
489 // create simple formula, as in ScColumn::CreateRefCell
491 ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
492 ScSingleRefData aRef;
493 aRef.nCol = nCol;
494 aRef.nRow = nRow;
495 aRef.nTab = nTab;
496 aRef.InitFlags(); // -> all absolute
497 aRef.SetFlag3D(TRUE);
498 aRef.CalcRelFromAbs( aDestPos );
499 ScTokenArray aArr;
500 aArr.AddSingleReference( aRef );
502 ScBaseCell* pNew = new ScFormulaCell( pDestDoc, aDestPos, &aArr );
503 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
506 else
508 ScColumnIterator aIter( &aCol[nCol], nRow1, nRow2 );
509 while (aIter.Next( nRow, pCell ))
511 ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
512 ScBaseCell* pNew;
513 if ( bAsLink ) // Referenz erzeugen ?
515 pNew = aCol[nCol].CreateRefCell( pDestDoc, aDestPos, aIter.GetIndex(), nFlags );
517 else // kopieren
519 if (pCell->GetCellType() == CELLTYPE_FORMULA)
521 pNew = pCell->CloneWithNote( *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
523 // Referenzen drehen
524 // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
526 if (!bWasCut)
527 ((ScFormulaCell*)pNew)->TransposeReference();
529 else
530 pNew = pCell->CloneWithNote( *pDestDoc, aDestPos );
532 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
536 // Attribute
538 SCROW nAttrRow1;
539 SCROW nAttrRow2;
540 const ScPatternAttr* pPattern;
541 ScAttrIterator* pAttrIter = aCol[nCol].CreateAttrIterator( nRow1, nRow2 );
542 while ( (pPattern = pAttrIter->Next( nAttrRow1, nAttrRow2 )) != 0 )
544 if ( !IsDefaultItem( pPattern ) )
546 const SfxItemSet& rSet = pPattern->GetItemSet();
547 if ( rSet.GetItemState( ATTR_MERGE, FALSE ) == SFX_ITEM_DEFAULT &&
548 rSet.GetItemState( ATTR_MERGE_FLAG, FALSE ) == SFX_ITEM_DEFAULT &&
549 rSet.GetItemState( ATTR_BORDER, FALSE ) == SFX_ITEM_DEFAULT )
551 // no borders or merge items involved - use pattern as-is
552 for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
553 pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern, TRUE );
555 else
557 // transpose borders and merge values, remove merge flags (refreshed after pasting)
558 ScPatternAttr aNewPattern( *pPattern );
559 SfxItemSet& rNewSet = aNewPattern.GetItemSet();
561 const SvxBoxItem& rOldBox = (const SvxBoxItem&)rSet.Get(ATTR_BORDER);
562 if ( rOldBox.GetTop() || rOldBox.GetBottom() || rOldBox.GetLeft() || rOldBox.GetRight() )
564 SvxBoxItem aNew( ATTR_BORDER );
565 aNew.SetLine( rOldBox.GetLine( BOX_LINE_TOP ), BOX_LINE_LEFT );
566 aNew.SetLine( rOldBox.GetLine( BOX_LINE_LEFT ), BOX_LINE_TOP );
567 aNew.SetLine( rOldBox.GetLine( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
568 aNew.SetLine( rOldBox.GetLine( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
569 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_TOP ), BOX_LINE_LEFT );
570 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_LEFT ), BOX_LINE_TOP );
571 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
572 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
573 rNewSet.Put( aNew );
576 const ScMergeAttr& rOldMerge = (const ScMergeAttr&)rSet.Get(ATTR_MERGE);
577 if (rOldMerge.IsMerged())
578 rNewSet.Put( ScMergeAttr( Min(
579 static_cast<SCsCOL>(rOldMerge.GetRowMerge()),
580 static_cast<SCsCOL>(MAXCOL+1 - (nAttrRow2-nRow1))),
581 Min(
582 static_cast<SCsROW>(rOldMerge.GetColMerge()),
583 static_cast<SCsROW>(MAXROW+1 - (nCol-nCol1)))));
584 const ScMergeFlagAttr& rOldFlag = (const ScMergeFlagAttr&)rSet.Get(ATTR_MERGE_FLAG);
585 if (rOldFlag.IsOverlapped())
587 INT16 nNewFlags = rOldFlag.GetValue() & ~( SC_MF_HOR | SC_MF_VER );
588 if ( nNewFlags )
589 rNewSet.Put( ScMergeFlagAttr( nNewFlags ) );
590 else
591 rNewSet.ClearItem( ATTR_MERGE_FLAG );
594 for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
595 pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
596 static_cast<SCROW>(nCol-nCol1), aNewPattern, TRUE);
601 delete pAttrIter;
606 void ScTable::StartAllListeners()
608 for (SCCOL i=0; i<=MAXCOL; i++)
609 aCol[i].StartAllListeners();
613 void ScTable::StartNeededListeners()
615 for (SCCOL i=0; i<=MAXCOL; i++)
616 aCol[i].StartNeededListeners();
620 void ScTable::BroadcastInArea( SCCOL nCol1, SCROW nRow1,
621 SCCOL nCol2, SCROW nRow2 )
623 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
624 if (nRow2 > MAXROW) nRow2 = MAXROW;
625 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
626 for (SCCOL i = nCol1; i <= nCol2; i++)
627 aCol[i].BroadcastInArea( nRow1, nRow2 );
631 void ScTable::StartListeningInArea( SCCOL nCol1, SCROW nRow1,
632 SCCOL nCol2, SCROW nRow2 )
634 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
635 if (nRow2 > MAXROW) nRow2 = MAXROW;
636 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
637 for (SCCOL i = nCol1; i <= nCol2; i++)
638 aCol[i].StartListeningInArea( nRow1, nRow2 );
642 void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
643 USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
644 const ScMarkData* pMarkData,
645 BOOL bAsLink, BOOL bColRowFlags)
647 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
649 if (nFlags)
650 for (SCCOL i = nCol1; i <= nCol2; i++)
651 aCol[i].CopyToColumn(nRow1, nRow2, nFlags, bMarked,
652 pDestTab->aCol[i], pMarkData, bAsLink);
654 if (bColRowFlags) // Spaltenbreiten/Zeilenhoehen/Flags
656 // Charts muessen beim Ein-/Ausblenden angepasst werden
657 ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection();
659 bool bFlagChange = false;
660 if (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth)
661 for (SCCOL i=nCol1; i<=nCol2; i++)
663 bool bThisHidden = ColHidden(i);
664 bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden);
665 bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]);
666 pDestTab->pColWidth[i] = pColWidth[i];
667 pDestTab->pColFlags[i] = pColFlags[i];
668 pDestTab->SetColHidden(i, i, bThisHidden);
669 //! Aenderungen zusammenfassen?
670 if (bHiddenChange && pCharts)
671 pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
673 if (bChange)
674 bFlagChange = true;
677 if (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight)
679 bool bChange = pDestTab->pRowHeight->SumValues(nRow1, nRow2) != pRowHeight->SumValues(nRow1, nRow2);
680 if (bChange)
681 bFlagChange = true;
683 pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
684 pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
686 for (SCROW i = nRow1; i <= nRow2; ++i)
688 SCROW nThisLastRow, nDestLastRow;
689 bool bThisHidden = RowHidden(i, nThisLastRow);
690 bool bDestHidden = pDestTab->RowHidden(i, nDestLastRow);
692 // If the segment sizes differ, we take the shorter segment of the two.
693 SCROW nLastRow = ::std::min(nThisLastRow, nDestLastRow);
694 if (nLastRow >= nRow2)
695 // the last row shouldn't exceed the upper bound the caller specified.
696 nLastRow = nRow2;
698 pDestTab->SetRowHidden(i, nLastRow, bThisHidden);
700 bool bThisHiddenChange = (bThisHidden != bDestHidden);
701 if (bThisHiddenChange && pCharts)
703 // Hidden flags differ.
704 pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab));
707 if (bThisHiddenChange)
708 bFlagChange = true;
710 // Jump to the last row of the identical flag segment.
711 i = nLastRow;
715 if (bFlagChange)
716 pDestTab->InvalidatePageBreaks();
718 pDestTab->SetOutlineTable( pOutlineTable ); // auch nur wenn bColRowFlags
724 void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
725 USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
726 const ScMarkData* pMarkData)
728 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
730 BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
731 BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight);
733 if (bWidth||bHeight)
734 nRecalcLvl++;
736 for ( SCCOL i = 0; i <= MAXCOL; i++)
738 if ( i >= nCol1 && i <= nCol2 )
739 aCol[i].UndoToColumn(nRow1, nRow2, nFlags, bMarked, pDestTab->aCol[i],
740 pMarkData);
741 else
742 aCol[i].CopyToColumn(0, MAXROW, IDF_FORMULA, FALSE, pDestTab->aCol[i]);
745 if (bWidth||bHeight)
747 if (bWidth)
748 for (SCCOL i=nCol1; i<=nCol2; i++)
749 pDestTab->pColWidth[i] = pColWidth[i];
750 if (bHeight)
751 pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
752 if( !--nRecalcLvl )
753 SetDrawPageSize();
759 void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
761 for (SCCOL i=0; i<=MAXCOL; i++)
762 aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
765 void ScTable::InvalidateTableArea()
767 bTableAreaValid = FALSE;
770 void ScTable::InvalidatePageBreaks()
772 mbPageBreaksValid = false;
775 void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
777 DBG_ASSERT( bScenario, "bScenario == FALSE" );
779 for (SCCOL i=0; i<=MAXCOL; i++)
780 aCol[i].CopyScenarioTo( pDestTab->aCol[i] );
783 void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
785 DBG_ASSERT( bScenario, "bScenario == FALSE" );
787 for (SCCOL i=0; i<=MAXCOL; i++)
788 aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
791 void ScTable::MarkScenarioIn( ScMarkData& rDestMark, USHORT nNeededBits ) const
793 DBG_ASSERT( bScenario, "bScenario == FALSE" );
795 if ( ( nScenarioFlags & nNeededBits ) != nNeededBits ) // alle Bits gesetzt?
796 return;
798 for (SCCOL i=0; i<=MAXCOL; i++)
799 aCol[i].MarkScenarioIn( rDestMark );
802 BOOL ScTable::HasScenarioRange( const ScRange& rRange ) const
804 DBG_ASSERT( bScenario, "bScenario == FALSE" );
806 // ScMarkData aMark;
807 // MarkScenarioIn( aMark, 0 ); //! Bits als Parameter von HasScenarioRange?
808 // return aMark.IsAllMarked( rRange );
810 ScRange aTabRange = rRange;
811 aTabRange.aStart.SetTab( nTab );
812 aTabRange.aEnd.SetTab( nTab );
814 const ScRangeList* pList = GetScenarioRanges();
815 // return ( pList && pList->Find( aTabRange ) );
817 if (pList)
819 ULONG nCount = pList->Count();
820 for ( ULONG j = 0; j < nCount; j++ )
822 ScRange* pR = pList->GetObject( j );
823 if ( pR->Intersects( aTabRange ) )
824 return TRUE;
828 return FALSE;
831 void ScTable::InvalidateScenarioRanges()
833 delete pScenarioRanges;
834 pScenarioRanges = NULL;
837 const ScRangeList* ScTable::GetScenarioRanges() const
839 DBG_ASSERT( bScenario, "bScenario == FALSE" );
841 if (!pScenarioRanges)
843 ((ScTable*)this)->pScenarioRanges = new ScRangeList;
844 ScMarkData aMark;
845 MarkScenarioIn( aMark, 0 ); // immer
846 aMark.FillRangeListWithMarks( pScenarioRanges, FALSE );
848 return pScenarioRanges;
851 BOOL ScTable::TestCopyScenarioTo( const ScTable* pDestTab ) const
853 DBG_ASSERT( bScenario, "bScenario == FALSE" );
855 if (!pDestTab->IsProtected())
856 return TRUE;
858 BOOL bOk = TRUE;
859 for (SCCOL i=0; i<=MAXCOL && bOk; i++)
860 bOk = aCol[i].TestCopyScenarioTo( pDestTab->aCol[i] );
861 return bOk;
864 void ScTable::PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell )
866 if (ValidColRow(nCol,nRow))
868 if (pCell)
869 aCol[nCol].Insert( nRow, pCell );
870 else
871 aCol[nCol].Delete( nRow );
876 void ScTable::PutCell( SCCOL nCol, SCROW nRow, ULONG nFormatIndex, ScBaseCell* pCell )
878 if (ValidColRow(nCol,nRow))
880 if (pCell)
881 aCol[nCol].Insert( nRow, nFormatIndex, pCell );
882 else
883 aCol[nCol].Delete( nRow );
888 void ScTable::PutCell( const ScAddress& rPos, ScBaseCell* pCell )
890 if (pCell)
891 aCol[rPos.Col()].Insert( rPos.Row(), pCell );
892 else
893 aCol[rPos.Col()].Delete( rPos.Row() );
897 void ScTable::PutCell( const ScAddress& rPos, ULONG nFormatIndex, ScBaseCell* pCell )
899 if (pCell)
900 aCol[rPos.Col()].Insert( rPos.Row(), nFormatIndex, pCell );
901 else
902 aCol[rPos.Col()].Delete( rPos.Row() );
906 BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString,
907 SvNumberFormatter* pFormatter, bool bDetectNumberFormat )
909 if (ValidColRow(nCol,nRow))
910 return aCol[nCol].SetString(
911 nRow, nTabP, rString, pDocument->GetAddressConvention(), pFormatter, bDetectNumberFormat );
912 else
913 return FALSE;
917 void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
919 if (ValidColRow(nCol, nRow))
920 aCol[nCol].SetValue( nRow, rVal );
924 void ScTable::GetString( SCCOL nCol, SCROW nRow, String& rString )
926 if (ValidColRow(nCol,nRow))
927 aCol[nCol].GetString( nRow, rString );
928 else
929 rString.Erase();
933 void ScTable::GetInputString( SCCOL nCol, SCROW nRow, String& rString )
935 if (ValidColRow(nCol,nRow))
936 aCol[nCol].GetInputString( nRow, rString );
937 else
938 rString.Erase();
942 double ScTable::GetValue( SCCOL nCol, SCROW nRow )
944 if (ValidColRow( nCol, nRow ))
945 return aCol[nCol].GetValue( nRow );
946 return 0.0;
950 void ScTable::GetFormula( SCCOL nCol, SCROW nRow, String& rFormula,
951 BOOL bAsciiExport )
953 if (ValidColRow(nCol,nRow))
954 aCol[nCol].GetFormula( nRow, rFormula, bAsciiExport );
955 else
956 rFormula.Erase();
960 ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
962 return ValidColRow( nCol, nRow ) ? aCol[ nCol ].GetNote( nRow ) : 0;
966 void ScTable::TakeNote( SCCOL nCol, SCROW nRow, ScPostIt*& rpNote )
968 if( ValidColRow( nCol, nRow ) )
969 aCol[ nCol ].TakeNote( nRow, rpNote );
970 else
971 DELETEZ( rpNote );
975 ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
977 return ValidColRow( nCol, nRow ) ? aCol[ nCol ].ReleaseNote( nRow ) : 0;
981 void ScTable::DeleteNote( SCCOL nCol, SCROW nRow )
983 if( ValidColRow( nCol, nRow ) )
984 aCol[ nCol ].DeleteNote( nRow );
988 CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
990 if (ValidColRow( nCol, nRow ))
991 return aCol[nCol].GetCellType( nRow );
992 return CELLTYPE_NONE;
996 ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
998 if (ValidColRow( nCol, nRow ))
999 return aCol[nCol].GetCell( nRow );
1001 DBG_ERROR("GetCell ausserhalb");
1002 return NULL;
1005 void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
1007 rCol = 0;
1008 rRow = 0;
1009 while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
1010 ++rCol;
1011 rRow = aCol[rCol].GetFirstDataPos();
1014 void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
1016 rCol = MAXCOL;
1017 rRow = 0;
1018 while (aCol[rCol].IsEmptyData() && (rCol > 0))
1019 rCol--;
1020 SCCOL nCol = rCol;
1021 while ((SCsCOL)nCol >= 0)
1023 rRow = Max(rRow, aCol[nCol].GetLastDataPos());
1024 nCol--;
1029 BOOL ScTable::HasData( SCCOL nCol, SCROW nRow )
1031 if (ValidColRow(nCol,nRow))
1032 return aCol[nCol].HasDataAt( nRow );
1033 else
1034 return FALSE;
1038 BOOL ScTable::HasStringData( SCCOL nCol, SCROW nRow )
1040 if (ValidColRow(nCol,nRow))
1041 return aCol[nCol].HasStringData( nRow );
1042 else
1043 return FALSE;
1047 BOOL ScTable::HasValueData( SCCOL nCol, SCROW nRow )
1049 if (ValidColRow(nCol,nRow))
1050 return aCol[nCol].HasValueData( nRow );
1051 else
1052 return FALSE;
1056 BOOL ScTable::HasStringCells( SCCOL nStartCol, SCROW nStartRow,
1057 SCCOL nEndCol, SCROW nEndRow ) const
1059 if ( ValidCol(nEndCol) )
1060 for ( SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++ )
1061 if (aCol[nCol].HasStringCells(nStartRow, nEndRow))
1062 return TRUE;
1064 return FALSE;
1068 //UNUSED2008-05 USHORT ScTable::GetErrCode( SCCOL nCol, SCROW nRow ) const
1069 //UNUSED2008-05 {
1070 //UNUSED2008-05 if (ValidColRow( nCol, nRow ))
1071 //UNUSED2008-05 return aCol[nCol].GetErrCode( nRow );
1072 //UNUSED2008-05 return 0;
1073 //UNUSED2008-05 }
1076 void ScTable::SetDirtyVar()
1078 for (SCCOL i=0; i<=MAXCOL; i++)
1079 aCol[i].SetDirtyVar();
1083 void ScTable::SetDirty()
1085 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1086 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1087 for (SCCOL i=0; i<=MAXCOL; i++)
1088 aCol[i].SetDirty();
1089 pDocument->SetAutoCalc( bOldAutoCalc );
1093 void ScTable::SetDirty( const ScRange& rRange )
1095 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1096 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1097 SCCOL nCol2 = rRange.aEnd.Col();
1098 for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1099 aCol[i].SetDirty( rRange );
1100 pDocument->SetAutoCalc( bOldAutoCalc );
1104 void ScTable::SetTableOpDirty( const ScRange& rRange )
1106 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1107 pDocument->SetAutoCalc( FALSE ); // no multiple recalculation
1108 SCCOL nCol2 = rRange.aEnd.Col();
1109 for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1110 aCol[i].SetTableOpDirty( rRange );
1111 pDocument->SetAutoCalc( bOldAutoCalc );
1115 void ScTable::SetDirtyAfterLoad()
1117 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1118 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1119 for (SCCOL i=0; i<=MAXCOL; i++)
1120 aCol[i].SetDirtyAfterLoad();
1121 pDocument->SetAutoCalc( bOldAutoCalc );
1125 void ScTable::SetRelNameDirty()
1127 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1128 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1129 for (SCCOL i=0; i<=MAXCOL; i++)
1130 aCol[i].SetRelNameDirty();
1131 pDocument->SetAutoCalc( bOldAutoCalc );
1135 void ScTable::CalcAll()
1137 for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll();
1141 void ScTable::CompileAll()
1143 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CompileAll();
1147 void ScTable::CompileXML( ScProgress& rProgress )
1149 for (SCCOL i=0; i <= MAXCOL; i++)
1151 aCol[i].CompileXML( rProgress );
1155 void ScTable::CalcAfterLoad()
1157 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CalcAfterLoad();
1161 bool ScTable::MarkUsedExternalReferences()
1163 bool bAllMarked = false;
1164 for (SCCOL i=0; i <= MAXCOL && !bAllMarked; ++i)
1166 bAllMarked = aCol[i].MarkUsedExternalReferences();
1168 return bAllMarked;
1172 void ScTable::ResetChanged( const ScRange& rRange )
1174 SCCOL nStartCol = rRange.aStart.Col();
1175 SCROW nStartRow = rRange.aStart.Row();
1176 SCCOL nEndCol = rRange.aEnd.Col();
1177 SCROW nEndRow = rRange.aEnd.Row();
1179 for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
1180 aCol[nCol].ResetChanged(nStartRow, nEndRow);
1183 // Attribute
1185 const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, USHORT nWhich ) const
1187 if (ValidColRow(nCol,nRow))
1188 return aCol[nCol].GetAttr( nRow, nWhich );
1189 else
1190 return NULL;
1194 ULONG ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
1196 if (ValidColRow(nCol,nRow))
1197 return aCol[nCol].GetNumberFormat( nRow );
1198 else
1199 return 0;
1202 sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1204 if (!ValidCol(nCol) || !ValidRow(nStartRow) || !ValidRow(nEndRow))
1205 return 0;
1207 return aCol[nCol].GetNumberFormat(nStartRow, nEndRow);
1211 const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
1213 if (ValidColRow(nCol,nRow))
1214 return aCol[nCol].GetPattern( nRow );
1215 else
1217 DBG_ERROR("wrong column or row");
1218 return pDocument->GetDefPattern(); // for safety
1223 const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1225 if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) )
1226 return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
1227 else
1228 return NULL;
1232 BOOL ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const
1234 BOOL bFound=FALSE;
1235 for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++)
1236 bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask );
1237 return bFound;
1241 BOOL ScTable::HasLines( const ScRange& rRange, Rectangle& rSizes ) const
1243 SCCOL nCol1 = rRange.aStart.Col();
1244 SCROW nRow1 = rRange.aStart.Row();
1245 SCCOL nCol2 = rRange.aEnd.Col();
1246 SCROW nRow2 = rRange.aEnd.Row();
1247 PutInOrder( nCol1, nCol2 );
1248 PutInOrder( nRow1, nRow2 );
1250 BOOL bFound = FALSE;
1251 for (SCCOL i=nCol1; i<=nCol2; i++)
1252 if (aCol[i].HasLines( nRow1, nRow2, rSizes, (i==nCol1), (i==nCol2) ))
1253 bFound = TRUE;
1255 return bFound;
1259 BOOL ScTable::HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const
1261 BOOL bFound=FALSE;
1262 for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
1263 bFound |= aCol[i].HasAttribSelection( rMark, nMask );
1264 return bFound;
1268 BOOL ScTable::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
1269 SCCOL& rEndCol, SCROW& rEndRow,
1270 BOOL bRefresh, BOOL bAttrs )
1272 if (!(ValidCol(nStartCol) && ValidCol(rEndCol)))
1274 DBG_ERRORFILE("ScTable::ExtendMerge: invalid column number");
1275 return FALSE;
1277 BOOL bFound=FALSE;
1278 SCCOL nOldEndX = rEndCol;
1279 SCROW nOldEndY = rEndRow;
1280 for (SCCOL i=nStartCol; i<=nOldEndX; i++)
1281 bFound |= aCol[i].ExtendMerge( i, nStartRow, nOldEndY, rEndCol, rEndRow, bRefresh, bAttrs );
1282 return bFound;
1286 BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const
1288 if (!(ValidCol(nCol1) && ValidCol(nCol2)))
1290 DBG_ERRORFILE("ScTable::IsBlockEmpty: invalid column number");
1291 return FALSE;
1293 BOOL bEmpty = TRUE;
1294 for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
1295 bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2, bIgnoreNotes );
1296 return bEmpty;
1299 SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
1300 SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
1301 const ScPatternAttr* pPattern, const SfxItemSet* pCondSet )
1303 // Rueckgabe = neues nArrY
1305 BYTE nRotDir = pPattern->GetRotateDir( pCondSet );
1306 if ( nRotDir != SC_ROTDIR_NONE )
1308 BOOL bHit = TRUE;
1309 if ( nCol+1 < nX1 ) // column to the left
1310 bHit = ( nRotDir != SC_ROTDIR_LEFT );
1311 else if ( nCol > nX2+1 ) // column to the right
1312 bHit = ( nRotDir != SC_ROTDIR_RIGHT ); // SC_ROTDIR_STANDARD may now also be extended to the left
1314 if ( bHit )
1316 double nFactor = 0.0;
1317 if ( nCol > nX2+1 )
1319 long nRotVal = ((const SfxInt32Item&) pPattern->
1320 GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue();
1321 double nRealOrient = nRotVal * F_PI18000; // 1/100 Grad
1322 double nCos = cos( nRealOrient );
1323 double nSin = sin( nRealOrient );
1324 //! begrenzen !!!
1325 //! zusaetzlich Faktor fuer unterschiedliche PPT X/Y !!!
1327 // bei SC_ROTDIR_LEFT kommt immer ein negativer Wert heraus,
1328 // wenn der Modus beruecksichtigt wird
1329 nFactor = -fabs( nCos / nSin );
1332 for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
1334 if (!RowHidden(nRow))
1336 BOOL bHitOne = TRUE;
1337 if ( nCol > nX2+1 )
1339 // reicht die gedrehte Zelle bis in den sichtbaren Bereich?
1341 SCCOL nTouchedCol = nCol;
1342 long nWidth = (long) ( pRowHeight->GetValue(nRow) * nFactor );
1343 DBG_ASSERT(nWidth <= 0, "Richtung falsch");
1344 while ( nWidth < 0 && nTouchedCol > 0 )
1346 --nTouchedCol;
1347 nWidth += GetColWidth( nTouchedCol );
1349 if ( nTouchedCol > nX2 )
1350 bHitOne = FALSE;
1353 if (bHitOne)
1355 while ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo < nRow )
1356 ++nArrY;
1357 if ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo == nRow )
1358 pRowInfo[nArrY].nRotMaxCol = nCol;
1365 return nArrY;
1368 void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 )
1370 if ( !pColWidth || !pRowHeight || !pColFlags || !pRowFlags )
1372 DBG_ERROR( "Spalten-/Zeileninfo fehlt" );
1373 return;
1376 // nRotMaxCol ist auf SC_ROTMAX_NONE initialisiert, nRowNo ist schon gesetzt
1378 SCROW nY1 = pRowInfo[0].nRowNo;
1379 SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
1381 for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
1383 if (!ColHidden(nCol))
1385 SCSIZE nArrY = 0;
1386 ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
1387 SCCOL nAttrCol;
1388 SCROW nAttrRow1, nAttrRow2;
1389 const ScPatternAttr* pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
1390 while ( pPattern )
1392 const SfxPoolItem* pCondItem;
1393 if ( pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, TRUE, &pCondItem )
1394 == SFX_ITEM_SET )
1396 // alle Formate durchgehen, damit die Zellen nicht einzeln
1397 // angeschaut werden muessen
1399 ULONG nIndex = ((const SfxUInt32Item*)pCondItem)->GetValue();
1400 ScConditionalFormatList* pList = pDocument->GetCondFormList();
1401 ScStyleSheetPool* pStylePool = pDocument->GetStyleSheetPool();
1402 if (pList && pStylePool && nIndex)
1404 const ScConditionalFormat* pFormat = pList->GetFormat(nIndex);
1405 if ( pFormat )
1407 USHORT nEntryCount = pFormat->Count();
1408 for (USHORT nEntry=0; nEntry<nEntryCount; nEntry++)
1410 String aStyleName = pFormat->GetEntry(nEntry)->GetStyle();
1411 if (aStyleName.Len())
1413 SfxStyleSheetBase* pStyleSheet =
1414 pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
1415 if ( pStyleSheet )
1417 FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
1418 nCol, nAttrRow1, nAttrRow2,
1419 nArrY, pPattern, &pStyleSheet->GetItemSet() );
1420 // nArrY nicht veraendern
1428 nArrY = FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
1429 nCol, nAttrRow1, nAttrRow2,
1430 nArrY, pPattern, NULL );
1432 pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
1438 BOOL ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
1440 // nix:0, mitte:1, unten:2, links:4, oben:8, rechts:16, offen:32
1441 USHORT nEdges;
1443 if ( nCol1 == nCol2 )
1444 { // linke und rechte Spalte
1445 const USHORT n = 4 | 16;
1446 nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n );
1447 // nicht (4 und 16) oder 1 oder 32
1448 if ( nEdges && (((nEdges & n) != n) || (nEdges & 33)) )
1449 return TRUE; // linke oder rechte Kante fehlt oder offen
1451 else
1452 { // linke Spalte
1453 nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, 4 );
1454 // nicht 4 oder 1 oder 32
1455 if ( nEdges && (((nEdges & 4) != 4) || (nEdges & 33)) )
1456 return TRUE; // linke Kante fehlt oder offen
1457 // rechte Spalte
1458 nEdges = aCol[nCol2].GetBlockMatrixEdges( nRow1, nRow2, 16 );
1459 // nicht 16 oder 1 oder 32
1460 if ( nEdges && (((nEdges & 16) != 16) || (nEdges & 33)) )
1461 return TRUE; // rechte Kante fehlt oder offen
1464 if ( nRow1 == nRow2 )
1465 { // obere und untere Zeile
1466 BOOL bOpen = FALSE;
1467 const USHORT n = 2 | 8;
1468 for ( SCCOL i=nCol1; i<=nCol2; i++)
1470 nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n );
1471 if ( nEdges )
1473 if ( (nEdges & n) != n )
1474 return TRUE; // obere oder untere Kante fehlt
1475 if ( nEdges & 4 )
1476 bOpen = TRUE; // linke Kante oeffnet, weitersehen
1477 else if ( !bOpen )
1478 return TRUE; // es gibt was, was nicht geoeffnet wurde
1479 if ( nEdges & 16 )
1480 bOpen = FALSE; // rechte Kante schliesst
1483 if ( bOpen )
1484 return TRUE; // es geht noch weiter
1486 else
1488 USHORT j, n;
1489 SCROW nR;
1490 // erst obere Zeile, dann untere Zeile
1491 for ( j=0, nR=nRow1, n=8; j<2; j++, nR=nRow2, n=2 )
1493 BOOL bOpen = FALSE;
1494 for ( SCCOL i=nCol1; i<=nCol2; i++)
1496 nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n );
1497 if ( nEdges )
1499 // in oberere Zeile keine obere Kante bzw.
1500 // in unterer Zeile keine untere Kante
1501 if ( (nEdges & n) != n )
1502 return TRUE;
1503 if ( nEdges & 4 )
1504 bOpen = TRUE; // linke Kante oeffnet, weitersehen
1505 else if ( !bOpen )
1506 return TRUE; // es gibt was, was nicht geoeffnet wurde
1507 if ( nEdges & 16 )
1508 bOpen = FALSE; // rechte Kante schliesst
1511 if ( bOpen )
1512 return TRUE; // es geht noch weiter
1515 return FALSE;
1519 BOOL ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
1521 BOOL bFound=FALSE;
1522 for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
1523 bFound |= aCol[i].HasSelectionMatrixFragment(rMark);
1524 return bFound;
1528 BOOL ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
1529 SCROW nRow2, BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
1531 if ( !ValidColRow( nCol2, nRow2 ) )
1533 DBG_ERRORFILE("IsBlockEditable: invalid column or row");
1534 if (pOnlyNotBecauseOfMatrix)
1535 *pOnlyNotBecauseOfMatrix = FALSE;
1536 return FALSE;
1539 BOOL bIsEditable = TRUE;
1540 if ( nLockCount )
1541 bIsEditable = FALSE;
1542 else if ( IsProtected() && !pDocument->IsScenario(nTab) )
1544 if((bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED )) != FALSE)
1546 // If Sheet is protected and cells are not protected then
1547 // check the active scenario protect flag if this range is
1548 // on the active scenario range. Note the 'copy back' must also
1549 // be set to apply protection.
1550 USHORT nScenTab = nTab+1;
1551 while(pDocument->IsScenario(nScenTab))
1553 ScRange aEditRange(nCol1, nRow1, nScenTab, nCol2, nRow2, nScenTab);
1554 if(pDocument->IsActiveScenario(nScenTab) && pDocument->HasScenarioRange(nScenTab, aEditRange))
1556 USHORT nFlags;
1557 pDocument->GetScenarioFlags(nScenTab,nFlags);
1558 bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
1559 break;
1561 nScenTab++;
1565 else if (pDocument->IsScenario(nTab))
1567 // Determine if the preceding sheet is protected
1568 SCTAB nActualTab = nTab;
1571 nActualTab--;
1573 while(pDocument->IsScenario(nActualTab));
1575 if(pDocument->IsTabProtected(nActualTab))
1577 ScRange aEditRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
1578 if(pDocument->HasScenarioRange(nTab, aEditRange))
1580 USHORT nFlags;
1581 pDocument->GetScenarioFlags(nTab,nFlags);
1582 bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
1586 if ( bIsEditable )
1588 if ( HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2 ) )
1590 bIsEditable = FALSE;
1591 if ( pOnlyNotBecauseOfMatrix )
1592 *pOnlyNotBecauseOfMatrix = TRUE;
1594 else if ( pOnlyNotBecauseOfMatrix )
1595 *pOnlyNotBecauseOfMatrix = FALSE;
1597 else if ( pOnlyNotBecauseOfMatrix )
1598 *pOnlyNotBecauseOfMatrix = FALSE;
1599 return bIsEditable;
1603 BOOL ScTable::IsSelectionEditable( const ScMarkData& rMark,
1604 BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
1606 BOOL bIsEditable = TRUE;
1607 if ( nLockCount )
1608 bIsEditable = FALSE;
1609 else if ( IsProtected() && !pDocument->IsScenario(nTab) )
1611 if((bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED )) != FALSE)
1613 // If Sheet is protected and cells are not protected then
1614 // check the active scenario protect flag if this area is
1615 // in the active scenario range.
1616 ScRangeList aRanges;
1617 rMark.FillRangeListWithMarks( &aRanges, FALSE );
1618 ULONG nRangeCount = aRanges.Count();
1619 SCTAB nScenTab = nTab+1;
1620 while(pDocument->IsScenario(nScenTab) && bIsEditable)
1622 if(pDocument->IsActiveScenario(nScenTab))
1624 for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
1626 ScRange aRange = *aRanges.GetObject(i);
1627 if(pDocument->HasScenarioRange(nScenTab, aRange))
1629 USHORT nFlags;
1630 pDocument->GetScenarioFlags(nScenTab,nFlags);
1631 bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
1635 nScenTab++;
1639 else if (pDocument->IsScenario(nTab))
1641 // Determine if the preceding sheet is protected
1642 SCTAB nActualTab = nTab;
1645 nActualTab--;
1647 while(pDocument->IsScenario(nActualTab));
1649 if(pDocument->IsTabProtected(nActualTab))
1651 ScRangeList aRanges;
1652 rMark.FillRangeListWithMarks( &aRanges, FALSE );
1653 ULONG nRangeCount = aRanges.Count();
1654 for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
1656 ScRange aRange = *aRanges.GetObject(i);
1657 if(pDocument->HasScenarioRange(nTab, aRange))
1659 USHORT nFlags;
1660 pDocument->GetScenarioFlags(nTab,nFlags);
1661 bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
1666 if ( bIsEditable )
1668 if ( HasSelectionMatrixFragment( rMark ) )
1670 bIsEditable = FALSE;
1671 if ( pOnlyNotBecauseOfMatrix )
1672 *pOnlyNotBecauseOfMatrix = TRUE;
1674 else if ( pOnlyNotBecauseOfMatrix )
1675 *pOnlyNotBecauseOfMatrix = FALSE;
1677 else if ( pOnlyNotBecauseOfMatrix )
1678 *pOnlyNotBecauseOfMatrix = FALSE;
1679 return bIsEditable;
1684 void ScTable::LockTable()
1686 ++nLockCount;
1690 void ScTable::UnlockTable()
1692 if (nLockCount)
1693 --nLockCount;
1694 else
1696 DBG_ERROR("UnlockTable ohne LockTable");
1701 void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, BOOL bDeep ) const
1703 for (SCCOL i=0; i<=MAXCOL; i++)
1704 aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
1708 void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1,
1709 SCCOL nCol2, SCROW nRow2, BOOL bDeep ) const
1711 for (SCCOL i=nCol1; i<=nCol2; i++)
1712 aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
1716 void ScTable::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
1717 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
1719 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1721 PutInOrder(nStartCol, nEndCol);
1722 PutInOrder(nStartRow, nEndRow);
1723 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1724 aCol[i].MergeBlockFrame( pLineOuter, pLineInner, rFlags,
1725 nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
1730 void ScTable::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
1731 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
1733 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1735 PutInOrder(nStartCol, nEndCol);
1736 PutInOrder(nStartRow, nEndRow);
1737 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1738 aCol[i].ApplyBlockFrame( pLineOuter, pLineInner,
1739 nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
1744 void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
1746 if (ValidColRow(nCol,nRow))
1747 aCol[nCol].ApplyPattern( nRow, rAttr );
1751 void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1752 const ScPatternAttr& rAttr, ScEditDataArray* pDataArray )
1754 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1756 PutInOrder(nStartCol, nEndCol);
1757 PutInOrder(nStartRow, nEndRow);
1758 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1759 aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray);
1763 void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
1764 const ScPatternAttr& rPattern, short nNewType )
1766 SCCOL nEndCol = rRange.aEnd.Col();
1767 for ( SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; nCol++ )
1769 aCol[nCol].ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
1775 void ScTable::ApplyStyle( SCCOL nCol, SCROW nRow, const ScStyleSheet& rStyle )
1777 if (ValidColRow(nCol,nRow))
1778 aCol[nCol].ApplyStyle( nRow, rStyle );
1782 void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
1784 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1786 PutInOrder(nStartCol, nEndCol);
1787 PutInOrder(nStartRow, nEndRow);
1788 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1789 aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
1794 void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
1796 for (SCCOL i=0; i<=MAXCOL; i++)
1797 aCol[i].ApplySelectionStyle( rStyle, rMark );
1801 void ScTable::ApplySelectionLineStyle( const ScMarkData& rMark,
1802 const SvxBorderLine* pLine, BOOL bColorOnly )
1804 if ( bColorOnly && !pLine )
1805 return;
1807 for (SCCOL i=0; i<=MAXCOL; i++)
1808 aCol[i].ApplySelectionLineStyle( rMark, pLine, bColorOnly );
1812 const ScStyleSheet* ScTable::GetStyle( SCCOL nCol, SCROW nRow ) const
1814 if (ValidColRow(nCol, nRow))
1815 return aCol[nCol].GetStyle(nRow);
1816 else
1817 return NULL;
1821 const ScStyleSheet* ScTable::GetSelectionStyle( const ScMarkData& rMark, BOOL& rFound ) const
1823 rFound = FALSE;
1825 BOOL bEqual = TRUE;
1826 BOOL bColFound;
1828 const ScStyleSheet* pStyle = NULL;
1829 const ScStyleSheet* pNewStyle;
1831 for (SCCOL i=0; i<=MAXCOL && bEqual; i++)
1832 if (rMark.HasMultiMarks(i))
1834 pNewStyle = aCol[i].GetSelectionStyle( rMark, bColFound );
1835 if (bColFound)
1837 rFound = TRUE;
1838 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
1839 bEqual = FALSE; // unterschiedliche
1840 pStyle = pNewStyle;
1844 return bEqual ? pStyle : NULL;
1848 const ScStyleSheet* ScTable::GetAreaStyle( BOOL& rFound, SCCOL nCol1, SCROW nRow1,
1849 SCCOL nCol2, SCROW nRow2 ) const
1851 rFound = FALSE;
1853 BOOL bEqual = TRUE;
1854 BOOL bColFound;
1856 const ScStyleSheet* pStyle = NULL;
1857 const ScStyleSheet* pNewStyle;
1859 for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
1861 pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
1862 if (bColFound)
1864 rFound = TRUE;
1865 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
1866 bEqual = FALSE; // unterschiedliche
1867 pStyle = pNewStyle;
1871 return bEqual ? pStyle : NULL;
1875 BOOL ScTable::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const
1877 BOOL bIsUsed = FALSE;
1879 for ( SCCOL i=0; i<=MAXCOL; i++ )
1881 if ( aCol[i].IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
1883 if ( !bGatherAllStyles )
1884 return TRUE;
1885 bIsUsed = TRUE;
1889 return bIsUsed;
1893 void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRemoved,
1894 OutputDevice* pDev,
1895 double nPPTX, double nPPTY,
1896 const Fraction& rZoomX, const Fraction& rZoomY )
1898 ScFlatBoolRowSegments aUsedRows;
1899 for (SCCOL i = 0; i <= MAXCOL; ++i)
1900 aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
1902 SCROW nRow = 0;
1903 while (nRow <= MAXROW)
1905 ScFlatBoolRowSegments::RangeData aData;
1906 if (!aUsedRows.getRangeData(nRow, aData))
1907 // search failed!
1908 return;
1910 SCROW nEndRow = aData.mnRow2;
1911 if (aData.mbValue)
1912 SetOptimalHeight(nRow, nEndRow, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE);
1914 nRow = nEndRow + 1;
1919 BOOL ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1920 INT16 nFlags )
1922 BOOL bChanged = FALSE;
1923 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1924 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1925 bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags);
1926 return bChanged;
1930 BOOL ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1931 INT16 nFlags )
1933 BOOL bChanged = FALSE;
1934 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1935 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1936 bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
1937 return bChanged;
1941 void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr, BOOL bPutToPool )
1943 if (ValidColRow(nCol,nRow))
1944 aCol[nCol].SetPattern( nRow, rAttr, bPutToPool );
1948 void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
1950 if (ValidColRow(nCol,nRow))
1951 aCol[nCol].ApplyAttr( nRow, rAttr );
1955 void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark,
1956 ScEditDataArray* pDataArray )
1958 for (SCCOL i=0; i<=MAXCOL; i++)
1959 aCol[i].ApplySelectionCache( pCache, rMark, pDataArray );
1963 void ScTable::ChangeSelectionIndent( BOOL bIncrement, const ScMarkData& rMark )
1965 for (SCCOL i=0; i<=MAXCOL; i++)
1966 aCol[i].ChangeSelectionIndent( bIncrement, rMark );
1970 void ScTable::ClearSelectionItems( const USHORT* pWhich, const ScMarkData& rMark )
1972 for (SCCOL i=0; i<=MAXCOL; i++)
1973 aCol[i].ClearSelectionItems( pWhich, rMark );
1977 // Spaltenbreiten / Zeilenhoehen
1979 void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
1981 if (VALIDCOL(nCol) && pColWidth)
1983 if (!nNewWidth)
1985 // DBG_ERROR("Spaltenbreite 0 in SetColWidth");
1986 nNewWidth = STD_COL_WIDTH;
1989 if ( nNewWidth != pColWidth[nCol] )
1991 nRecalcLvl++;
1992 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1993 if (pDrawLayer)
1994 pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
1995 pColWidth[nCol] = nNewWidth;
1996 if( !--nRecalcLvl )
1997 SetDrawPageSize();
1999 InvalidatePageBreaks();
2002 else
2004 DBG_ERROR("Falsche Spaltennummer oder keine Breiten");
2009 void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
2011 if (VALIDROW(nRow) && pRowHeight)
2013 if (!nNewHeight)
2015 DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
2016 nNewHeight = ScGlobal::nStdRowHeight;
2019 USHORT nOldHeight = pRowHeight->GetValue(nRow);
2020 if ( nNewHeight != nOldHeight )
2022 nRecalcLvl++;
2023 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2024 if (pDrawLayer)
2025 pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
2026 pRowHeight->SetValue( nRow, nNewHeight);
2027 if( !--nRecalcLvl )
2028 SetDrawPageSize();
2030 InvalidatePageBreaks();
2033 else
2035 DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
2040 BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight,
2041 double /* nPPTX */, double nPPTY )
2043 BOOL bChanged = FALSE;
2044 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
2046 nRecalcLvl++;
2047 if (!nNewHeight)
2049 DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
2050 nNewHeight = ScGlobal::nStdRowHeight;
2053 long nNewPix = (long) ( nNewHeight * nPPTY );
2055 BOOL bSingle = FALSE;
2056 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2057 if (pDrawLayer)
2058 if (pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ))
2059 bSingle = TRUE;
2061 if (bSingle)
2063 size_t nIndex;
2064 SCROW nRegionEndRow;
2065 USHORT nOldHeight = pRowHeight->GetValue( nStartRow, nIndex, nRegionEndRow);
2066 if (nNewHeight == nOldHeight && nEndRow <= nRegionEndRow)
2067 bSingle = FALSE; // no difference in this range
2069 if (bSingle)
2071 if (nEndRow-nStartRow < 20)
2073 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
2075 if (!bChanged)
2076 if (pRowHeight->GetValue( nRow ))
2077 bChanged = (nNewPix != (long) (pRowHeight->GetValue( nRow ) * nPPTY));
2078 SetRowHeight( nRow, nNewHeight );
2081 else
2083 SCROW nMid = (nStartRow+nEndRow) / 2;
2084 if (SetRowHeightRange( nStartRow, nMid, nNewHeight, 1.0, 1.0 ))
2085 bChanged = TRUE;
2086 if (SetRowHeightRange( nMid+1, nEndRow, nNewHeight, 1.0, 1.0 ))
2087 bChanged = TRUE;
2090 else
2092 if (pDrawLayer)
2094 unsigned long nOldHeights = pRowHeight->SumValues( nStartRow, nEndRow);
2095 // FIXME: should we test for overflows?
2096 long nHeightDif = (long) (unsigned long) nNewHeight *
2097 (nEndRow - nStartRow + 1) - nOldHeights;
2098 pDrawLayer->HeightChanged( nTab, nEndRow, nHeightDif );
2100 // Whether new pixel size will differ from old pixel size in any row.
2101 ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight,
2102 nStartRow, nEndRow);
2105 if (*aIter != nNewHeight)
2106 bChanged = (nNewPix != (long) (*aIter * nPPTY));
2107 } while (!bChanged && aIter.NextRange());
2108 pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
2110 if( !--nRecalcLvl )
2111 SetDrawPageSize();
2113 if (bChanged)
2114 InvalidatePageBreaks();
2116 else
2118 DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
2121 return bChanged;
2125 void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
2127 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
2129 if (bManual)
2130 pRowFlags->OrValue( nStartRow, nEndRow, CR_MANUALSIZE);
2131 else
2132 pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
2134 else
2136 DBG_ERROR("Falsche Zeilennummer oder keine Zeilenflags");
2141 USHORT ScTable::GetColWidth( SCCOL nCol )
2143 DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
2145 if (VALIDCOL(nCol) && pColFlags && pColWidth)
2147 if (ColHidden(nCol))
2148 return 0;
2149 else
2150 return pColWidth[nCol];
2152 else
2153 return (USHORT) STD_COL_WIDTH;
2157 USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingestellte
2159 DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
2161 if (VALIDCOL(nCol) && pColWidth)
2162 return pColWidth[nCol];
2163 else
2164 return (USHORT) STD_COL_WIDTH;
2168 USHORT ScTable::GetCommonWidth( SCCOL nEndCol )
2170 // get the width that is used in the largest continuous column range (up to nEndCol)
2172 if ( !ValidCol(nEndCol) )
2174 DBG_ERROR("wrong column");
2175 nEndCol = MAXCOL;
2178 USHORT nMaxWidth = 0;
2179 USHORT nMaxCount = 0;
2180 SCCOL nRangeStart = 0;
2181 while ( nRangeStart <= nEndCol )
2183 // skip hidden columns
2184 while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) )
2185 ++nRangeStart;
2186 if ( nRangeStart <= nEndCol )
2188 USHORT nThisCount = 0;
2189 USHORT nThisWidth = pColWidth[nRangeStart];
2190 SCCOL nRangeEnd = nRangeStart;
2191 while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth )
2193 ++nThisCount;
2194 ++nRangeEnd;
2196 // skip hidden columns
2197 while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) )
2198 ++nRangeEnd;
2201 if ( nThisCount > nMaxCount )
2203 nMaxCount = nThisCount;
2204 nMaxWidth = nThisWidth;
2207 nRangeStart = nRangeEnd; // next range
2211 return nMaxWidth;
2215 USHORT ScTable::GetRowHeight( SCROW nRow )
2217 DBG_ASSERT(VALIDROW(nRow),"Falsche Zeilennummer");
2219 if (VALIDROW(nRow) && pRowHeight)
2221 if (RowHidden(nRow))
2222 return 0;
2223 else
2224 return pRowHeight->GetValue(nRow);
2226 else
2227 return (USHORT) ScGlobal::nStdRowHeight;
2231 ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow )
2233 DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
2235 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
2237 ULONG nHeight = 0;
2238 SCROW nRow = nStartRow;
2239 while (nRow <= nEndRow)
2241 SCROW nLastRow = -1;
2242 if (!RowHidden(nRow, nLastRow))
2244 if (nLastRow > nEndRow)
2245 nLastRow = nEndRow;
2246 nHeight += pRowFlags->SumCoupledArrayForCondition(nRow, nLastRow, 0, 0, *pRowHeight);
2248 nRow = nLastRow + 1;
2250 return nHeight;
2252 else
2253 return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight);
2257 ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale )
2259 DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
2261 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
2263 ULONG nHeight = 0;
2264 SCROW nRow = nStartRow;
2265 while (nRow <= nEndRow)
2267 SCROW nLastRow = -1;
2268 if (!RowHidden(nRow, nLastRow))
2270 if (nLastRow > nEndRow)
2271 nLastRow = nEndRow;
2272 nHeight += pRowFlags->SumScaledCoupledArrayForCondition(
2273 nRow, nLastRow, 0, 0, *pRowHeight, fScale);
2275 nRow = nLastRow + 1;
2277 return nHeight;
2279 else
2280 return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
2284 USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hidden
2286 DBG_ASSERT(VALIDROW(nRow),"wrong row number");
2288 if (VALIDROW(nRow) && pRowHeight)
2289 return pRowHeight->GetValue(nRow);
2290 else
2291 return (USHORT) ScGlobal::nStdRowHeight;
2295 // Spalten-/Zeilen-Flags
2298 SCROW ScTable::GetHiddenRowCount( SCROW nRow )
2300 if (!ValidRow(nRow))
2301 return 0;
2303 SCROW nLastRow = -1;
2304 if (!RowHidden(nRow, nLastRow) || !ValidRow(nLastRow))
2305 return 0;
2307 return nLastRow - nRow + 1;
2311 //! ShowRows / DBShowRows zusammenfassen
2313 void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
2315 if (VALIDCOL(nCol))
2317 bool bWasVis = !ColHidden(nCol);
2318 if (bWasVis != bShow)
2320 nRecalcLvl++;
2321 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2322 if (pDrawLayer)
2324 if (bShow)
2325 pDrawLayer->WidthChanged( nTab, nCol, (long) pColWidth[nCol] );
2326 else
2327 pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] );
2330 SetColHidden(nCol, nCol, !bShow);
2332 if( !--nRecalcLvl )
2333 SetDrawPageSize();
2335 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2336 if ( pCharts )
2337 pCharts->SetRangeDirty(ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ));
2340 else
2342 DBG_ERROR("Falsche Spaltennummer oder keine Flags");
2347 void ScTable::ShowRow(SCROW nRow, BOOL bShow)
2349 if (VALIDROW(nRow) && pRowFlags)
2351 bool bWasVis = !RowHidden(nRow);
2352 if (bWasVis != bShow)
2354 nRecalcLvl++;
2355 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2356 if (pDrawLayer)
2358 if (bShow)
2359 pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
2360 else
2361 pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
2364 SetRowHidden(nRow, nRow, !bShow);
2365 if (bShow)
2366 SetRowFiltered(nRow, nRow, false);
2368 if( !--nRecalcLvl )
2369 SetDrawPageSize();
2371 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2372 if ( pCharts )
2373 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
2375 InvalidatePageBreaks();
2378 else
2380 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2385 void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
2387 if (VALIDROW(nRow) && pRowFlags)
2389 bool bWasVis = !RowHidden(nRow);
2390 nRecalcLvl++;
2391 if (bWasVis != bShow)
2393 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2394 if (pDrawLayer)
2396 if (bShow)
2397 pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
2398 else
2399 pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
2403 // Filter-Flag immer setzen, auch wenn Hidden unveraendert
2405 SetRowHidden(nRow, nRow, !bShow);
2406 SetRowFiltered(nRow, nRow, !bShow);
2408 if( !--nRecalcLvl )
2409 SetDrawPageSize();
2411 if (bWasVis != bShow)
2413 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2414 if ( pCharts )
2415 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
2417 if (pOutlineTable)
2418 UpdateOutlineRow( nRow, nRow, bShow );
2420 InvalidatePageBreaks();
2423 else
2425 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2430 void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
2432 SCROW nStartRow = nRow1;
2433 nRecalcLvl++;
2434 while (nStartRow <= nRow2)
2436 SCROW nEndRow = -1;
2437 bool bWasVis = !RowHidden(nStartRow, nEndRow);
2438 if (nEndRow > nRow2)
2439 nEndRow = nRow2;
2441 BOOL bChanged = ( bWasVis != bShow );
2442 if ( bChanged )
2444 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2445 if (pDrawLayer)
2447 long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
2448 if (bShow)
2449 pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
2450 else
2451 pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
2455 SetRowHidden(nStartRow, nEndRow, !bShow);
2456 SetRowFiltered(nStartRow, nEndRow, !bShow);
2458 if ( bChanged )
2460 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2461 if ( pCharts )
2462 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
2465 nStartRow = nEndRow + 1;
2468 // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
2469 // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
2470 // to be done here.
2471 if (pOutlineTable)
2472 UpdateOutlineRow( nRow1, nRow2, bShow );
2474 if( !--nRecalcLvl )
2475 SetDrawPageSize();
2479 void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
2481 SCROW nStartRow = nRow1;
2482 nRecalcLvl++;
2483 while (nStartRow <= nRow2)
2485 SCROW nEndRow = -1;
2486 bool bWasVis = !RowHidden(nStartRow, nEndRow);
2487 if (nEndRow > nRow2)
2488 nEndRow = nRow2;
2490 BOOL bChanged = ( bWasVis != bShow );
2491 if ( bChanged )
2493 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2494 if (pDrawLayer)
2496 long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
2497 if (bShow)
2498 pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
2499 else
2500 pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
2504 SetRowHidden(nStartRow, nEndRow, !bShow);
2505 if (bShow)
2506 SetRowFiltered(nStartRow, nEndRow, false);
2508 if ( bChanged )
2510 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2511 if ( pCharts )
2512 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
2514 InvalidatePageBreaks();
2517 nStartRow = nEndRow + 1;
2519 if( !--nRecalcLvl )
2520 SetDrawPageSize();
2524 void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags )
2526 if (VALIDCOL(nCol) && pColFlags)
2527 pColFlags[nCol] = nNewFlags;
2528 else
2530 DBG_ERROR("Falsche Spaltennummer oder keine Flags");
2535 void ScTable::SetRowFlags( SCROW nRow, BYTE nNewFlags )
2537 if (VALIDROW(nRow) && pRowFlags)
2538 pRowFlags->SetValue( nRow, nNewFlags);
2539 else
2541 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2546 void ScTable::SetRowFlags( SCROW nStartRow, SCROW nEndRow, BYTE nNewFlags )
2548 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
2549 pRowFlags->SetValue( nStartRow, nEndRow, nNewFlags);
2550 else
2552 DBG_ERROR("Falsche Zeilennummer(n) oder keine Flags");
2557 BYTE ScTable::GetColFlags( SCCOL nCol ) const
2559 if (VALIDCOL(nCol) && pColFlags)
2560 return pColFlags[nCol];
2561 else
2562 return 0;
2566 BYTE ScTable::GetRowFlags( SCROW nRow ) const
2568 if (VALIDROW(nRow) && pRowFlags)
2569 return pRowFlags->GetValue(nRow);
2570 else
2571 return 0;
2575 SCROW ScTable::GetLastFlaggedRow() const
2577 if ( !pRowFlags )
2578 return 0;
2580 SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
2581 return ValidRow(nLastFound) ? nLastFound : 0;
2585 SCCOL ScTable::GetLastChangedCol() const
2587 if ( !pColFlags )
2588 return 0;
2590 SCCOL nLastFound = 0;
2591 for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
2592 if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH))
2593 nLastFound = nCol;
2595 return nLastFound;
2599 SCROW ScTable::GetLastChangedRow() const
2601 if ( !pRowFlags )
2602 return 0;
2604 SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
2605 if (!ValidRow(nLastFlags))
2606 nLastFlags = 0;
2608 SCROW nLastHeight = pRowHeight->GetLastUnequalAccess( 0, ScGlobal::nStdRowHeight);
2609 if (!ValidRow(nLastHeight))
2610 nLastHeight = 0;
2612 return std::max( nLastFlags, nLastHeight);
2616 BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
2618 if (pOutlineTable && pColFlags)
2620 ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
2621 return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, *this, true );
2623 else
2624 return FALSE;
2628 BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
2630 if (pOutlineTable && pRowFlags)
2631 return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *this, false );
2632 else
2633 return FALSE;
2637 void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
2639 // Column-wise expansion
2641 while (rX1 > 0 && ColHidden(rX1-1))
2642 --rX1;
2644 while (rX2 < MAXCOL && ColHidden(rX2+1))
2645 ++rX2;
2647 // Row-wise expansion
2649 if (rY1 > 0)
2651 ScFlatBoolRowSegments::RangeData aData;
2652 if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
2654 SCROW nStartRow = aData.mnRow1;
2655 if (ValidRow(nStartRow))
2656 rY1 = nStartRow;
2659 if (rY2 < MAXROW)
2661 SCROW nEndRow = -1;
2662 if (RowHidden(rY2+1, nEndRow) && ValidRow(nEndRow))
2663 rY2 = nEndRow;
2668 void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
2670 while ( rX2>rX1 && ColHidden(rX2) )
2671 --rX2;
2672 while ( rX2>rX1 && ColHidden(rX1) )
2673 ++rX1;
2675 if (rY1 < rY2)
2677 ScFlatBoolRowSegments::RangeData aData;
2678 if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
2680 SCROW nStartRow = aData.mnRow1;
2681 if (ValidRow(nStartRow) && nStartRow >= rY1)
2682 rY2 = nStartRow;
2686 if (rY1 < rY2)
2688 SCROW nEndRow = -1;
2689 if (RowHidden(rY1, nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2)
2690 rY1 = nEndRow;
2695 // Auto-Outline
2697 template< typename T >
2698 short DiffSign( T a, T b )
2700 return (a<b) ? -1 :
2701 (a>b) ? 1 : 0;
2705 void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
2707 BOOL bSizeChanged = FALSE;
2708 BOOL bMissed = FALSE;
2710 SCCOL nCol;
2711 SCROW nRow;
2712 SCROW i;
2713 BOOL bFound;
2714 ScOutlineArray* pArray;
2715 ScBaseCell* pCell;
2716 ScRange aRef;
2717 /* ScPatternAttr aBoldPattern( pDocument->GetPool() ); //! spezielle Format-Vorlage
2718 aBoldPattern.GetItemSet().Put( SvxWeightItem( WEIGHT_BOLD ) );
2721 StartOutlineTable();
2723 // Zeilen
2725 SCROW nCount = nEndRow-nStartRow+1;
2726 BOOL* pUsed = new BOOL[nCount];
2727 for (i=0; i<nCount; i++)
2728 pUsed[i] = FALSE;
2729 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
2730 if (!aCol[nCol].IsEmptyData())
2731 aCol[nCol].FindUsed( nStartRow, nEndRow, pUsed );
2733 pArray = pOutlineTable->GetRowArray();
2734 for (nRow=nStartRow; nRow<=nEndRow; nRow++)
2735 if (pUsed[nRow-nStartRow])
2737 bFound = FALSE;
2738 for (nCol=nStartCol; nCol<=nEndCol && !bFound; nCol++)
2739 if (!aCol[nCol].IsEmptyData())
2741 pCell = aCol[nCol].GetCell( nRow );
2742 if (pCell)
2743 if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2744 if (((ScFormulaCell*)pCell)->HasOneReference( aRef ))
2745 if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
2746 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
2747 DiffSign( aRef.aStart.Row(), nRow ) ==
2748 DiffSign( aRef.aEnd.Row(), nRow ) )
2750 if (pArray->Insert( aRef.aStart.Row(), aRef.aEnd.Row(), bSizeChanged ))
2752 // ApplyPatternArea( nStartCol, nRow, nEndCol, nRow, aBoldPattern );
2753 bFound = TRUE;
2755 else
2756 bMissed = TRUE;
2761 delete[] pUsed;
2763 // Spalten
2765 pArray = pOutlineTable->GetColArray();
2766 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
2768 if (!aCol[nCol].IsEmptyData())
2770 bFound = FALSE;
2771 ScColumnIterator aIter( &aCol[nCol], nStartRow, nEndRow );
2772 while ( aIter.Next( nRow, pCell ) && !bFound )
2774 if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2775 if (((ScFormulaCell*)pCell)->HasOneReference( aRef ))
2776 if ( aRef.aStart.Row() == nRow && aRef.aEnd.Row() == nRow &&
2777 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
2778 DiffSign( aRef.aStart.Col(), nCol ) ==
2779 DiffSign( aRef.aEnd.Col(), nCol ) )
2781 if (pArray->Insert( aRef.aStart.Col(), aRef.aEnd.Col(), bSizeChanged ))
2783 // ApplyPatternArea( nCol, nStartRow, nCol, nEndRow, aBoldPattern );
2784 bFound = TRUE;
2786 else
2787 bMissed = TRUE;
2794 // CopyData - fuer Query in anderen Bereich
2796 void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2797 SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab )
2799 //! wenn fuer mehrere Zeilen benutzt, nach Spalten optimieren!
2801 ScAddress aSrc( nStartCol, nStartRow, nTab );
2802 ScAddress aDest( nDestCol, nDestRow, nDestTab );
2803 ScRange aRange( aSrc, aDest );
2804 BOOL bThisTab = ( nDestTab == nTab );
2805 SCROW nDestY = nDestRow;
2806 for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
2808 aSrc.SetRow( nRow );
2809 aDest.SetRow( nDestY );
2810 SCCOL nDestX = nDestCol;
2811 for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
2813 aSrc.SetCol( nCol );
2814 aDest.SetCol( nDestX );
2815 ScBaseCell* pCell = GetCell( nCol, nRow );
2816 if (pCell)
2818 pCell = pCell->CloneWithoutNote( *pDocument );
2819 if (pCell->GetCellType() == CELLTYPE_FORMULA)
2821 ((ScFormulaCell*)pCell)->UpdateReference( URM_COPY, aRange,
2822 ((SCsCOL) nDestCol) - ((SCsCOL) nStartCol),
2823 ((SCsROW) nDestRow) - ((SCsROW) nStartRow),
2824 ((SCsTAB) nDestTab) - ((SCsTAB) nTab) );
2825 ((ScFormulaCell*)pCell)->aPos = aDest;
2828 if (bThisTab)
2830 PutCell( nDestX, nDestY, pCell );
2831 SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ), TRUE );
2833 else
2835 pDocument->PutCell( aDest, pCell );
2836 pDocument->SetPattern( aDest, *GetPattern( nCol, nRow ), TRUE );
2839 ++nDestX;
2841 ++nDestY;
2846 BOOL ScTable::RefVisible(ScFormulaCell* pCell)
2848 ScRange aRef;
2850 if (pCell->HasOneReference(aRef))
2852 if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
2854 SCROW nEndRow;
2855 if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow))
2856 // row not filtered.
2857 nEndRow = ::std::numeric_limits<SCROW>::max();
2859 if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
2860 return TRUE; // at least partly visible
2861 return FALSE; // completely invisible
2865 return TRUE; // irgendwie anders
2869 void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, String& rStr)
2871 GetInputString(nCol, nRow, rStr);
2872 rStr.EraseTrailingChars();
2873 rStr.EraseLeadingChars();
2874 ScGlobal::pCharClass->toUpper(rStr);
2878 // Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
2880 void ScTable::SetDrawPageSize()
2882 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2883 if( pDrawLayer )
2885 long x = GetColOffset( MAXCOL + 1 );
2886 long y = GetRowOffset( MAXROW + 1 );
2887 x = (long) ((double) x * HMM_PER_TWIPS);
2888 y = (long) ((double) y * HMM_PER_TWIPS);
2890 if ( IsLayoutRTL() ) // IsNegativePage
2891 x = -x;
2893 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ) );
2898 ULONG ScTable::GetRowOffset( SCROW nRow )
2900 ULONG n = 0;
2901 if ( pRowFlags && pRowHeight )
2903 if (nRow == 0)
2904 return 0;
2905 else if (nRow == 1)
2906 return GetRowHeight(0);
2908 n = GetTotalRowHeight(0, nRow-1);
2909 #ifdef DBG_UTIL
2910 if (n == ::std::numeric_limits<unsigned long>::max())
2911 DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow");
2912 #endif
2914 else
2916 DBG_ERROR("GetRowOffset: Daten fehlen");
2918 return n;
2921 SCROW ScTable::GetRowForHeight(ULONG nHeight)
2923 sal_uInt32 nSum = 0;
2925 ScFlatBoolRowSegments::RangeData aData;
2926 for (SCROW nRow = 0; nRow <= MAXROW; ++nRow)
2928 if (!mpHiddenRows->getRangeData(nRow, aData))
2929 break;
2931 if (aData.mbValue)
2933 nRow = aData.mnRow2;
2934 continue;
2937 sal_uInt32 nNew = pRowHeight->GetValue(nRow);
2938 nSum += nNew;
2939 if (nSum > nHeight)
2941 return nRow < MAXROW ? nRow + 1 : MAXROW;
2944 return -1;
2948 ULONG ScTable::GetColOffset( SCCOL nCol )
2950 ULONG n = 0;
2951 if ( pColWidth )
2953 SCCOL i;
2954 for( i = 0; i < nCol; i++ )
2955 if (!ColHidden(i))
2956 n += pColWidth[i];
2958 else
2960 DBG_ERROR("GetColumnOffset: Daten fehlen");
2962 return n;