update dev300-m57
[ooovba.git] / sc / source / core / data / table2.cxx
blob4a2f5998cc2a39620d77b6a30314ed0be7303563
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 );
137 for (SCCOL j=nStartCol; j<=nEndCol; j++)
138 aCol[j].InsertRow( nStartRow, nSize );
139 if( !--nRecalcLvl )
140 SetDrawPageSize();
144 void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
145 BOOL* pUndoOutline )
147 nRecalcLvl++;
148 InitializeNoteCaptions();
149 if (nStartCol==0 && nEndCol==MAXCOL)
151 if (pRowHeight && pRowFlags)
153 pRowHeight->Remove( nStartRow, nSize);
154 pRowFlags->Remove( nStartRow, nSize);
156 if (pOutlineTable)
157 if (pOutlineTable->DeleteRow( nStartRow, nSize ))
158 if (pUndoOutline)
159 *pUndoOutline = TRUE;
162 { // scope for bulk broadcast
163 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
164 for (SCCOL j=nStartCol; j<=nEndCol; j++)
165 aCol[j].DeleteRow( nStartRow, nSize );
167 if( !--nRecalcLvl )
168 SetDrawPageSize();
172 BOOL ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
174 BOOL bTest = TRUE;
176 if ( nStartRow==0 && nEndRow==MAXROW && pOutlineTable )
177 bTest = pOutlineTable->TestInsertCol(nSize);
179 if ( nSize > static_cast<SCSIZE>(MAXCOL) )
180 bTest = FALSE;
182 for (SCCOL i=MAXCOL; (i+static_cast<SCCOL>(nSize)>MAXCOL) && bTest; i--)
183 bTest = aCol[i].TestInsertCol(nStartRow, nEndRow);
185 return bTest;
189 void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
191 nRecalcLvl++;
192 InitializeNoteCaptions();
193 if (nStartRow==0 && nEndRow==MAXROW)
195 if (pColWidth && pColFlags)
197 memmove( &pColWidth[nStartCol+nSize], &pColWidth[nStartCol],
198 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
199 memmove( &pColFlags[nStartCol+nSize], &pColFlags[nStartCol],
200 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
202 if (pOutlineTable)
203 pOutlineTable->InsertCol( nStartCol, nSize );
207 if ((nStartRow == 0) && (nEndRow == MAXROW))
209 for (SCSIZE i=0; i < nSize; i++)
210 for (SCCOL nCol = MAXCOL; nCol > nStartCol; nCol--)
211 aCol[nCol].SwapCol(aCol[nCol-1]);
213 else
215 for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
216 aCol[MAXCOL - nSize - i].MoveTo(nStartRow, nEndRow, aCol[MAXCOL - i]);
219 if (nStartCol>0) // copy old attributes
221 USHORT nWhichArray[2];
222 nWhichArray[0] = ATTR_MERGE;
223 nWhichArray[1] = 0;
225 for (SCSIZE i=0; i<nSize; i++)
227 aCol[nStartCol-1].CopyToColumn( nStartRow, nEndRow, IDF_ATTRIB,
228 FALSE, aCol[nStartCol+i] );
229 aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
230 SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
231 aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray );
234 if( !--nRecalcLvl )
235 SetDrawPageSize();
239 void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize,
240 BOOL* pUndoOutline )
242 nRecalcLvl++;
243 InitializeNoteCaptions();
244 if (nStartRow==0 && nEndRow==MAXROW)
246 if (pColWidth && pColFlags)
248 memmove( &pColWidth[nStartCol], &pColWidth[nStartCol+nSize],
249 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
250 memmove( &pColFlags[nStartCol], &pColFlags[nStartCol+nSize],
251 (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
253 if (pOutlineTable)
254 if (pOutlineTable->DeleteCol( nStartCol, nSize ))
255 if (pUndoOutline)
256 *pUndoOutline = TRUE;
260 { // scope for bulk broadcast
261 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
262 for (SCSIZE i = 0; i < nSize; i++)
263 aCol[nStartCol + i].DeleteArea(nStartRow, nEndRow, IDF_ALL);
266 if ((nStartRow == 0) && (nEndRow == MAXROW))
268 for (SCSIZE i=0; i < nSize; i++)
269 for (SCCOL nCol = nStartCol; nCol < MAXCOL; nCol++)
270 aCol[nCol].SwapCol(aCol[nCol+1]);
272 else
274 for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
275 aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
277 if( !--nRecalcLvl )
278 SetDrawPageSize();
282 void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nDelFlag)
284 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
285 if (nRow2 > MAXROW) nRow2 = MAXROW;
286 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
288 // nRecalcLvl++;
290 { // scope for bulk broadcast
291 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
292 for (SCCOL i = nCol1; i <= nCol2; i++)
293 aCol[i].DeleteArea(nRow1, nRow2, nDelFlag);
297 // Zellschutz auf geschuetzter Tabelle nicht setzen
300 if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
302 ScPatternAttr aPattern(pDocument->GetPool());
303 aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
304 ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
307 /* if( !--nRecalcLvl )
308 SetDrawPageSize();
314 void ScTable::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
316 { // scope for bulk broadcast
317 ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
318 for (SCCOL i=0; i<=MAXCOL; i++)
319 aCol[i].DeleteSelection( nDelFlag, rMark );
323 // Zellschutz auf geschuetzter Tabelle nicht setzen
326 if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
328 ScDocumentPool* pPool = pDocument->GetPool();
329 SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
330 aSet.Put( ScProtectionAttr( FALSE ) );
331 SfxItemPoolCache aCache( pPool, &aSet );
332 ApplySelectionCache( &aCache, rMark );
337 // pTable = Clipboard
338 void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
339 ScTable* pTable, BOOL bKeepScenarioFlags, BOOL bCloneNoteCaptions)
341 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
343 // Inhalte kopieren
344 SCCOL i;
346 for ( i = nCol1; i <= nCol2; i++)
347 aCol[i].CopyToClip(nRow1, nRow2, pTable->aCol[i], bKeepScenarioFlags, bCloneNoteCaptions);
349 // copy widths/heights, and only "hidden", "filtered" and "manual" flags
350 // also for all preceding columns/rows, to have valid positions for drawing objects
352 if (pColFlags && pTable->pColFlags && pColWidth && pTable->pColWidth)
353 for (i=0; i<=nCol2; i++)
355 pTable->pColFlags[i] = pColFlags[i] & CR_HIDDEN;
356 pTable->pColWidth[i] = pColWidth[i];
359 if (pRowFlags && pTable->pRowFlags && pRowHeight && pTable->pRowHeight)
361 pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2,
362 (CR_HIDDEN | CR_FILTERED | CR_MANUALSIZE));
363 pTable->pRowHeight->CopyFrom( *pRowHeight, 0, nRow2);
367 // ggf. Formeln durch Werte ersetzen
369 if ( IsProtected() )
370 for (i = nCol1; i <= nCol2; i++)
371 pTable->aCol[i].RemoveProtected(nRow1, nRow2);
375 void ScTable::CopyToClip(const ScRangeList& rRanges, ScTable* pTable,
376 bool bKeepScenarioFlags, bool bCloneNoteCaptions)
378 ScRangeList aRanges(rRanges);
379 for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
381 CopyToClip(p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(),
382 pTable, bKeepScenarioFlags, bCloneNoteCaptions);
386 void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
387 SCsCOL nDx, SCsROW nDy, USHORT nInsFlag,
388 BOOL bAsLink, BOOL bSkipAttrForEmpty, ScTable* pTable)
390 SCCOL i;
392 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
393 if (nRow2 > MAXROW) nRow2 = MAXROW;
394 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
396 nRecalcLvl++;
397 for ( i = nCol1; i <= nCol2; i++)
398 aCol[i].CopyFromClip(nRow1, nRow2, nDy, nInsFlag, bAsLink, bSkipAttrForEmpty, pTable->aCol[i - nDx]);
400 if ((nInsFlag & IDF_ATTRIB) != 0)
402 if (nRow1==0 && nRow2==MAXROW && pColWidth && pTable->pColWidth)
403 for (i=nCol1; i<=nCol2; i++)
404 pColWidth[i] = pTable->pColWidth[i-nDx];
406 if (nCol1==0 && nCol2==MAXCOL && pRowHeight && pTable->pRowHeight &&
407 pRowFlags && pTable->pRowFlags)
409 pRowHeight->CopyFrom( *pTable->pRowHeight, nRow1, nRow2, -nDy);
410 // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
411 for (SCROW j=nRow1; j<=nRow2; j++)
413 if ( pTable->pRowFlags->GetValue(j-nDy) & CR_MANUALSIZE )
414 pRowFlags->OrValue( j, CR_MANUALSIZE);
415 else
416 pRowFlags->AndValue( j, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
421 // Zellschutz auf geschuetzter Tabelle nicht setzen
424 if ( IsProtected() && (nInsFlag & IDF_ATTRIB) )
426 ScPatternAttr aPattern(pDocument->GetPool());
427 aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
428 ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
431 if( !--nRecalcLvl )
432 SetDrawPageSize();
437 void ScTable::MixData( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
438 USHORT nFunction, BOOL bSkipEmpty, ScTable* pSrcTab )
440 for (SCCOL i=nCol1; i<=nCol2; i++)
441 aCol[i].MixData( nRow1, nRow2, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
445 // Markierung von diesem Dokument
446 void ScTable::MixMarked( const ScMarkData& rMark, USHORT nFunction,
447 BOOL bSkipEmpty, ScTable* pSrcTab )
449 for (SCCOL i=0; i<=MAXCOL; i++)
450 aCol[i].MixMarked( rMark, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
454 void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
455 ScTable* pTransClip, USHORT nFlags, BOOL bAsLink )
457 BOOL bWasCut = pDocument->IsCutMode();
459 ScDocument* pDestDoc = pTransClip->pDocument;
461 for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
463 SCROW nRow;
464 ScBaseCell* pCell;
466 if ( bAsLink && nFlags == IDF_ALL )
468 // #68989# with IDF_ALL, also create links (formulas) for empty cells
470 for ( nRow=nRow1; nRow<=nRow2; nRow++ )
472 // create simple formula, as in ScColumn::CreateRefCell
474 ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
475 ScSingleRefData aRef;
476 aRef.nCol = nCol;
477 aRef.nRow = nRow;
478 aRef.nTab = nTab;
479 aRef.InitFlags(); // -> all absolute
480 aRef.SetFlag3D(TRUE);
481 aRef.CalcRelFromAbs( aDestPos );
482 ScTokenArray aArr;
483 aArr.AddSingleReference( aRef );
485 ScBaseCell* pNew = new ScFormulaCell( pDestDoc, aDestPos, &aArr );
486 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
489 else
491 ScColumnIterator aIter( &aCol[nCol], nRow1, nRow2 );
492 while (aIter.Next( nRow, pCell ))
494 ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
495 ScBaseCell* pNew;
496 if ( bAsLink ) // Referenz erzeugen ?
498 pNew = aCol[nCol].CreateRefCell( pDestDoc, aDestPos, aIter.GetIndex(), nFlags );
500 else // kopieren
502 ScAddress aOwnPos( nCol, nRow, nTab );
503 if (pCell->GetCellType() == CELLTYPE_FORMULA)
505 pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
507 // Referenzen drehen
508 // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
510 if (!bWasCut)
511 ((ScFormulaCell*)pNew)->TransposeReference();
513 else
515 pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos );
518 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
522 // Attribute
524 SCROW nAttrRow1;
525 SCROW nAttrRow2;
526 const ScPatternAttr* pPattern;
527 ScAttrIterator* pAttrIter = aCol[nCol].CreateAttrIterator( nRow1, nRow2 );
528 while ( (pPattern = pAttrIter->Next( nAttrRow1, nAttrRow2 )) != 0 )
530 if ( !IsDefaultItem( pPattern ) )
532 const SfxItemSet& rSet = pPattern->GetItemSet();
533 if ( rSet.GetItemState( ATTR_MERGE, FALSE ) == SFX_ITEM_DEFAULT &&
534 rSet.GetItemState( ATTR_MERGE_FLAG, FALSE ) == SFX_ITEM_DEFAULT &&
535 rSet.GetItemState( ATTR_BORDER, FALSE ) == SFX_ITEM_DEFAULT )
537 // no borders or merge items involved - use pattern as-is
538 for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
539 pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern, TRUE );
541 else
543 // transpose borders and merge values, remove merge flags (refreshed after pasting)
544 ScPatternAttr aNewPattern( *pPattern );
545 SfxItemSet& rNewSet = aNewPattern.GetItemSet();
547 const SvxBoxItem& rOldBox = (const SvxBoxItem&)rSet.Get(ATTR_BORDER);
548 if ( rOldBox.GetTop() || rOldBox.GetBottom() || rOldBox.GetLeft() || rOldBox.GetRight() )
550 SvxBoxItem aNew( ATTR_BORDER );
551 aNew.SetLine( rOldBox.GetLine( BOX_LINE_TOP ), BOX_LINE_LEFT );
552 aNew.SetLine( rOldBox.GetLine( BOX_LINE_LEFT ), BOX_LINE_TOP );
553 aNew.SetLine( rOldBox.GetLine( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
554 aNew.SetLine( rOldBox.GetLine( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
555 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_TOP ), BOX_LINE_LEFT );
556 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_LEFT ), BOX_LINE_TOP );
557 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
558 aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
559 rNewSet.Put( aNew );
562 const ScMergeAttr& rOldMerge = (const ScMergeAttr&)rSet.Get(ATTR_MERGE);
563 if (rOldMerge.IsMerged())
564 rNewSet.Put( ScMergeAttr( Min(
565 static_cast<SCsCOL>(rOldMerge.GetRowMerge()),
566 static_cast<SCsCOL>(MAXCOL+1 - (nAttrRow2-nRow1))),
567 Min(
568 static_cast<SCsROW>(rOldMerge.GetColMerge()),
569 static_cast<SCsROW>(MAXROW+1 - (nCol-nCol1)))));
570 const ScMergeFlagAttr& rOldFlag = (const ScMergeFlagAttr&)rSet.Get(ATTR_MERGE_FLAG);
571 if (rOldFlag.IsOverlapped())
573 INT16 nNewFlags = rOldFlag.GetValue() & ~( SC_MF_HOR | SC_MF_VER );
574 if ( nNewFlags )
575 rNewSet.Put( ScMergeFlagAttr( nNewFlags ) );
576 else
577 rNewSet.ClearItem( ATTR_MERGE_FLAG );
580 for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
581 pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
582 static_cast<SCROW>(nCol-nCol1), aNewPattern, TRUE);
587 delete pAttrIter;
592 void ScTable::StartAllListeners()
594 for (SCCOL i=0; i<=MAXCOL; i++)
595 aCol[i].StartAllListeners();
599 void ScTable::StartNeededListeners()
601 for (SCCOL i=0; i<=MAXCOL; i++)
602 aCol[i].StartNeededListeners();
606 void ScTable::BroadcastInArea( SCCOL nCol1, SCROW nRow1,
607 SCCOL nCol2, SCROW nRow2 )
609 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
610 if (nRow2 > MAXROW) nRow2 = MAXROW;
611 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
612 for (SCCOL i = nCol1; i <= nCol2; i++)
613 aCol[i].BroadcastInArea( nRow1, nRow2 );
617 void ScTable::StartListeningInArea( SCCOL nCol1, SCROW nRow1,
618 SCCOL nCol2, SCROW nRow2 )
620 if (nCol2 > MAXCOL) nCol2 = MAXCOL;
621 if (nRow2 > MAXROW) nRow2 = MAXROW;
622 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
623 for (SCCOL i = nCol1; i <= nCol2; i++)
624 aCol[i].StartListeningInArea( nRow1, nRow2 );
628 void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
629 USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
630 const ScMarkData* pMarkData,
631 BOOL bAsLink, BOOL bColRowFlags)
633 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
635 if (nFlags)
636 for (SCCOL i = nCol1; i <= nCol2; i++)
637 aCol[i].CopyToColumn(nRow1, nRow2, nFlags, bMarked,
638 pDestTab->aCol[i], pMarkData, bAsLink);
640 if (bColRowFlags) // Spaltenbreiten/Zeilenhoehen/Flags
642 // Charts muessen beim Ein-/Ausblenden angepasst werden
643 ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection();
645 BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
646 BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight);
648 if (bWidth||bHeight)
650 pDestTab->IncRecalcLevel();
652 if (bWidth)
653 for (SCCOL i=nCol1; i<=nCol2; i++)
655 BOOL bChange = pCharts &&
656 ( pDestTab->pColFlags[i] & CR_HIDDEN ) != ( pColFlags[i] & CR_HIDDEN );
657 pDestTab->pColWidth[i] = pColWidth[i];
658 pDestTab->pColFlags[i] = pColFlags[i];
659 //! Aenderungen zusammenfassen?
660 if (bChange)
661 pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
664 if (bHeight)
666 pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
667 for (SCROW i=nRow1; i<=nRow2; i++)
669 // TODO: might need some performance improvement, block
670 // operations instead of single GetValue()/SetValue() calls.
671 BYTE nThisRowFlags = pRowFlags->GetValue(i);
672 BOOL bChange = pCharts &&
673 ( pDestTab->pRowFlags->GetValue(i) & CR_HIDDEN ) != ( nThisRowFlags & CR_HIDDEN );
674 pDestTab->pRowFlags->SetValue( i, nThisRowFlags );
675 //! Aenderungen zusammenfassen?
676 if (bChange)
677 pCharts->SetRangeDirty(ScRange( 0, i, nTab, MAXCOL, i, nTab ));
680 pDestTab->DecRecalcLevel();
682 pDestTab->SetOutlineTable( pOutlineTable ); // auch nur wenn bColRowFlags
688 void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
689 USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
690 const ScMarkData* pMarkData)
692 if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
694 BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
695 BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight);
697 if (bWidth||bHeight)
698 nRecalcLvl++;
700 for ( SCCOL i = 0; i <= MAXCOL; i++)
702 if ( i >= nCol1 && i <= nCol2 )
703 aCol[i].UndoToColumn(nRow1, nRow2, nFlags, bMarked, pDestTab->aCol[i],
704 pMarkData);
705 else
706 aCol[i].CopyToColumn(0, MAXROW, IDF_FORMULA, FALSE, pDestTab->aCol[i]);
709 if (bWidth||bHeight)
711 if (bWidth)
712 for (SCCOL i=nCol1; i<=nCol2; i++)
713 pDestTab->pColWidth[i] = pColWidth[i];
714 if (bHeight)
715 pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
716 if( !--nRecalcLvl )
717 SetDrawPageSize();
723 void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
725 for (SCCOL i=0; i<=MAXCOL; i++)
726 aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
729 void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
731 DBG_ASSERT( bScenario, "bScenario == FALSE" );
733 for (SCCOL i=0; i<=MAXCOL; i++)
734 aCol[i].CopyScenarioTo( pDestTab->aCol[i] );
737 void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
739 DBG_ASSERT( bScenario, "bScenario == FALSE" );
741 for (SCCOL i=0; i<=MAXCOL; i++)
742 aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
745 void ScTable::MarkScenarioIn( ScMarkData& rDestMark, USHORT nNeededBits ) const
747 DBG_ASSERT( bScenario, "bScenario == FALSE" );
749 if ( ( nScenarioFlags & nNeededBits ) != nNeededBits ) // alle Bits gesetzt?
750 return;
752 for (SCCOL i=0; i<=MAXCOL; i++)
753 aCol[i].MarkScenarioIn( rDestMark );
756 BOOL ScTable::HasScenarioRange( const ScRange& rRange ) const
758 DBG_ASSERT( bScenario, "bScenario == FALSE" );
760 // ScMarkData aMark;
761 // MarkScenarioIn( aMark, 0 ); //! Bits als Parameter von HasScenarioRange?
762 // return aMark.IsAllMarked( rRange );
764 ScRange aTabRange = rRange;
765 aTabRange.aStart.SetTab( nTab );
766 aTabRange.aEnd.SetTab( nTab );
768 const ScRangeList* pList = GetScenarioRanges();
769 // return ( pList && pList->Find( aTabRange ) );
771 if (pList)
773 ULONG nCount = pList->Count();
774 for ( ULONG j = 0; j < nCount; j++ )
776 ScRange* pR = pList->GetObject( j );
777 if ( pR->Intersects( aTabRange ) )
778 return TRUE;
782 return FALSE;
785 void ScTable::InvalidateScenarioRanges()
787 delete pScenarioRanges;
788 pScenarioRanges = NULL;
791 const ScRangeList* ScTable::GetScenarioRanges() const
793 DBG_ASSERT( bScenario, "bScenario == FALSE" );
795 if (!pScenarioRanges)
797 ((ScTable*)this)->pScenarioRanges = new ScRangeList;
798 ScMarkData aMark;
799 MarkScenarioIn( aMark, 0 ); // immer
800 aMark.FillRangeListWithMarks( pScenarioRanges, FALSE );
802 return pScenarioRanges;
805 BOOL ScTable::TestCopyScenarioTo( const ScTable* pDestTab ) const
807 DBG_ASSERT( bScenario, "bScenario == FALSE" );
809 if (!pDestTab->IsProtected())
810 return TRUE;
812 BOOL bOk = TRUE;
813 for (SCCOL i=0; i<=MAXCOL && bOk; i++)
814 bOk = aCol[i].TestCopyScenarioTo( pDestTab->aCol[i] );
815 return bOk;
818 void ScTable::PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell )
820 if (ValidColRow(nCol,nRow))
822 if (pCell)
823 aCol[nCol].Insert( nRow, pCell );
824 else
825 aCol[nCol].Delete( nRow );
830 void ScTable::PutCell( SCCOL nCol, SCROW nRow, ULONG nFormatIndex, ScBaseCell* pCell )
832 if (ValidColRow(nCol,nRow))
834 if (pCell)
835 aCol[nCol].Insert( nRow, nFormatIndex, pCell );
836 else
837 aCol[nCol].Delete( nRow );
842 void ScTable::PutCell( const ScAddress& rPos, ScBaseCell* pCell )
844 if (pCell)
845 aCol[rPos.Col()].Insert( rPos.Row(), pCell );
846 else
847 aCol[rPos.Col()].Delete( rPos.Row() );
851 //UNUSED2009-05 void ScTable::PutCell( const ScAddress& rPos, ULONG nFormatIndex, ScBaseCell* pCell )
852 //UNUSED2009-05 {
853 //UNUSED2009-05 if (pCell)
854 //UNUSED2009-05 aCol[rPos.Col()].Insert( rPos.Row(), nFormatIndex, pCell );
855 //UNUSED2009-05 else
856 //UNUSED2009-05 aCol[rPos.Col()].Delete( rPos.Row() );
857 //UNUSED2009-05 }
860 BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString,
861 SvNumberFormatter* pFormatter, bool bDetectNumberFormat )
863 if (ValidColRow(nCol,nRow))
864 return aCol[nCol].SetString(
865 nRow, nTabP, rString, pDocument->GetAddressConvention(), pFormatter, bDetectNumberFormat );
866 else
867 return FALSE;
871 void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
873 if (ValidColRow(nCol, nRow))
874 aCol[nCol].SetValue( nRow, rVal );
878 void ScTable::GetString( SCCOL nCol, SCROW nRow, String& rString )
880 if (ValidColRow(nCol,nRow))
881 aCol[nCol].GetString( nRow, rString );
882 else
883 rString.Erase();
887 void ScTable::GetInputString( SCCOL nCol, SCROW nRow, String& rString )
889 if (ValidColRow(nCol,nRow))
890 aCol[nCol].GetInputString( nRow, rString );
891 else
892 rString.Erase();
896 double ScTable::GetValue( SCCOL nCol, SCROW nRow )
898 if (ValidColRow( nCol, nRow ))
899 return aCol[nCol].GetValue( nRow );
900 return 0.0;
904 void ScTable::GetFormula( SCCOL nCol, SCROW nRow, String& rFormula,
905 BOOL bAsciiExport )
907 if (ValidColRow(nCol,nRow))
908 aCol[nCol].GetFormula( nRow, rFormula, bAsciiExport );
909 else
910 rFormula.Erase();
914 ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
916 return ValidColRow( nCol, nRow ) ? aCol[ nCol ].GetNote( nRow ) : 0;
920 void ScTable::TakeNote( SCCOL nCol, SCROW nRow, ScPostIt*& rpNote )
922 if( ValidColRow( nCol, nRow ) )
924 aCol[ nCol ].TakeNote( nRow, rpNote );
925 if( rpNote && rpNote->GetNoteData().mxInitData.get() )
927 if( !mxUninitNotes.get() )
928 mxUninitNotes.reset( new ScAddress2DVec );
929 mxUninitNotes->push_back( ScAddress2D( nCol, nRow ) );
932 else
933 DELETEZ( rpNote );
937 ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
939 return ValidColRow( nCol, nRow ) ? aCol[ nCol ].ReleaseNote( nRow ) : 0;
943 void ScTable::DeleteNote( SCCOL nCol, SCROW nRow )
945 if( ValidColRow( nCol, nRow ) )
946 aCol[ nCol ].DeleteNote( nRow );
950 void ScTable::InitializeNoteCaptions( bool bForced )
952 if( mxUninitNotes.get() && (bForced || pDocument->IsUndoEnabled()) )
954 for( ScAddress2DVec::iterator aIt = mxUninitNotes->begin(), aEnd = mxUninitNotes->end(); aIt != aEnd; ++aIt )
955 if( ScPostIt* pNote = GetNote( aIt->first, aIt->second ) )
956 pNote->GetOrCreateCaption( ScAddress( aIt->first, aIt->second, nTab ) );
957 mxUninitNotes.reset();
961 CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
963 if (ValidColRow( nCol, nRow ))
964 return aCol[nCol].GetCellType( nRow );
965 return CELLTYPE_NONE;
969 ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
971 if (ValidColRow( nCol, nRow ))
972 return aCol[nCol].GetCell( nRow );
974 DBG_ERROR("GetCell ausserhalb");
975 return NULL;
978 void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
980 rCol = 0;
981 rRow = 0;
982 while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
983 ++rCol;
984 rRow = aCol[rCol].GetFirstDataPos();
987 void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
989 rCol = MAXCOL;
990 rRow = 0;
991 while (aCol[rCol].IsEmptyData() && (rCol > 0))
992 rCol--;
993 SCCOL nCol = rCol;
994 while ((SCsCOL)nCol >= 0)
996 rRow = Max(rRow, aCol[nCol].GetLastDataPos());
997 nCol--;
1002 BOOL ScTable::HasData( SCCOL nCol, SCROW nRow )
1004 if (ValidColRow(nCol,nRow))
1005 return aCol[nCol].HasDataAt( nRow );
1006 else
1007 return FALSE;
1011 BOOL ScTable::HasStringData( SCCOL nCol, SCROW nRow )
1013 if (ValidColRow(nCol,nRow))
1014 return aCol[nCol].HasStringData( nRow );
1015 else
1016 return FALSE;
1020 BOOL ScTable::HasValueData( SCCOL nCol, SCROW nRow )
1022 if (ValidColRow(nCol,nRow))
1023 return aCol[nCol].HasValueData( nRow );
1024 else
1025 return FALSE;
1029 BOOL ScTable::HasStringCells( SCCOL nStartCol, SCROW nStartRow,
1030 SCCOL nEndCol, SCROW nEndRow ) const
1032 if ( ValidCol(nEndCol) )
1033 for ( SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++ )
1034 if (aCol[nCol].HasStringCells(nStartRow, nEndRow))
1035 return TRUE;
1037 return FALSE;
1041 //UNUSED2008-05 USHORT ScTable::GetErrCode( SCCOL nCol, SCROW nRow ) const
1042 //UNUSED2008-05 {
1043 //UNUSED2008-05 if (ValidColRow( nCol, nRow ))
1044 //UNUSED2008-05 return aCol[nCol].GetErrCode( nRow );
1045 //UNUSED2008-05 return 0;
1046 //UNUSED2008-05 }
1049 void ScTable::SetDirtyVar()
1051 for (SCCOL i=0; i<=MAXCOL; i++)
1052 aCol[i].SetDirtyVar();
1056 void ScTable::SetDirty()
1058 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1059 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1060 for (SCCOL i=0; i<=MAXCOL; i++)
1061 aCol[i].SetDirty();
1062 pDocument->SetAutoCalc( bOldAutoCalc );
1066 void ScTable::SetDirty( const ScRange& rRange )
1068 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1069 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1070 SCCOL nCol2 = rRange.aEnd.Col();
1071 for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1072 aCol[i].SetDirty( rRange );
1073 pDocument->SetAutoCalc( bOldAutoCalc );
1077 void ScTable::SetTableOpDirty( const ScRange& rRange )
1079 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1080 pDocument->SetAutoCalc( FALSE ); // no multiple recalculation
1081 SCCOL nCol2 = rRange.aEnd.Col();
1082 for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1083 aCol[i].SetTableOpDirty( rRange );
1084 pDocument->SetAutoCalc( bOldAutoCalc );
1088 void ScTable::SetDirtyAfterLoad()
1090 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1091 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1092 for (SCCOL i=0; i<=MAXCOL; i++)
1093 aCol[i].SetDirtyAfterLoad();
1094 pDocument->SetAutoCalc( bOldAutoCalc );
1098 void ScTable::SetRelNameDirty()
1100 BOOL bOldAutoCalc = pDocument->GetAutoCalc();
1101 pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
1102 for (SCCOL i=0; i<=MAXCOL; i++)
1103 aCol[i].SetRelNameDirty();
1104 pDocument->SetAutoCalc( bOldAutoCalc );
1108 void ScTable::CalcAll()
1110 for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll();
1114 void ScTable::CompileAll()
1116 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CompileAll();
1120 void ScTable::CompileXML( ScProgress& rProgress )
1122 for (SCCOL i=0; i <= MAXCOL; i++)
1124 aCol[i].CompileXML( rProgress );
1128 void ScTable::CalcAfterLoad()
1130 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CalcAfterLoad();
1134 bool ScTable::MarkUsedExternalReferences()
1136 bool bAllMarked = false;
1137 for (SCCOL i=0; i <= MAXCOL && !bAllMarked; ++i)
1139 bAllMarked = aCol[i].MarkUsedExternalReferences();
1141 return bAllMarked;
1145 void ScTable::ResetChanged( const ScRange& rRange )
1147 SCCOL nStartCol = rRange.aStart.Col();
1148 SCROW nStartRow = rRange.aStart.Row();
1149 SCCOL nEndCol = rRange.aEnd.Col();
1150 SCROW nEndRow = rRange.aEnd.Row();
1152 for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
1153 aCol[nCol].ResetChanged(nStartRow, nEndRow);
1156 // Attribute
1158 const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, USHORT nWhich ) const
1160 if (ValidColRow(nCol,nRow))
1161 return aCol[nCol].GetAttr( nRow, nWhich );
1162 else
1163 return NULL;
1167 ULONG ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
1169 if (ValidColRow(nCol,nRow))
1170 return aCol[nCol].GetNumberFormat( nRow );
1171 else
1172 return 0;
1175 sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1177 if (!ValidCol(nCol) || !ValidRow(nStartRow) || !ValidRow(nEndRow))
1178 return 0;
1180 return aCol[nCol].GetNumberFormat(nStartRow, nEndRow);
1184 const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
1186 if (ValidColRow(nCol,nRow))
1187 return aCol[nCol].GetPattern( nRow );
1188 else
1190 DBG_ERROR("wrong column or row");
1191 return pDocument->GetDefPattern(); // for safety
1196 const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1198 if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) )
1199 return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
1200 else
1201 return NULL;
1205 BOOL ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const
1207 BOOL bFound=FALSE;
1208 for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++)
1209 bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask );
1210 return bFound;
1214 //UNUSED2009-05 BOOL ScTable::HasLines( const ScRange& rRange, Rectangle& rSizes ) const
1215 //UNUSED2009-05 {
1216 //UNUSED2009-05 SCCOL nCol1 = rRange.aStart.Col();
1217 //UNUSED2009-05 SCROW nRow1 = rRange.aStart.Row();
1218 //UNUSED2009-05 SCCOL nCol2 = rRange.aEnd.Col();
1219 //UNUSED2009-05 SCROW nRow2 = rRange.aEnd.Row();
1220 //UNUSED2009-05 PutInOrder( nCol1, nCol2 );
1221 //UNUSED2009-05 PutInOrder( nRow1, nRow2 );
1222 //UNUSED2009-05
1223 //UNUSED2009-05 BOOL bFound = FALSE;
1224 //UNUSED2009-05 for (SCCOL i=nCol1; i<=nCol2; i++)
1225 //UNUSED2009-05 if (aCol[i].HasLines( nRow1, nRow2, rSizes, (i==nCol1), (i==nCol2) ))
1226 //UNUSED2009-05 bFound = TRUE;
1227 //UNUSED2009-05
1228 //UNUSED2009-05 return bFound;
1229 //UNUSED2009-05 }
1232 BOOL ScTable::HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const
1234 BOOL bFound=FALSE;
1235 for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
1236 bFound |= aCol[i].HasAttribSelection( rMark, nMask );
1237 return bFound;
1241 BOOL ScTable::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
1242 SCCOL& rEndCol, SCROW& rEndRow,
1243 BOOL bRefresh, BOOL bAttrs )
1245 if (!(ValidCol(nStartCol) && ValidCol(rEndCol)))
1247 DBG_ERRORFILE("ScTable::ExtendMerge: invalid column number");
1248 return FALSE;
1250 BOOL bFound=FALSE;
1251 SCCOL nOldEndX = rEndCol;
1252 SCROW nOldEndY = rEndRow;
1253 for (SCCOL i=nStartCol; i<=nOldEndX; i++)
1254 bFound |= aCol[i].ExtendMerge( i, nStartRow, nOldEndY, rEndCol, rEndRow, bRefresh, bAttrs );
1255 return bFound;
1259 BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const
1261 if (!(ValidCol(nCol1) && ValidCol(nCol2)))
1263 DBG_ERRORFILE("ScTable::IsBlockEmpty: invalid column number");
1264 return FALSE;
1266 BOOL bEmpty = TRUE;
1267 for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
1268 bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2, bIgnoreNotes );
1269 return bEmpty;
1272 SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
1273 SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
1274 const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ) const
1276 // Rueckgabe = neues nArrY
1278 BYTE nRotDir = pPattern->GetRotateDir( pCondSet );
1279 if ( nRotDir != SC_ROTDIR_NONE )
1281 BOOL bHit = TRUE;
1282 if ( nCol+1 < nX1 ) // column to the left
1283 bHit = ( nRotDir != SC_ROTDIR_LEFT );
1284 else if ( nCol > nX2+1 ) // column to the right
1285 bHit = ( nRotDir != SC_ROTDIR_RIGHT ); // SC_ROTDIR_STANDARD may now also be extended to the left
1287 if ( bHit )
1289 double nFactor = 0.0;
1290 if ( nCol > nX2+1 )
1292 long nRotVal = ((const SfxInt32Item&) pPattern->
1293 GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue();
1294 double nRealOrient = nRotVal * F_PI18000; // 1/100 Grad
1295 double nCos = cos( nRealOrient );
1296 double nSin = sin( nRealOrient );
1297 //! begrenzen !!!
1298 //! zusaetzlich Faktor fuer unterschiedliche PPT X/Y !!!
1300 // bei SC_ROTDIR_LEFT kommt immer ein negativer Wert heraus,
1301 // wenn der Modus beruecksichtigt wird
1302 nFactor = -fabs( nCos / nSin );
1305 for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
1307 if ( !(pRowFlags->GetValue(nRow) & CR_HIDDEN) )
1309 BOOL bHitOne = TRUE;
1310 if ( nCol > nX2+1 )
1312 // reicht die gedrehte Zelle bis in den sichtbaren Bereich?
1314 SCCOL nTouchedCol = nCol;
1315 long nWidth = (long) ( pRowHeight->GetValue(nRow) * nFactor );
1316 DBG_ASSERT(nWidth <= 0, "Richtung falsch");
1317 while ( nWidth < 0 && nTouchedCol > 0 )
1319 --nTouchedCol;
1320 nWidth += GetColWidth( nTouchedCol );
1322 if ( nTouchedCol > nX2 )
1323 bHitOne = FALSE;
1326 if (bHitOne)
1328 while ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo < nRow )
1329 ++nArrY;
1330 if ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo == nRow )
1331 pRowInfo[nArrY].nRotMaxCol = nCol;
1338 return nArrY;
1341 void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ) const
1343 if ( !pColWidth || !pRowHeight || !pColFlags || !pRowFlags )
1345 DBG_ERROR( "Spalten-/Zeileninfo fehlt" );
1346 return;
1349 // nRotMaxCol ist auf SC_ROTMAX_NONE initialisiert, nRowNo ist schon gesetzt
1351 SCROW nY1 = pRowInfo[0].nRowNo;
1352 SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
1354 for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
1356 if ( !(pColFlags[nCol] & CR_HIDDEN) )
1358 SCSIZE nArrY = 0;
1359 ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
1360 SCCOL nAttrCol;
1361 SCROW nAttrRow1, nAttrRow2;
1362 const ScPatternAttr* pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
1363 while ( pPattern )
1365 const SfxPoolItem* pCondItem;
1366 if ( pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, TRUE, &pCondItem )
1367 == SFX_ITEM_SET )
1369 // alle Formate durchgehen, damit die Zellen nicht einzeln
1370 // angeschaut werden muessen
1372 ULONG nIndex = ((const SfxUInt32Item*)pCondItem)->GetValue();
1373 ScConditionalFormatList* pList = pDocument->GetCondFormList();
1374 ScStyleSheetPool* pStylePool = pDocument->GetStyleSheetPool();
1375 if (pList && pStylePool && nIndex)
1377 const ScConditionalFormat* pFormat = pList->GetFormat(nIndex);
1378 if ( pFormat )
1380 USHORT nEntryCount = pFormat->Count();
1381 for (USHORT nEntry=0; nEntry<nEntryCount; nEntry++)
1383 String aStyleName = pFormat->GetEntry(nEntry)->GetStyle();
1384 if (aStyleName.Len())
1386 SfxStyleSheetBase* pStyleSheet =
1387 pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
1388 if ( pStyleSheet )
1390 FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
1391 nCol, nAttrRow1, nAttrRow2,
1392 nArrY, pPattern, &pStyleSheet->GetItemSet() );
1393 // nArrY nicht veraendern
1401 nArrY = FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
1402 nCol, nAttrRow1, nAttrRow2,
1403 nArrY, pPattern, NULL );
1405 pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
1411 BOOL ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
1413 // nix:0, mitte:1, unten:2, links:4, oben:8, rechts:16, offen:32
1414 USHORT nEdges;
1416 if ( nCol1 == nCol2 )
1417 { // linke und rechte Spalte
1418 const USHORT n = 4 | 16;
1419 nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n );
1420 // nicht (4 und 16) oder 1 oder 32
1421 if ( nEdges && (((nEdges & n) != n) || (nEdges & 33)) )
1422 return TRUE; // linke oder rechte Kante fehlt oder offen
1424 else
1425 { // linke Spalte
1426 nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, 4 );
1427 // nicht 4 oder 1 oder 32
1428 if ( nEdges && (((nEdges & 4) != 4) || (nEdges & 33)) )
1429 return TRUE; // linke Kante fehlt oder offen
1430 // rechte Spalte
1431 nEdges = aCol[nCol2].GetBlockMatrixEdges( nRow1, nRow2, 16 );
1432 // nicht 16 oder 1 oder 32
1433 if ( nEdges && (((nEdges & 16) != 16) || (nEdges & 33)) )
1434 return TRUE; // rechte Kante fehlt oder offen
1437 if ( nRow1 == nRow2 )
1438 { // obere und untere Zeile
1439 BOOL bOpen = FALSE;
1440 const USHORT n = 2 | 8;
1441 for ( SCCOL i=nCol1; i<=nCol2; i++)
1443 nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n );
1444 if ( nEdges )
1446 if ( (nEdges & n) != n )
1447 return TRUE; // obere oder untere Kante fehlt
1448 if ( nEdges & 4 )
1449 bOpen = TRUE; // linke Kante oeffnet, weitersehen
1450 else if ( !bOpen )
1451 return TRUE; // es gibt was, was nicht geoeffnet wurde
1452 if ( nEdges & 16 )
1453 bOpen = FALSE; // rechte Kante schliesst
1456 if ( bOpen )
1457 return TRUE; // es geht noch weiter
1459 else
1461 USHORT j, n;
1462 SCROW nR;
1463 // erst obere Zeile, dann untere Zeile
1464 for ( j=0, nR=nRow1, n=8; j<2; j++, nR=nRow2, n=2 )
1466 BOOL bOpen = FALSE;
1467 for ( SCCOL i=nCol1; i<=nCol2; i++)
1469 nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n );
1470 if ( nEdges )
1472 // in oberere Zeile keine obere Kante bzw.
1473 // in unterer Zeile keine untere Kante
1474 if ( (nEdges & n) != n )
1475 return TRUE;
1476 if ( nEdges & 4 )
1477 bOpen = TRUE; // linke Kante oeffnet, weitersehen
1478 else if ( !bOpen )
1479 return TRUE; // es gibt was, was nicht geoeffnet wurde
1480 if ( nEdges & 16 )
1481 bOpen = FALSE; // rechte Kante schliesst
1484 if ( bOpen )
1485 return TRUE; // es geht noch weiter
1488 return FALSE;
1492 BOOL ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
1494 BOOL bFound=FALSE;
1495 for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
1496 bFound |= aCol[i].HasSelectionMatrixFragment(rMark);
1497 return bFound;
1501 BOOL ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
1502 SCROW nRow2, BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
1504 if ( !ValidColRow( nCol2, nRow2 ) )
1506 DBG_ERRORFILE("IsBlockEditable: invalid column or row");
1507 if (pOnlyNotBecauseOfMatrix)
1508 *pOnlyNotBecauseOfMatrix = FALSE;
1509 return FALSE;
1512 BOOL bIsEditable = TRUE;
1513 if ( nLockCount )
1514 bIsEditable = FALSE;
1515 else if ( IsProtected() && !pDocument->IsScenario(nTab) )
1517 if((bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED )) != FALSE)
1519 // If Sheet is protected and cells are not protected then
1520 // check the active scenario protect flag if this range is
1521 // on the active scenario range. Note the 'copy back' must also
1522 // be set to apply protection.
1523 USHORT nScenTab = nTab+1;
1524 while(pDocument->IsScenario(nScenTab))
1526 ScRange aEditRange(nCol1, nRow1, nScenTab, nCol2, nRow2, nScenTab);
1527 if(pDocument->IsActiveScenario(nScenTab) && pDocument->HasScenarioRange(nScenTab, aEditRange))
1529 USHORT nFlags;
1530 pDocument->GetScenarioFlags(nScenTab,nFlags);
1531 bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
1532 break;
1534 nScenTab++;
1538 else if (pDocument->IsScenario(nTab))
1540 // Determine if the preceding sheet is protected
1541 SCTAB nActualTab = nTab;
1544 nActualTab--;
1546 while(pDocument->IsScenario(nActualTab));
1548 if(pDocument->IsTabProtected(nActualTab))
1550 ScRange aEditRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
1551 if(pDocument->HasScenarioRange(nTab, aEditRange))
1553 USHORT nFlags;
1554 pDocument->GetScenarioFlags(nTab,nFlags);
1555 bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
1559 if ( bIsEditable )
1561 if ( HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2 ) )
1563 bIsEditable = FALSE;
1564 if ( pOnlyNotBecauseOfMatrix )
1565 *pOnlyNotBecauseOfMatrix = TRUE;
1567 else if ( pOnlyNotBecauseOfMatrix )
1568 *pOnlyNotBecauseOfMatrix = FALSE;
1570 else if ( pOnlyNotBecauseOfMatrix )
1571 *pOnlyNotBecauseOfMatrix = FALSE;
1572 return bIsEditable;
1576 BOOL ScTable::IsSelectionEditable( const ScMarkData& rMark,
1577 BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
1579 BOOL bIsEditable = TRUE;
1580 if ( nLockCount )
1581 bIsEditable = FALSE;
1582 else if ( IsProtected() && !pDocument->IsScenario(nTab) )
1584 if((bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED )) != FALSE)
1586 // If Sheet is protected and cells are not protected then
1587 // check the active scenario protect flag if this area is
1588 // in the active scenario range.
1589 ScRangeList aRanges;
1590 rMark.FillRangeListWithMarks( &aRanges, FALSE );
1591 ULONG nRangeCount = aRanges.Count();
1592 SCTAB nScenTab = nTab+1;
1593 while(pDocument->IsScenario(nScenTab) && bIsEditable)
1595 if(pDocument->IsActiveScenario(nScenTab))
1597 for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
1599 ScRange aRange = *aRanges.GetObject(i);
1600 if(pDocument->HasScenarioRange(nScenTab, aRange))
1602 USHORT nFlags;
1603 pDocument->GetScenarioFlags(nScenTab,nFlags);
1604 bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
1608 nScenTab++;
1612 else if (pDocument->IsScenario(nTab))
1614 // Determine if the preceding sheet is protected
1615 SCTAB nActualTab = nTab;
1618 nActualTab--;
1620 while(pDocument->IsScenario(nActualTab));
1622 if(pDocument->IsTabProtected(nActualTab))
1624 ScRangeList aRanges;
1625 rMark.FillRangeListWithMarks( &aRanges, FALSE );
1626 ULONG nRangeCount = aRanges.Count();
1627 for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
1629 ScRange aRange = *aRanges.GetObject(i);
1630 if(pDocument->HasScenarioRange(nTab, aRange))
1632 USHORT nFlags;
1633 pDocument->GetScenarioFlags(nTab,nFlags);
1634 bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
1639 if ( bIsEditable )
1641 if ( HasSelectionMatrixFragment( rMark ) )
1643 bIsEditable = FALSE;
1644 if ( pOnlyNotBecauseOfMatrix )
1645 *pOnlyNotBecauseOfMatrix = TRUE;
1647 else if ( pOnlyNotBecauseOfMatrix )
1648 *pOnlyNotBecauseOfMatrix = FALSE;
1650 else if ( pOnlyNotBecauseOfMatrix )
1651 *pOnlyNotBecauseOfMatrix = FALSE;
1652 return bIsEditable;
1657 void ScTable::LockTable()
1659 ++nLockCount;
1663 void ScTable::UnlockTable()
1665 if (nLockCount)
1666 --nLockCount;
1667 else
1669 DBG_ERROR("UnlockTable ohne LockTable");
1674 void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, BOOL bDeep ) const
1676 for (SCCOL i=0; i<=MAXCOL; i++)
1677 aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
1681 void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1,
1682 SCCOL nCol2, SCROW nRow2, BOOL bDeep ) const
1684 for (SCCOL i=nCol1; i<=nCol2; i++)
1685 aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
1689 void ScTable::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
1690 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
1692 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1694 PutInOrder(nStartCol, nEndCol);
1695 PutInOrder(nStartRow, nEndRow);
1696 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1697 aCol[i].MergeBlockFrame( pLineOuter, pLineInner, rFlags,
1698 nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
1703 void ScTable::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
1704 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
1706 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1708 PutInOrder(nStartCol, nEndCol);
1709 PutInOrder(nStartRow, nEndRow);
1710 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1711 aCol[i].ApplyBlockFrame( pLineOuter, pLineInner,
1712 nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
1717 void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
1719 if (ValidColRow(nCol,nRow))
1720 aCol[nCol].ApplyPattern( nRow, rAttr );
1724 void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1725 const ScPatternAttr& rAttr, ScEditDataArray* pDataArray )
1727 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1729 PutInOrder(nStartCol, nEndCol);
1730 PutInOrder(nStartRow, nEndRow);
1731 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1732 aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray);
1736 void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
1737 const ScPatternAttr& rPattern, short nNewType )
1739 SCCOL nEndCol = rRange.aEnd.Col();
1740 for ( SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; nCol++ )
1742 aCol[nCol].ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
1748 void ScTable::ApplyStyle( SCCOL nCol, SCROW nRow, const ScStyleSheet& rStyle )
1750 if (ValidColRow(nCol,nRow))
1751 aCol[nCol].ApplyStyle( nRow, rStyle );
1755 void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
1757 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1759 PutInOrder(nStartCol, nEndCol);
1760 PutInOrder(nStartRow, nEndRow);
1761 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1762 aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
1767 void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
1769 for (SCCOL i=0; i<=MAXCOL; i++)
1770 aCol[i].ApplySelectionStyle( rStyle, rMark );
1774 void ScTable::ApplySelectionLineStyle( const ScMarkData& rMark,
1775 const SvxBorderLine* pLine, BOOL bColorOnly )
1777 if ( bColorOnly && !pLine )
1778 return;
1780 for (SCCOL i=0; i<=MAXCOL; i++)
1781 aCol[i].ApplySelectionLineStyle( rMark, pLine, bColorOnly );
1785 const ScStyleSheet* ScTable::GetStyle( SCCOL nCol, SCROW nRow ) const
1787 if (ValidColRow(nCol, nRow))
1788 return aCol[nCol].GetStyle(nRow);
1789 else
1790 return NULL;
1794 const ScStyleSheet* ScTable::GetSelectionStyle( const ScMarkData& rMark, BOOL& rFound ) const
1796 rFound = FALSE;
1798 BOOL bEqual = TRUE;
1799 BOOL bColFound;
1801 const ScStyleSheet* pStyle = NULL;
1802 const ScStyleSheet* pNewStyle;
1804 for (SCCOL i=0; i<=MAXCOL && bEqual; i++)
1805 if (rMark.HasMultiMarks(i))
1807 pNewStyle = aCol[i].GetSelectionStyle( rMark, bColFound );
1808 if (bColFound)
1810 rFound = TRUE;
1811 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
1812 bEqual = FALSE; // unterschiedliche
1813 pStyle = pNewStyle;
1817 return bEqual ? pStyle : NULL;
1821 const ScStyleSheet* ScTable::GetAreaStyle( BOOL& rFound, SCCOL nCol1, SCROW nRow1,
1822 SCCOL nCol2, SCROW nRow2 ) const
1824 rFound = FALSE;
1826 BOOL bEqual = TRUE;
1827 BOOL bColFound;
1829 const ScStyleSheet* pStyle = NULL;
1830 const ScStyleSheet* pNewStyle;
1832 for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
1834 pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
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 BOOL ScTable::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const
1850 BOOL bIsUsed = FALSE;
1852 for ( SCCOL i=0; i<=MAXCOL; i++ )
1854 if ( aCol[i].IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
1856 if ( !bGatherAllStyles )
1857 return TRUE;
1858 bIsUsed = TRUE;
1862 return bIsUsed;
1866 void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRemoved,
1867 OutputDevice* pDev,
1868 double nPPTX, double nPPTY,
1869 const Fraction& rZoomX, const Fraction& rZoomY )
1871 ScFlatBoolRowSegments aUsedRows;
1872 for (SCCOL i = 0; i <= MAXCOL; ++i)
1873 aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
1875 SCROW nRow = 0;
1876 while (nRow <= MAXROW)
1878 ScFlatBoolRowSegments::RangeData aData;
1879 if (!aUsedRows.getRangeData(nRow, aData))
1880 // search failed!
1881 return;
1883 SCROW nEndRow = aData.mnRow2;
1884 if (aData.mbValue)
1885 SetOptimalHeight(nRow, nEndRow, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE);
1887 nRow = nEndRow + 1;
1892 BOOL ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1893 INT16 nFlags )
1895 BOOL bChanged = FALSE;
1896 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1897 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1898 bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags);
1899 return bChanged;
1903 BOOL ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1904 INT16 nFlags )
1906 BOOL bChanged = FALSE;
1907 if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
1908 for (SCCOL i = nStartCol; i <= nEndCol; i++)
1909 bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
1910 return bChanged;
1914 void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr, BOOL bPutToPool )
1916 if (ValidColRow(nCol,nRow))
1917 aCol[nCol].SetPattern( nRow, rAttr, bPutToPool );
1921 void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
1923 if (ValidColRow(nCol,nRow))
1924 aCol[nCol].ApplyAttr( nRow, rAttr );
1928 void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark,
1929 ScEditDataArray* pDataArray )
1931 for (SCCOL i=0; i<=MAXCOL; i++)
1932 aCol[i].ApplySelectionCache( pCache, rMark, pDataArray );
1936 void ScTable::ChangeSelectionIndent( BOOL bIncrement, const ScMarkData& rMark )
1938 for (SCCOL i=0; i<=MAXCOL; i++)
1939 aCol[i].ChangeSelectionIndent( bIncrement, rMark );
1943 void ScTable::ClearSelectionItems( const USHORT* pWhich, const ScMarkData& rMark )
1945 for (SCCOL i=0; i<=MAXCOL; i++)
1946 aCol[i].ClearSelectionItems( pWhich, rMark );
1950 // Spaltenbreiten / Zeilenhoehen
1952 void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
1954 if (VALIDCOL(nCol) && pColWidth)
1956 if (!nNewWidth)
1958 // DBG_ERROR("Spaltenbreite 0 in SetColWidth");
1959 nNewWidth = STD_COL_WIDTH;
1962 if ( nNewWidth != pColWidth[nCol] )
1964 nRecalcLvl++;
1965 InitializeNoteCaptions();
1966 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1967 if (pDrawLayer)
1968 pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
1969 pColWidth[nCol] = nNewWidth;
1970 if( !--nRecalcLvl )
1971 SetDrawPageSize();
1974 else
1976 DBG_ERROR("Falsche Spaltennummer oder keine Breiten");
1981 void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
1983 if (VALIDROW(nRow) && pRowHeight)
1985 if (!nNewHeight)
1987 DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
1988 nNewHeight = ScGlobal::nStdRowHeight;
1991 USHORT nOldHeight = pRowHeight->GetValue(nRow);
1992 if ( nNewHeight != nOldHeight )
1994 nRecalcLvl++;
1995 InitializeNoteCaptions();
1996 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1997 if (pDrawLayer)
1998 pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
1999 pRowHeight->SetValue( nRow, nNewHeight);
2000 if( !--nRecalcLvl )
2001 SetDrawPageSize();
2004 else
2006 DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
2011 BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight,
2012 double /* nPPTX */, double nPPTY )
2014 BOOL bChanged = FALSE;
2015 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
2017 nRecalcLvl++;
2018 InitializeNoteCaptions();
2019 if (!nNewHeight)
2021 DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
2022 nNewHeight = ScGlobal::nStdRowHeight;
2025 long nNewPix = (long) ( nNewHeight * nPPTY );
2027 BOOL bSingle = FALSE; // TRUE = process every row for its own
2028 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2029 if (pDrawLayer)
2030 if (pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ))
2031 bSingle = TRUE;
2033 if (bSingle)
2035 size_t nIndex;
2036 SCROW nRegionEndRow;
2037 USHORT nOldHeight = pRowHeight->GetValue( nStartRow, nIndex, nRegionEndRow);
2038 if (nNewHeight == nOldHeight && nEndRow <= nRegionEndRow)
2039 bSingle = FALSE; // no difference in this range
2041 if (bSingle)
2043 if (nEndRow-nStartRow < 20)
2045 // Whether new pixel size will differ from old pixel size in any row.
2046 ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight,
2047 nStartRow, nEndRow);
2050 if (*aIter != nNewHeight)
2051 bChanged = (nNewPix != (long) (*aIter * nPPTY));
2052 } while (!bChanged && aIter.NextRange());
2054 /* #i94028# #i94991# If drawing objects are involved, each row
2055 has to be changed for its own, because each call to
2056 ScDrawLayer::HeightChanged expects correct row heights
2057 above passed row in the document. Cannot use array iterator
2058 because array changes in every cycle. */
2059 if( pDrawLayer )
2061 for( SCROW nRow = nStartRow; nRow <= nEndRow ; ++nRow )
2063 pDrawLayer->HeightChanged( nTab, nRow,
2064 ((long) nNewHeight) - ((long) pRowHeight->GetValue( nRow )));
2065 pRowHeight->SetValue( nRow, nNewHeight );
2068 else
2069 pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
2071 else
2073 SCROW nMid = (nStartRow+nEndRow) / 2;
2074 if (SetRowHeightRange( nStartRow, nMid, nNewHeight, 1.0, 1.0 ))
2075 bChanged = TRUE;
2076 if (SetRowHeightRange( nMid+1, nEndRow, nNewHeight, 1.0, 1.0 ))
2077 bChanged = TRUE;
2080 else
2082 if (pDrawLayer)
2084 unsigned long nOldHeights = pRowHeight->SumValues( nStartRow, nEndRow);
2085 // FIXME: should we test for overflows?
2086 long nHeightDif = (long) (unsigned long) nNewHeight *
2087 (nEndRow - nStartRow + 1) - nOldHeights;
2088 pDrawLayer->HeightChanged( nTab, nEndRow, nHeightDif );
2090 // Whether new pixel size will differ from old pixel size in any row.
2091 ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight,
2092 nStartRow, nEndRow);
2095 if (*aIter != nNewHeight)
2096 bChanged = (nNewPix != (long) (*aIter * nPPTY));
2097 } while (!bChanged && aIter.NextRange());
2098 pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
2100 if( !--nRecalcLvl )
2101 SetDrawPageSize();
2103 else
2105 DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
2108 return bChanged;
2112 void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
2114 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
2116 if (bManual)
2117 pRowFlags->OrValue( nStartRow, nEndRow, CR_MANUALSIZE);
2118 else
2119 pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
2121 else
2123 DBG_ERROR("Falsche Zeilennummer oder keine Zeilenflags");
2128 USHORT ScTable::GetColWidth( SCCOL nCol ) const
2130 DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
2132 if (VALIDCOL(nCol) && pColFlags && pColWidth)
2134 if ( pColFlags[nCol] & CR_HIDDEN )
2135 return 0;
2136 else
2137 return pColWidth[nCol];
2139 else
2140 return (USHORT) STD_COL_WIDTH;
2144 USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingestellte
2146 DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
2148 if (VALIDCOL(nCol) && pColWidth)
2149 return pColWidth[nCol];
2150 else
2151 return (USHORT) STD_COL_WIDTH;
2155 USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
2157 // get the width that is used in the largest continuous column range (up to nEndCol)
2159 if ( !ValidCol(nEndCol) )
2161 DBG_ERROR("wrong column");
2162 nEndCol = MAXCOL;
2165 USHORT nMaxWidth = 0;
2166 USHORT nMaxCount = 0;
2167 USHORT nRangeStart = 0;
2168 while ( nRangeStart <= nEndCol )
2170 // skip hidden columns
2171 while ( nRangeStart <= nEndCol && (pColFlags[nRangeStart] & CR_HIDDEN) )
2172 ++nRangeStart;
2173 if ( nRangeStart <= nEndCol )
2175 USHORT nThisCount = 0;
2176 USHORT nThisWidth = pColWidth[nRangeStart];
2177 USHORT nRangeEnd = nRangeStart;
2178 while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth )
2180 ++nThisCount;
2181 ++nRangeEnd;
2183 // skip hidden columns
2184 while ( nRangeEnd <= nEndCol && (pColFlags[nRangeEnd] & CR_HIDDEN) )
2185 ++nRangeEnd;
2188 if ( nThisCount > nMaxCount )
2190 nMaxCount = nThisCount;
2191 nMaxWidth = nThisWidth;
2194 nRangeStart = nRangeEnd; // next range
2198 return nMaxWidth;
2202 USHORT ScTable::GetRowHeight( SCROW nRow ) const
2204 DBG_ASSERT(VALIDROW(nRow),"Falsche Zeilennummer");
2206 if (VALIDROW(nRow) && pRowFlags && pRowHeight)
2208 if ( pRowFlags->GetValue(nRow) & CR_HIDDEN )
2209 return 0;
2210 else
2211 return pRowHeight->GetValue(nRow);
2213 else
2214 return (USHORT) ScGlobal::nStdRowHeight;
2218 ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const
2220 DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
2222 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight)
2224 return pRowFlags->SumCoupledArrayForCondition( nStartRow, nEndRow,
2225 CR_HIDDEN, 0, *pRowHeight);
2227 else
2228 return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight);
2232 ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const
2234 DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
2236 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight)
2238 return pRowFlags->SumScaledCoupledArrayForCondition( nStartRow,
2239 nEndRow, CR_HIDDEN, 0, *pRowHeight, fScale);
2241 else
2242 return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
2246 USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hidden
2248 DBG_ASSERT(VALIDROW(nRow),"wrong row number");
2250 if (VALIDROW(nRow) && pRowHeight)
2251 return pRowHeight->GetValue(nRow);
2252 else
2253 return (USHORT) ScGlobal::nStdRowHeight;
2257 // Spalten-/Zeilen-Flags
2260 SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const
2262 SCROW nEndRow = nRow;
2263 if ( pRowFlags )
2265 nEndRow = pRowFlags->GetBitStateEnd( nRow, CR_HIDDEN, CR_HIDDEN);
2266 if (ValidRow(nEndRow))
2267 ++nEndRow;
2268 else
2269 nEndRow = nRow;
2271 return nEndRow - nRow;
2275 //! ShowRows / DBShowRows zusammenfassen
2277 void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
2279 if (VALIDCOL(nCol) && pColFlags)
2281 BOOL bWasVis = ( pColFlags[nCol] & CR_HIDDEN ) == 0;
2282 if (bWasVis != bShow)
2284 nRecalcLvl++;
2285 InitializeNoteCaptions();
2286 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2287 if (pDrawLayer)
2289 if (bShow)
2290 pDrawLayer->WidthChanged( nTab, nCol, (long) pColWidth[nCol] );
2291 else
2292 pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] );
2295 if (bShow)
2296 pColFlags[nCol] &= ~CR_HIDDEN;
2297 else
2298 pColFlags[nCol] |= CR_HIDDEN;
2299 if( !--nRecalcLvl )
2300 SetDrawPageSize();
2302 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2303 if ( pCharts )
2304 pCharts->SetRangeDirty(ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ));
2307 else
2309 DBG_ERROR("Falsche Spaltennummer oder keine Flags");
2314 void ScTable::ShowRow(SCROW nRow, BOOL bShow)
2316 if (VALIDROW(nRow) && pRowFlags)
2318 BYTE nFlags = pRowFlags->GetValue(nRow);
2319 BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
2320 if (bWasVis != bShow)
2322 nRecalcLvl++;
2323 InitializeNoteCaptions();
2324 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2325 if (pDrawLayer)
2327 if (bShow)
2328 pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
2329 else
2330 pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
2333 if (bShow)
2334 pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED));
2335 else
2336 pRowFlags->SetValue( nRow, nFlags | CR_HIDDEN);
2337 if( !--nRecalcLvl )
2338 SetDrawPageSize();
2340 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2341 if ( pCharts )
2342 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
2345 else
2347 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2352 void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
2354 if (VALIDROW(nRow) && pRowFlags)
2356 BYTE nFlags = pRowFlags->GetValue(nRow);
2357 BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
2358 nRecalcLvl++;
2359 InitializeNoteCaptions();
2360 if (bWasVis != bShow)
2362 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2363 if (pDrawLayer)
2365 if (bShow)
2366 pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
2367 else
2368 pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
2372 // Filter-Flag immer setzen, auch wenn Hidden unveraendert
2373 if (bShow)
2374 pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED));
2375 else
2376 pRowFlags->SetValue( nRow, nFlags | (CR_HIDDEN | CR_FILTERED));
2377 if( !--nRecalcLvl )
2378 SetDrawPageSize();
2380 if (bWasVis != bShow)
2382 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2383 if ( pCharts )
2384 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
2386 if (pOutlineTable)
2387 UpdateOutlineRow( nRow, nRow, bShow );
2390 else
2392 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2397 void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
2399 SCROW nStartRow = nRow1;
2400 nRecalcLvl++;
2401 InitializeNoteCaptions();
2402 while (nStartRow <= nRow2)
2404 BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
2405 SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag);
2406 if (nEndRow > nRow2)
2407 nEndRow = nRow2;
2409 BOOL bWasVis = ( nOldFlag == 0 );
2410 BOOL bChanged = ( bWasVis != bShow );
2411 if ( bChanged )
2413 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2414 if (pDrawLayer)
2416 long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
2417 if (bShow)
2418 pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
2419 else
2420 pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
2424 if (bShow)
2425 pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) );
2426 else
2427 pRowFlags->OrValue( nStartRow, nEndRow, (CR_HIDDEN | CR_FILTERED));
2429 if ( bChanged )
2431 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2432 if ( pCharts )
2433 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
2436 nStartRow = nEndRow + 1;
2439 // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
2440 // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
2441 // to be done here.
2442 if (pOutlineTable)
2443 UpdateOutlineRow( nRow1, nRow2, bShow );
2445 if( !--nRecalcLvl )
2446 SetDrawPageSize();
2450 void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
2452 SCROW nStartRow = nRow1;
2453 nRecalcLvl++;
2454 InitializeNoteCaptions();
2455 while (nStartRow <= nRow2)
2457 BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
2458 SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag);
2459 if (nEndRow > nRow2)
2460 nEndRow = nRow2;
2462 BOOL bWasVis = ( nOldFlag == 0 );
2463 BOOL bChanged = ( bWasVis != bShow );
2464 if ( bChanged )
2466 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2467 if (pDrawLayer)
2469 long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
2470 if (bShow)
2471 pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
2472 else
2473 pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
2477 if (bShow)
2478 pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) );
2479 else
2480 pRowFlags->OrValue( nStartRow, nEndRow, CR_HIDDEN);
2482 if ( bChanged )
2484 ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
2485 if ( pCharts )
2486 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
2489 nStartRow = nEndRow + 1;
2491 if( !--nRecalcLvl )
2492 SetDrawPageSize();
2496 BOOL ScTable::IsFiltered(SCROW nRow) const
2498 if (VALIDROW(nRow) && pRowFlags)
2499 return ( pRowFlags->GetValue(nRow) & CR_FILTERED ) != 0;
2501 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2502 return FALSE;
2506 void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags )
2508 if (VALIDCOL(nCol) && pColFlags)
2509 pColFlags[nCol] = nNewFlags;
2510 else
2512 DBG_ERROR("Falsche Spaltennummer oder keine Flags");
2517 void ScTable::SetRowFlags( SCROW nRow, BYTE nNewFlags )
2519 if (VALIDROW(nRow) && pRowFlags)
2520 pRowFlags->SetValue( nRow, nNewFlags);
2521 else
2523 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2528 void ScTable::SetRowFlags( SCROW nStartRow, SCROW nEndRow, BYTE nNewFlags )
2530 if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
2531 pRowFlags->SetValue( nStartRow, nEndRow, nNewFlags);
2532 else
2534 DBG_ERROR("Falsche Zeilennummer(n) oder keine Flags");
2539 BYTE ScTable::GetColFlags( SCCOL nCol ) const
2541 if (VALIDCOL(nCol) && pColFlags)
2542 return pColFlags[nCol];
2543 else
2544 return 0;
2548 BYTE ScTable::GetRowFlags( SCROW nRow ) const
2550 if (VALIDROW(nRow) && pRowFlags)
2551 return pRowFlags->GetValue(nRow);
2552 else
2553 return 0;
2557 SCROW ScTable::GetLastFlaggedRow() const
2559 if ( !pRowFlags )
2560 return 0;
2562 SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
2563 return ValidRow(nLastFound) ? nLastFound : 0;
2567 SCCOL ScTable::GetLastChangedCol() const
2569 if ( !pColFlags )
2570 return 0;
2572 SCCOL nLastFound = 0;
2573 for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
2574 if ((pColFlags[nCol] & ~CR_PAGEBREAK) || (pColWidth[nCol] != STD_COL_WIDTH))
2575 nLastFound = nCol;
2577 return nLastFound;
2581 SCROW ScTable::GetLastChangedRow() const
2583 if ( !pRowFlags )
2584 return 0;
2586 SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
2587 if (!ValidRow(nLastFlags))
2588 nLastFlags = 0;
2590 SCROW nLastHeight = pRowHeight->GetLastUnequalAccess( 0, ScGlobal::nStdRowHeight);
2591 if (!ValidRow(nLastHeight))
2592 nLastHeight = 0;
2594 return std::max( nLastFlags, nLastHeight);
2598 BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
2600 if (pOutlineTable && pColFlags)
2602 ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
2603 return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, aArray );
2605 else
2606 return FALSE;
2610 BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
2612 if (pOutlineTable && pRowFlags)
2613 return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *pRowFlags );
2614 else
2615 return FALSE;
2619 void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
2621 if (pColFlags)
2623 while ( rX1>0 ? (pColFlags[rX1-1] & CR_HIDDEN) : FALSE )
2624 --rX1;
2625 while ( rX2<MAXCOL ? (pColFlags[rX2+1] & CR_HIDDEN) : FALSE )
2626 ++rX2;
2628 if (pRowFlags)
2630 if (rY1 > 0)
2632 SCROW nStartRow = pRowFlags->GetBitStateStart( rY1-1, CR_HIDDEN, CR_HIDDEN);
2633 if (ValidRow(nStartRow))
2634 rY1 = nStartRow;
2636 if (rY2 < MAXROW)
2638 SCROW nEndRow = pRowFlags->GetBitStateEnd( rY2+1, CR_HIDDEN, CR_HIDDEN);
2639 if (ValidRow(nEndRow))
2640 rY2 = nEndRow;
2646 void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
2648 if (pColFlags)
2650 while ( rX2>rX1 && (pColFlags[rX2] & CR_HIDDEN) )
2651 --rX2;
2652 while ( rX2>rX1 && (pColFlags[rX1] & CR_HIDDEN) )
2653 ++rX1;
2655 if (pRowFlags)
2657 if (rY1 < rY2)
2659 SCROW nStartRow = pRowFlags->GetBitStateStart( rY2, CR_HIDDEN, CR_HIDDEN);
2660 if (ValidRow(nStartRow) && nStartRow >= rY1)
2661 rY2 = nStartRow;
2663 if (rY1 < rY2)
2665 SCROW nEndRow = pRowFlags->GetBitStateEnd( rY1, CR_HIDDEN, CR_HIDDEN);
2666 if (ValidRow(nEndRow) && nEndRow <= rY2)
2667 rY1 = nEndRow;
2673 // Auto-Outline
2675 template< typename T >
2676 short DiffSign( T a, T b )
2678 return (a<b) ? -1 :
2679 (a>b) ? 1 : 0;
2683 void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
2685 BOOL bSizeChanged = FALSE;
2686 BOOL bMissed = FALSE;
2688 SCCOL nCol;
2689 SCROW nRow;
2690 SCROW i;
2691 BOOL bFound;
2692 ScOutlineArray* pArray;
2693 ScBaseCell* pCell;
2694 ScRange aRef;
2695 /* ScPatternAttr aBoldPattern( pDocument->GetPool() ); //! spezielle Format-Vorlage
2696 aBoldPattern.GetItemSet().Put( SvxWeightItem( WEIGHT_BOLD ) );
2699 StartOutlineTable();
2701 // Zeilen
2703 SCROW nCount = nEndRow-nStartRow+1;
2704 BOOL* pUsed = new BOOL[nCount];
2705 for (i=0; i<nCount; i++)
2706 pUsed[i] = FALSE;
2707 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
2708 if (!aCol[nCol].IsEmptyData())
2709 aCol[nCol].FindUsed( nStartRow, nEndRow, pUsed );
2711 pArray = pOutlineTable->GetRowArray();
2712 for (nRow=nStartRow; nRow<=nEndRow; nRow++)
2713 if (pUsed[nRow-nStartRow])
2715 bFound = FALSE;
2716 for (nCol=nStartCol; nCol<=nEndCol && !bFound; nCol++)
2717 if (!aCol[nCol].IsEmptyData())
2719 pCell = aCol[nCol].GetCell( nRow );
2720 if (pCell)
2721 if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2722 if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
2723 if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
2724 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
2725 DiffSign( aRef.aStart.Row(), nRow ) ==
2726 DiffSign( aRef.aEnd.Row(), nRow ) )
2728 if (pArray->Insert( aRef.aStart.Row(), aRef.aEnd.Row(), bSizeChanged ))
2730 // ApplyPatternArea( nStartCol, nRow, nEndCol, nRow, aBoldPattern );
2731 bFound = TRUE;
2733 else
2734 bMissed = TRUE;
2739 delete[] pUsed;
2741 // Spalten
2743 pArray = pOutlineTable->GetColArray();
2744 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
2746 if (!aCol[nCol].IsEmptyData())
2748 bFound = FALSE;
2749 ScColumnIterator aIter( &aCol[nCol], nStartRow, nEndRow );
2750 while ( aIter.Next( nRow, pCell ) && !bFound )
2752 if ( pCell->GetCellType() == CELLTYPE_FORMULA )
2753 if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
2754 if ( aRef.aStart.Row() == nRow && aRef.aEnd.Row() == nRow &&
2755 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
2756 DiffSign( aRef.aStart.Col(), nCol ) ==
2757 DiffSign( aRef.aEnd.Col(), nCol ) )
2759 if (pArray->Insert( aRef.aStart.Col(), aRef.aEnd.Col(), bSizeChanged ))
2761 // ApplyPatternArea( nCol, nStartRow, nCol, nEndRow, aBoldPattern );
2762 bFound = TRUE;
2764 else
2765 bMissed = TRUE;
2772 // CopyData - fuer Query in anderen Bereich
2774 void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2775 SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab )
2777 //! wenn fuer mehrere Zeilen benutzt, nach Spalten optimieren!
2779 ScAddress aSrc( nStartCol, nStartRow, nTab );
2780 ScAddress aDest( nDestCol, nDestRow, nDestTab );
2781 ScRange aRange( aSrc, aDest );
2782 BOOL bThisTab = ( nDestTab == nTab );
2783 SCROW nDestY = nDestRow;
2784 for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
2786 aSrc.SetRow( nRow );
2787 aDest.SetRow( nDestY );
2788 SCCOL nDestX = nDestCol;
2789 for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
2791 aSrc.SetCol( nCol );
2792 aDest.SetCol( nDestX );
2793 ScBaseCell* pCell = GetCell( nCol, nRow );
2794 if (pCell)
2796 pCell = pCell->CloneWithoutNote( *pDocument );
2797 if (pCell->GetCellType() == CELLTYPE_FORMULA)
2799 ((ScFormulaCell*)pCell)->UpdateReference( URM_COPY, aRange,
2800 ((SCsCOL) nDestCol) - ((SCsCOL) nStartCol),
2801 ((SCsROW) nDestRow) - ((SCsROW) nStartRow),
2802 ((SCsTAB) nDestTab) - ((SCsTAB) nTab) );
2803 ((ScFormulaCell*)pCell)->aPos = aDest;
2806 if (bThisTab)
2808 PutCell( nDestX, nDestY, pCell );
2809 SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ), TRUE );
2811 else
2813 pDocument->PutCell( aDest, pCell );
2814 pDocument->SetPattern( aDest, *GetPattern( nCol, nRow ), TRUE );
2817 ++nDestX;
2819 ++nDestY;
2824 BOOL ScTable::RefVisible(ScFormulaCell* pCell)
2826 ScRange aRef;
2828 if (pCell->HasOneReference(aRef))
2830 if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab() && pRowFlags)
2832 // while ((value & CR_FILTERED) == CR_FILTERED)
2833 // most times will be faster than
2834 // while ((value & CR_FILTERED) == 0)
2835 SCROW nEndRow = pRowFlags->GetBitStateEnd( aRef.aStart.Row(),
2836 CR_FILTERED, CR_FILTERED);
2837 if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
2838 return TRUE; // at least partly visible
2839 return FALSE; // completely unvisible
2843 return TRUE; // irgendwie anders
2847 void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, String& rStr)
2849 GetInputString(nCol, nRow, rStr);
2850 rStr.EraseTrailingChars();
2851 rStr.EraseLeadingChars();
2852 ScGlobal::pCharClass->toUpper(rStr);
2856 // Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
2858 void ScTable::SetDrawPageSize()
2860 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2861 if( pDrawLayer )
2863 long x = GetColOffset( MAXCOL + 1 );
2864 long y = GetRowOffset( MAXROW + 1 );
2865 x = (long) ((double) x * HMM_PER_TWIPS);
2866 y = (long) ((double) y * HMM_PER_TWIPS);
2868 if ( IsLayoutRTL() ) // IsNegativePage
2869 x = -x;
2871 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ) );
2876 ULONG ScTable::GetRowOffset( SCROW nRow ) const
2878 ULONG n = 0;
2879 if ( pRowFlags && pRowHeight )
2881 if (nRow == 0)
2882 return 0;
2883 else if (nRow == 1)
2884 return GetRowHeight(0);
2886 n = pRowFlags->SumCoupledArrayForCondition( 0, nRow-1, CR_HIDDEN, 0,
2887 *pRowHeight);
2888 #ifdef DBG_UTIL
2889 if (n == ::std::numeric_limits<unsigned long>::max())
2890 DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow");
2891 #endif
2893 else
2895 DBG_ERROR("GetRowOffset: Daten fehlen");
2897 return n;
2901 ULONG ScTable::GetColOffset( SCCOL nCol ) const
2903 ULONG n = 0;
2904 if ( pColFlags && pColWidth )
2906 SCCOL i;
2907 BYTE* pFlags = pColFlags;
2908 USHORT* pWidth = pColWidth;
2909 for( i = 0; i < nCol; i++, pFlags++, pWidth++ )
2910 if( !( *pFlags & CR_HIDDEN ) )
2911 n += *pWidth;
2913 else
2915 DBG_ERROR("GetColumnOffset: Daten fehlen");
2917 return n;