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>
42 #include <svtools/PasswordHelper.hxx>
43 #include <unotools/transliterationwrapper.hxx>
45 #include "patattr.hxx"
46 #include "docpool.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"
62 #include "globstr.hrc"
63 #include "segmenttree.hxx"
67 // STATIC DATA -----------------------------------------------------------
70 BOOL
ScTable::SetOutlineTable( const ScOutlineTable
* pNewOutline
)
79 nOldSizeX
= pOutlineTable
->GetColArray()->GetDepth();
80 nOldSizeY
= pOutlineTable
->GetRowArray()->GetDepth();
86 pOutlineTable
= new ScOutlineTable( *pNewOutline
);
87 nNewSizeX
= pOutlineTable
->GetColArray()->GetDepth();
88 nNewSizeY
= pOutlineTable
->GetRowArray()->GetDepth();
93 return ( nNewSizeX
!= nOldSizeX
|| nNewSizeY
!= nOldSizeY
); // Groesse geaendert ?
97 void ScTable::StartOutlineTable()
100 pOutlineTable
= new ScOutlineTable
;
104 BOOL
ScTable::TestInsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCSIZE nSize
)
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
);
118 void ScTable::InsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
)
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
);
134 pOutlineTable
->InsertRow( nStartRow
, nSize
);
137 for (SCCOL j
=nStartCol
; j
<=nEndCol
; j
++)
138 aCol
[j
].InsertRow( nStartRow
, nSize
);
144 void ScTable::DeleteRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
,
148 InitializeNoteCaptions();
149 if (nStartCol
==0 && nEndCol
==MAXCOL
)
151 if (pRowHeight
&& pRowFlags
)
153 pRowHeight
->Remove( nStartRow
, nSize
);
154 pRowFlags
->Remove( nStartRow
, nSize
);
157 if (pOutlineTable
->DeleteRow( nStartRow
, nSize
))
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
);
172 BOOL
ScTable::TestInsertCol( SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
)
176 if ( nStartRow
==0 && nEndRow
==MAXROW
&& pOutlineTable
)
177 bTest
= pOutlineTable
->TestInsertCol(nSize
);
179 if ( nSize
> static_cast<SCSIZE
>(MAXCOL
) )
182 for (SCCOL i
=MAXCOL
; (i
+static_cast<SCCOL
>(nSize
)>MAXCOL
) && bTest
; i
--)
183 bTest
= aCol
[i
].TestInsertCol(nStartRow
, nEndRow
);
189 void ScTable::InsertCol( SCCOL nStartCol
, SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
)
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]) );
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]);
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
;
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
);
239 void ScTable::DeleteCol( SCCOL nStartCol
, SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
,
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]) );
254 if (pOutlineTable
->DeleteCol( nStartCol
, nSize
))
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]);
274 for (SCSIZE i
=0; static_cast<SCCOL
>(i
+nSize
)+nStartCol
<= MAXCOL
; i
++)
275 aCol
[nStartCol
+ nSize
+ i
].MoveTo(nStartRow
, nEndRow
, aCol
[nStartCol
+ i
]);
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
))
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 )
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
))
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
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
)
392 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
393 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
394 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
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
);
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
);
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
++)
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
;
479 aRef
.InitFlags(); // -> all absolute
480 aRef
.SetFlag3D(TRUE
);
481 aRef
.CalcRelFromAbs( aDestPos
);
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
);
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
);
496 if ( bAsLink
) // Referenz erzeugen ?
498 pNew
= aCol
[nCol
].CreateRefCell( pDestDoc
, aDestPos
, aIter
.GetIndex(), nFlags
);
502 ScAddress
aOwnPos( nCol
, nRow
, nTab
);
503 if (pCell
->GetCellType() == CELLTYPE_FORMULA
)
505 pNew
= pCell
->CloneWithNote( aOwnPos
, *pDestDoc
, aDestPos
, SC_CLONECELL_STARTLISTENING
);
508 // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
511 ((ScFormulaCell
*)pNew
)->TransposeReference();
515 pNew
= pCell
->CloneWithNote( aOwnPos
, *pDestDoc
, aDestPos
);
518 pTransClip
->PutCell( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pNew
);
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
);
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
);
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
))),
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
);
575 rNewSet
.Put( ScMergeFlagAttr( nNewFlags
) );
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
);
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
))
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
);
650 pDestTab
->IncRecalcLevel();
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?
661 pCharts
->SetRangeDirty(ScRange( i
, 0, nTab
, i
, MAXROW
, nTab
));
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?
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
);
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
],
706 aCol
[i
].CopyToColumn(0, MAXROW
, IDF_FORMULA
, FALSE
, pDestTab
->aCol
[i
]);
712 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
713 pDestTab
->pColWidth
[i
] = pColWidth
[i
];
715 pDestTab
->pRowHeight
->CopyFrom( *pRowHeight
, nRow1
, nRow2
);
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?
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" );
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 ) );
773 ULONG nCount
= pList
->Count();
774 for ( ULONG j
= 0; j
< nCount
; j
++ )
776 ScRange
* pR
= pList
->GetObject( j
);
777 if ( pR
->Intersects( aTabRange
) )
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
;
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())
813 for (SCCOL i
=0; i
<=MAXCOL
&& bOk
; i
++)
814 bOk
= aCol
[i
].TestCopyScenarioTo( pDestTab
->aCol
[i
] );
818 void ScTable::PutCell( SCCOL nCol
, SCROW nRow
, ScBaseCell
* pCell
)
820 if (ValidColRow(nCol
,nRow
))
823 aCol
[nCol
].Insert( nRow
, pCell
);
825 aCol
[nCol
].Delete( nRow
);
830 void ScTable::PutCell( SCCOL nCol
, SCROW nRow
, ULONG nFormatIndex
, ScBaseCell
* pCell
)
832 if (ValidColRow(nCol
,nRow
))
835 aCol
[nCol
].Insert( nRow
, nFormatIndex
, pCell
);
837 aCol
[nCol
].Delete( nRow
);
842 void ScTable::PutCell( const ScAddress
& rPos
, ScBaseCell
* pCell
)
845 aCol
[rPos
.Col()].Insert( rPos
.Row(), pCell
);
847 aCol
[rPos
.Col()].Delete( rPos
.Row() );
851 //UNUSED2009-05 void ScTable::PutCell( const ScAddress& rPos, ULONG nFormatIndex, ScBaseCell* pCell )
853 //UNUSED2009-05 if (pCell)
854 //UNUSED2009-05 aCol[rPos.Col()].Insert( rPos.Row(), nFormatIndex, pCell );
856 //UNUSED2009-05 aCol[rPos.Col()].Delete( rPos.Row() );
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
);
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
);
887 void ScTable::GetInputString( SCCOL nCol
, SCROW nRow
, String
& rString
)
889 if (ValidColRow(nCol
,nRow
))
890 aCol
[nCol
].GetInputString( nRow
, rString
);
896 double ScTable::GetValue( SCCOL nCol
, SCROW nRow
)
898 if (ValidColRow( nCol
, nRow
))
899 return aCol
[nCol
].GetValue( nRow
);
904 void ScTable::GetFormula( SCCOL nCol
, SCROW nRow
, String
& rFormula
,
907 if (ValidColRow(nCol
,nRow
))
908 aCol
[nCol
].GetFormula( nRow
, rFormula
, bAsciiExport
);
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
) );
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");
978 void ScTable::GetFirstDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
982 while (aCol
[rCol
].IsEmptyData() && rCol
< MAXCOL
)
984 rRow
= aCol
[rCol
].GetFirstDataPos();
987 void ScTable::GetLastDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
991 while (aCol
[rCol
].IsEmptyData() && (rCol
> 0))
994 while ((SCsCOL
)nCol
>= 0)
996 rRow
= Max(rRow
, aCol
[nCol
].GetLastDataPos());
1002 BOOL
ScTable::HasData( SCCOL nCol
, SCROW nRow
)
1004 if (ValidColRow(nCol
,nRow
))
1005 return aCol
[nCol
].HasDataAt( nRow
);
1011 BOOL
ScTable::HasStringData( SCCOL nCol
, SCROW nRow
)
1013 if (ValidColRow(nCol
,nRow
))
1014 return aCol
[nCol
].HasStringData( nRow
);
1020 BOOL
ScTable::HasValueData( SCCOL nCol
, SCROW nRow
)
1022 if (ValidColRow(nCol
,nRow
))
1023 return aCol
[nCol
].HasValueData( nRow
);
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
))
1041 //UNUSED2008-05 USHORT ScTable::GetErrCode( SCCOL nCol, SCROW nRow ) const
1043 //UNUSED2008-05 if (ValidColRow( nCol, nRow ))
1044 //UNUSED2008-05 return aCol[nCol].GetErrCode( nRow );
1045 //UNUSED2008-05 return 0;
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
++)
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();
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
);
1158 const SfxPoolItem
* ScTable::GetAttr( SCCOL nCol
, SCROW nRow
, USHORT nWhich
) const
1160 if (ValidColRow(nCol
,nRow
))
1161 return aCol
[nCol
].GetAttr( nRow
, nWhich
);
1167 ULONG
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nRow
) const
1169 if (ValidColRow(nCol
,nRow
))
1170 return aCol
[nCol
].GetNumberFormat( nRow
);
1175 sal_uInt32
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
) const
1177 if (!ValidCol(nCol
) || !ValidRow(nStartRow
) || !ValidRow(nEndRow
))
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
);
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
);
1205 BOOL
ScTable::HasAttrib( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, USHORT nMask
) const
1208 for (SCCOL i
=nCol1
; i
<=nCol2
&& !bFound
; i
++)
1209 bFound
|= aCol
[i
].HasAttrib( nRow1
, nRow2
, nMask
);
1214 //UNUSED2009-05 BOOL ScTable::HasLines( const ScRange& rRange, Rectangle& rSizes ) const
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 );
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;
1228 //UNUSED2009-05 return bFound;
1232 BOOL
ScTable::HasAttribSelection( const ScMarkData
& rMark
, USHORT nMask
) const
1235 for (SCCOL i
=0; i
<=MAXCOL
&& !bFound
; i
++)
1236 bFound
|= aCol
[i
].HasAttribSelection( rMark
, nMask
);
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");
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
);
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");
1267 for (SCCOL i
=nCol1
; i
<=nCol2
&& bEmpty
; i
++)
1268 bEmpty
= aCol
[i
].IsEmptyBlock( nRow1
, nRow2
, bIgnoreNotes
);
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
)
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
1289 double nFactor
= 0.0;
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
);
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
;
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 )
1320 nWidth
+= GetColWidth( nTouchedCol
);
1322 if ( nTouchedCol
> nX2
)
1328 while ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
< nRow
)
1330 if ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
== nRow
)
1331 pRowInfo
[nArrY
].nRotMaxCol
= nCol
;
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" );
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
) )
1359 ScDocAttrIterator
aIter( pDocument
, nTab
, nCol
, nY1
, nCol
, nY2
);
1361 SCROW nAttrRow1
, nAttrRow2
;
1362 const ScPatternAttr
* pPattern
= aIter
.GetNext( nAttrCol
, nAttrRow1
, nAttrRow2
);
1365 const SfxPoolItem
* pCondItem
;
1366 if ( pPattern
->GetItemSet().GetItemState( ATTR_CONDITIONAL
, TRUE
, &pCondItem
)
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
);
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
);
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
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
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
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
1440 const USHORT n
= 2 | 8;
1441 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
1443 nEdges
= aCol
[i
].GetBlockMatrixEdges( nRow1
, nRow1
, n
);
1446 if ( (nEdges
& n
) != n
)
1447 return TRUE
; // obere oder untere Kante fehlt
1449 bOpen
= TRUE
; // linke Kante oeffnet, weitersehen
1451 return TRUE
; // es gibt was, was nicht geoeffnet wurde
1453 bOpen
= FALSE
; // rechte Kante schliesst
1457 return TRUE
; // es geht noch weiter
1463 // erst obere Zeile, dann untere Zeile
1464 for ( j
=0, nR
=nRow1
, n
=8; j
<2; j
++, nR
=nRow2
, n
=2 )
1467 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
1469 nEdges
= aCol
[i
].GetBlockMatrixEdges( nR
, nR
, n
);
1472 // in oberere Zeile keine obere Kante bzw.
1473 // in unterer Zeile keine untere Kante
1474 if ( (nEdges
& n
) != n
)
1477 bOpen
= TRUE
; // linke Kante oeffnet, weitersehen
1479 return TRUE
; // es gibt was, was nicht geoeffnet wurde
1481 bOpen
= FALSE
; // rechte Kante schliesst
1485 return TRUE
; // es geht noch weiter
1492 BOOL
ScTable::HasSelectionMatrixFragment( const ScMarkData
& rMark
) const
1495 for (SCCOL i
=0; i
<=MAXCOL
&& !bFound
; i
++)
1496 bFound
|= aCol
[i
].HasSelectionMatrixFragment(rMark
);
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
;
1512 BOOL bIsEditable
= TRUE
;
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
))
1530 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
1531 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
1538 else if (pDocument
->IsScenario(nTab
))
1540 // Determine if the preceding sheet is protected
1541 SCTAB nActualTab
= nTab
;
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
))
1554 pDocument
->GetScenarioFlags(nTab
,nFlags
);
1555 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
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
;
1576 BOOL
ScTable::IsSelectionEditable( const ScMarkData
& rMark
,
1577 BOOL
* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
1579 BOOL bIsEditable
= TRUE
;
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
))
1603 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
1604 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
1612 else if (pDocument
->IsScenario(nTab
))
1614 // Determine if the preceding sheet is protected
1615 SCTAB nActualTab
= nTab
;
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
))
1633 pDocument
->GetScenarioFlags(nTab
,nFlags
);
1634 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
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
;
1657 void ScTable::LockTable()
1663 void ScTable::UnlockTable()
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
)
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
);
1794 const ScStyleSheet
* ScTable::GetSelectionStyle( const ScMarkData
& rMark
, BOOL
& rFound
) const
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
);
1811 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
1812 bEqual
= FALSE
; // unterschiedliche
1817 return bEqual
? pStyle
: NULL
;
1821 const ScStyleSheet
* ScTable::GetAreaStyle( BOOL
& rFound
, SCCOL nCol1
, SCROW nRow1
,
1822 SCCOL nCol2
, SCROW nRow2
) const
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
);
1838 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
1839 bEqual
= FALSE
; // unterschiedliche
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
)
1866 void ScTable::StyleSheetChanged( const SfxStyleSheetBase
* pStyleSheet
, BOOL bRemoved
,
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
);
1876 while (nRow
<= MAXROW
)
1878 ScFlatBoolRowSegments::RangeData aData
;
1879 if (!aUsedRows
.getRangeData(nRow
, aData
))
1883 SCROW nEndRow
= aData
.mnRow2
;
1885 SetOptimalHeight(nRow
, nEndRow
, 0, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, FALSE
);
1892 BOOL
ScTable::ApplyFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
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
);
1903 BOOL
ScTable::RemoveFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
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
);
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
)
1958 // DBG_ERROR("Spaltenbreite 0 in SetColWidth");
1959 nNewWidth
= STD_COL_WIDTH
;
1962 if ( nNewWidth
!= pColWidth
[nCol
] )
1965 InitializeNoteCaptions();
1966 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
1968 pDrawLayer
->WidthChanged( nTab
, nCol
, ((long) nNewWidth
) - (long) pColWidth
[nCol
] );
1969 pColWidth
[nCol
] = nNewWidth
;
1976 DBG_ERROR("Falsche Spaltennummer oder keine Breiten");
1981 void ScTable::SetRowHeight( SCROW nRow
, USHORT nNewHeight
)
1983 if (VALIDROW(nRow
) && pRowHeight
)
1987 DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
1988 nNewHeight
= ScGlobal::nStdRowHeight
;
1991 USHORT nOldHeight
= pRowHeight
->GetValue(nRow
);
1992 if ( nNewHeight
!= nOldHeight
)
1995 InitializeNoteCaptions();
1996 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
1998 pDrawLayer
->HeightChanged( nTab
, nRow
, ((long) nNewHeight
) - (long) nOldHeight
);
1999 pRowHeight
->SetValue( nRow
, nNewHeight
);
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
)
2018 InitializeNoteCaptions();
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();
2030 if (pDrawLayer
->HasObjectsInRows( nTab
, nStartRow
, nEndRow
))
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
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. */
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
);
2069 pRowHeight
->SetValue( nStartRow
, nEndRow
, nNewHeight
);
2073 SCROW nMid
= (nStartRow
+nEndRow
) / 2;
2074 if (SetRowHeightRange( nStartRow
, nMid
, nNewHeight
, 1.0, 1.0 ))
2076 if (SetRowHeightRange( nMid
+1, nEndRow
, nNewHeight
, 1.0, 1.0 ))
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
);
2105 DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
2112 void ScTable::SetManualHeight( SCROW nStartRow
, SCROW nEndRow
, BOOL bManual
)
2114 if (VALIDROW(nStartRow
) && VALIDROW(nEndRow
) && pRowFlags
)
2117 pRowFlags
->OrValue( nStartRow
, nEndRow
, CR_MANUALSIZE
);
2119 pRowFlags
->AndValue( nStartRow
, nEndRow
, sal::static_int_cast
<BYTE
>(~CR_MANUALSIZE
));
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
)
2137 return pColWidth
[nCol
];
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
];
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");
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
) )
2173 if ( nRangeStart
<= nEndCol
)
2175 USHORT nThisCount
= 0;
2176 USHORT nThisWidth
= pColWidth
[nRangeStart
];
2177 USHORT nRangeEnd
= nRangeStart
;
2178 while ( nRangeEnd
<= nEndCol
&& pColWidth
[nRangeEnd
] == nThisWidth
)
2183 // skip hidden columns
2184 while ( nRangeEnd
<= nEndCol
&& (pColFlags
[nRangeEnd
] & CR_HIDDEN
) )
2188 if ( nThisCount
> nMaxCount
)
2190 nMaxCount
= nThisCount
;
2191 nMaxWidth
= nThisWidth
;
2194 nRangeStart
= nRangeEnd
; // next range
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
)
2211 return pRowHeight
->GetValue(nRow
);
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
);
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
);
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
);
2253 return (USHORT
) ScGlobal::nStdRowHeight
;
2257 // Spalten-/Zeilen-Flags
2260 SCROW
ScTable::GetHiddenRowCount( SCROW nRow
) const
2262 SCROW nEndRow
= nRow
;
2265 nEndRow
= pRowFlags
->GetBitStateEnd( nRow
, CR_HIDDEN
, CR_HIDDEN
);
2266 if (ValidRow(nEndRow
))
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
)
2285 InitializeNoteCaptions();
2286 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2290 pDrawLayer
->WidthChanged( nTab
, nCol
, (long) pColWidth
[nCol
] );
2292 pDrawLayer
->WidthChanged( nTab
, nCol
, -(long) pColWidth
[nCol
] );
2296 pColFlags
[nCol
] &= ~CR_HIDDEN
;
2298 pColFlags
[nCol
] |= CR_HIDDEN
;
2302 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
2304 pCharts
->SetRangeDirty(ScRange( nCol
, 0, nTab
, nCol
, MAXROW
, nTab
));
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
)
2323 InitializeNoteCaptions();
2324 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2328 pDrawLayer
->HeightChanged( nTab
, nRow
, (long) pRowHeight
->GetValue(nRow
) );
2330 pDrawLayer
->HeightChanged( nTab
, nRow
, -(long) pRowHeight
->GetValue(nRow
) );
2334 pRowFlags
->SetValue( nRow
, nFlags
& ~(CR_HIDDEN
| CR_FILTERED
));
2336 pRowFlags
->SetValue( nRow
, nFlags
| CR_HIDDEN
);
2340 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
2342 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
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;
2359 InitializeNoteCaptions();
2360 if (bWasVis
!= bShow
)
2362 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2366 pDrawLayer
->HeightChanged( nTab
, nRow
, (long) pRowHeight
->GetValue(nRow
) );
2368 pDrawLayer
->HeightChanged( nTab
, nRow
, -(long) pRowHeight
->GetValue(nRow
) );
2372 // Filter-Flag immer setzen, auch wenn Hidden unveraendert
2374 pRowFlags
->SetValue( nRow
, nFlags
& ~(CR_HIDDEN
| CR_FILTERED
));
2376 pRowFlags
->SetValue( nRow
, nFlags
| (CR_HIDDEN
| CR_FILTERED
));
2380 if (bWasVis
!= bShow
)
2382 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
2384 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
2387 UpdateOutlineRow( nRow
, nRow
, bShow
);
2392 DBG_ERROR("Falsche Zeilennummer oder keine Flags");
2397 void ScTable::DBShowRows(SCROW nRow1
, SCROW nRow2
, BOOL bShow
)
2399 SCROW nStartRow
= nRow1
;
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
)
2409 BOOL bWasVis
= ( nOldFlag
== 0 );
2410 BOOL bChanged
= ( bWasVis
!= bShow
);
2413 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2416 long nHeight
= (long) pRowHeight
->SumValues( nStartRow
, nEndRow
);
2418 pDrawLayer
->HeightChanged( nTab
, nStartRow
, nHeight
);
2420 pDrawLayer
->HeightChanged( nTab
, nStartRow
, -nHeight
);
2425 pRowFlags
->AndValue( nStartRow
, nEndRow
, sal::static_int_cast
<BYTE
>(~(CR_HIDDEN
| CR_FILTERED
)) );
2427 pRowFlags
->OrValue( nStartRow
, nEndRow
, (CR_HIDDEN
| CR_FILTERED
));
2431 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
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
2443 UpdateOutlineRow( nRow1
, nRow2
, bShow
);
2450 void ScTable::ShowRows(SCROW nRow1
, SCROW nRow2
, BOOL bShow
)
2452 SCROW nStartRow
= nRow1
;
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
)
2462 BOOL bWasVis
= ( nOldFlag
== 0 );
2463 BOOL bChanged
= ( bWasVis
!= bShow
);
2466 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2469 long nHeight
= (long) pRowHeight
->SumValues( nStartRow
, nEndRow
);
2471 pDrawLayer
->HeightChanged( nTab
, nStartRow
, nHeight
);
2473 pDrawLayer
->HeightChanged( nTab
, nStartRow
, -nHeight
);
2478 pRowFlags
->AndValue( nStartRow
, nEndRow
, sal::static_int_cast
<BYTE
>(~(CR_HIDDEN
| CR_FILTERED
)) );
2480 pRowFlags
->OrValue( nStartRow
, nEndRow
, CR_HIDDEN
);
2484 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
2486 pCharts
->SetRangeDirty(ScRange( 0, nStartRow
, nTab
, MAXCOL
, nEndRow
, nTab
));
2489 nStartRow
= nEndRow
+ 1;
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");
2506 void ScTable::SetColFlags( SCCOL nCol
, BYTE nNewFlags
)
2508 if (VALIDCOL(nCol
) && pColFlags
)
2509 pColFlags
[nCol
] = nNewFlags
;
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
);
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
);
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
];
2548 BYTE
ScTable::GetRowFlags( SCROW nRow
) const
2550 if (VALIDROW(nRow
) && pRowFlags
)
2551 return pRowFlags
->GetValue(nRow
);
2557 SCROW
ScTable::GetLastFlaggedRow() const
2562 SCROW nLastFound
= pRowFlags
->GetLastAnyBitAccess( 0, sal::static_int_cast
<BYTE
>(~CR_PAGEBREAK
) );
2563 return ValidRow(nLastFound
) ? nLastFound
: 0;
2567 SCCOL
ScTable::GetLastChangedCol() const
2572 SCCOL nLastFound
= 0;
2573 for (SCCOL nCol
= 1; nCol
<= MAXCOL
; nCol
++)
2574 if ((pColFlags
[nCol
] & ~CR_PAGEBREAK
) || (pColWidth
[nCol
] != STD_COL_WIDTH
))
2581 SCROW
ScTable::GetLastChangedRow() const
2586 SCROW nLastFlags
= pRowFlags
->GetLastAnyBitAccess( 0, sal::static_int_cast
<BYTE
>(~CR_PAGEBREAK
) );
2587 if (!ValidRow(nLastFlags
))
2590 SCROW nLastHeight
= pRowHeight
->GetLastUnequalAccess( 0, ScGlobal::nStdRowHeight
);
2591 if (!ValidRow(nLastHeight
))
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
);
2610 BOOL
ScTable::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, BOOL bShow
)
2612 if (pOutlineTable
&& pRowFlags
)
2613 return pOutlineTable
->GetRowArray()->ManualAction( nStartRow
, nEndRow
, bShow
, *pRowFlags
);
2619 void ScTable::ExtendHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
2623 while ( rX1
>0 ? (pColFlags
[rX1
-1] & CR_HIDDEN
) : FALSE
)
2625 while ( rX2
<MAXCOL
? (pColFlags
[rX2
+1] & CR_HIDDEN
) : FALSE
)
2632 SCROW nStartRow
= pRowFlags
->GetBitStateStart( rY1
-1, CR_HIDDEN
, CR_HIDDEN
);
2633 if (ValidRow(nStartRow
))
2638 SCROW nEndRow
= pRowFlags
->GetBitStateEnd( rY2
+1, CR_HIDDEN
, CR_HIDDEN
);
2639 if (ValidRow(nEndRow
))
2646 void ScTable::StripHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
2650 while ( rX2
>rX1
&& (pColFlags
[rX2
] & CR_HIDDEN
) )
2652 while ( rX2
>rX1
&& (pColFlags
[rX1
] & CR_HIDDEN
) )
2659 SCROW nStartRow
= pRowFlags
->GetBitStateStart( rY2
, CR_HIDDEN
, CR_HIDDEN
);
2660 if (ValidRow(nStartRow
) && nStartRow
>= rY1
)
2665 SCROW nEndRow
= pRowFlags
->GetBitStateEnd( rY1
, CR_HIDDEN
, CR_HIDDEN
);
2666 if (ValidRow(nEndRow
) && nEndRow
<= rY2
)
2675 template< typename T
>
2676 short DiffSign( T a
, T b
)
2683 void ScTable::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
)
2685 BOOL bSizeChanged
= FALSE
;
2686 BOOL bMissed
= FALSE
;
2692 ScOutlineArray
* pArray
;
2695 /* ScPatternAttr aBoldPattern( pDocument->GetPool() ); //! spezielle Format-Vorlage
2696 aBoldPattern.GetItemSet().Put( SvxWeightItem( WEIGHT_BOLD ) );
2699 StartOutlineTable();
2703 SCROW nCount
= nEndRow
-nStartRow
+1;
2704 BOOL
* pUsed
= new BOOL
[nCount
];
2705 for (i
=0; i
<nCount
; i
++)
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
])
2716 for (nCol
=nStartCol
; nCol
<=nEndCol
&& !bFound
; nCol
++)
2717 if (!aCol
[nCol
].IsEmptyData())
2719 pCell
= aCol
[nCol
].GetCell( nRow
);
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 );
2743 pArray
= pOutlineTable
->GetColArray();
2744 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
2746 if (!aCol
[nCol
].IsEmptyData())
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 );
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
);
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
;
2808 PutCell( nDestX
, nDestY
, pCell
);
2809 SetPattern( nDestX
, nDestY
, *GetPattern( nCol
, nRow
), TRUE
);
2813 pDocument
->PutCell( aDest
, pCell
);
2814 pDocument
->SetPattern( aDest
, *GetPattern( nCol
, nRow
), TRUE
);
2824 BOOL
ScTable::RefVisible(ScFormulaCell
* pCell
)
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();
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
2871 pDrawLayer
->SetPageSize( static_cast<sal_uInt16
>(nTab
), Size( x
, y
) );
2876 ULONG
ScTable::GetRowOffset( SCROW nRow
) const
2879 if ( pRowFlags
&& pRowHeight
)
2884 return GetRowHeight(0);
2886 n
= pRowFlags
->SumCoupledArrayForCondition( 0, nRow
-1, CR_HIDDEN
, 0,
2889 if (n
== ::std::numeric_limits
<unsigned long>::max())
2890 DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow");
2895 DBG_ERROR("GetRowOffset: Daten fehlen");
2901 ULONG
ScTable::GetColOffset( SCCOL nCol
) const
2904 if ( pColFlags
&& pColWidth
)
2907 BYTE
* pFlags
= pColFlags
;
2908 USHORT
* pWidth
= pColWidth
;
2909 for( i
= 0; i
< nCol
; i
++, pFlags
++, pWidth
++ )
2910 if( !( *pFlags
& CR_HIDDEN
) )
2915 DBG_ERROR("GetColumnOffset: Daten fehlen");