1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "patattr.hxx"
22 #include "docpool.hxx"
23 #include "formulacell.hxx"
24 #include "document.hxx"
25 #include "drwlayer.hxx"
26 #include "olinetab.hxx"
27 #include "rechead.hxx"
28 #include "stlpool.hxx"
29 #include "attarray.hxx"
30 #include "markdata.hxx"
31 #include "progress.hxx"
32 #include "dociter.hxx"
33 #include "conditio.hxx"
34 #include "chartlis.hxx"
35 #include "fillinfo.hxx"
36 #include "bcaslot.hxx"
38 #include "sheetevents.hxx"
39 #include "globstr.hrc"
40 #include "segmenttree.hxx"
41 #include "queryparam.hxx"
42 #include "queryentry.hxx"
44 #include "colorscale.hxx"
45 #include "tokenarray.hxx"
46 #include "clipcontext.hxx"
48 #include "editutil.hxx"
49 #include "mtvcellfunc.hxx"
50 #include "refupdatecontext.hxx"
51 #include "scopetools.hxx"
53 #include "scitems.hxx"
54 #include <editeng/boxitem.hxx>
55 #include "editeng/editobj.hxx"
56 #include <svl/poolcach.hxx>
57 #include <unotools/charclass.hxx>
59 #include <svl/PasswordHelper.hxx>
60 #include <unotools/transliterationwrapper.hxx>
64 class ColumnRegroupFormulaCells
68 ColumnRegroupFormulaCells(ScColumn
* pCols
) : mpCols(pCols
) {}
70 void operator() (SCCOL nCol
)
72 mpCols
[nCol
].RegroupFormulaCells();
78 sal_uInt16
ScTable::GetTextWidth(SCCOL nCol
, SCROW nRow
) const
80 return aCol
[nCol
].GetTextWidth(nRow
);
83 bool ScTable::SetOutlineTable( const ScOutlineTable
* pNewOutline
)
85 sal_uInt16 nOldSizeX
= 0;
86 sal_uInt16 nOldSizeY
= 0;
87 sal_uInt16 nNewSizeX
= 0;
88 sal_uInt16 nNewSizeY
= 0;
92 nOldSizeX
= pOutlineTable
->GetColArray()->GetDepth();
93 nOldSizeY
= pOutlineTable
->GetRowArray()->GetDepth();
99 pOutlineTable
= new ScOutlineTable( *pNewOutline
);
100 nNewSizeX
= pOutlineTable
->GetColArray()->GetDepth();
101 nNewSizeY
= pOutlineTable
->GetRowArray()->GetDepth();
104 pOutlineTable
= NULL
;
106 return ( nNewSizeX
!= nOldSizeX
|| nNewSizeY
!= nOldSizeY
); // Groesse geaendert ?
110 void ScTable::StartOutlineTable()
113 pOutlineTable
= new ScOutlineTable
;
117 void ScTable::SetSheetEvents( const ScSheetEvents
* pNew
)
121 pSheetEvents
= new ScSheetEvents(*pNew
);
125 SetCalcNotification( false ); // discard notifications before the events were set
128 SetStreamValid(false);
132 void ScTable::SetCalcNotification( bool bSet
)
134 bCalcNotification
= bSet
;
138 bool ScTable::TestInsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
) const
142 if ( nStartCol
==0 && nEndCol
==MAXCOL
&& pOutlineTable
)
143 bTest
= pOutlineTable
->TestInsertRow(nSize
);
145 for (SCCOL i
=nStartCol
; (i
<=nEndCol
) && bTest
; i
++)
146 bTest
= aCol
[i
].TestInsertRow(nStartRow
, nSize
);
152 void ScTable::InsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
)
154 if (nStartCol
==0 && nEndCol
==MAXCOL
)
156 if (mpRowHeights
&& pRowFlags
)
158 mpRowHeights
->insertSegment(nStartRow
, nSize
, false);
159 sal_uInt8 nNewFlags
= pRowFlags
->Insert( nStartRow
, nSize
);
160 // only copy manual size flag, clear all others
161 if (nNewFlags
&& (nNewFlags
!= CR_MANUALSIZE
))
162 pRowFlags
->SetValue( nStartRow
, nStartRow
+ nSize
- 1,
163 nNewFlags
& CR_MANUALSIZE
);
167 pOutlineTable
->InsertRow( nStartRow
, nSize
);
169 mpFilteredRows
->insertSegment(nStartRow
, nSize
, true);
170 mpHiddenRows
->insertSegment(nStartRow
, nSize
, true);
172 if (!maRowManualBreaks
.empty())
174 // Copy all breaks up to nStartRow (non-inclusive).
175 ::std::set
<SCROW
>::iterator itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
176 ::std::set
<SCROW
> aNewBreaks(maRowManualBreaks
.begin(), itr1
);
178 // Copy all breaks from nStartRow (inclusive) to the last element,
179 // but add nSize to each value.
180 ::std::set
<SCROW
>::iterator itr2
= maRowManualBreaks
.end();
181 for (; itr1
!= itr2
; ++itr1
)
182 aNewBreaks
.insert(static_cast<SCROW
>(*itr1
+ nSize
));
184 maRowManualBreaks
.swap(aNewBreaks
);
188 for (SCCOL j
=nStartCol
; j
<=nEndCol
; j
++)
189 aCol
[j
].InsertRow( nStartRow
, nSize
);
191 mpCondFormatList
->InsertRow(nTab
, nStartCol
, nEndCol
, nStartRow
, nSize
);
193 InvalidatePageBreaks();
196 // TODO: In the future we may want to check if the table has been
197 // really modified before setting the stream invalid.
198 SetStreamValid(false);
202 void ScTable::DeleteRow(
203 const sc::ColumnSet
& rRegroupCols
, SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
,
206 if (nStartCol
==0 && nEndCol
==MAXCOL
)
209 pRowFlags
->Remove( nStartRow
, nSize
);
212 mpRowHeights
->removeSegment(nStartRow
, nStartRow
+nSize
);
215 if (pOutlineTable
->DeleteRow( nStartRow
, nSize
))
217 *pUndoOutline
= true;
219 mpFilteredRows
->removeSegment(nStartRow
, nStartRow
+nSize
);
220 mpHiddenRows
->removeSegment(nStartRow
, nStartRow
+nSize
);
222 if (!maRowManualBreaks
.empty())
224 // Erase all manual breaks between nStartRow and nStartRow + nSize - 1 (inclusive).
225 std::set
<SCROW
>::iterator itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
226 std::set
<SCROW
>::iterator itr2
= maRowManualBreaks
.upper_bound(static_cast<SCROW
>(nStartRow
+ nSize
- 1));
227 maRowManualBreaks
.erase(itr1
, itr2
);
229 // Copy all breaks from the 1st element up to nStartRow to the new container.
230 itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
231 ::std::set
<SCROW
> aNewBreaks(maRowManualBreaks
.begin(), itr1
);
233 // Copy all breaks from nStartRow to the last element, but subtract each value by nSize.
234 itr2
= maRowManualBreaks
.end();
235 for (; itr1
!= itr2
; ++itr1
)
236 aNewBreaks
.insert(static_cast<SCROW
>(*itr1
- nSize
));
238 maRowManualBreaks
.swap(aNewBreaks
);
242 { // scope for bulk broadcast
243 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
244 for (SCCOL j
=nStartCol
; j
<=nEndCol
; j
++)
245 aCol
[j
].DeleteRow( nStartRow
, nSize
);
248 std::vector
<SCCOL
> aRegroupCols
;
249 rRegroupCols
.getColumns(nTab
, aRegroupCols
);
250 std::for_each(aRegroupCols
.begin(), aRegroupCols
.end(), ColumnRegroupFormulaCells(aCol
));
252 InvalidatePageBreaks();
255 // TODO: In the future we may want to check if the table has been
256 // really modified before setting the stream invalid.
257 SetStreamValid(false);
261 bool ScTable::TestInsertCol( SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
) const
265 if ( nStartRow
==0 && nEndRow
==MAXROW
&& pOutlineTable
)
266 bTest
= pOutlineTable
->TestInsertCol(nSize
);
268 if ( nSize
> static_cast<SCSIZE
>(MAXCOL
) )
271 for (SCCOL i
=MAXCOL
; (i
+static_cast<SCCOL
>(nSize
)>MAXCOL
) && bTest
; i
--)
272 bTest
= aCol
[i
].TestInsertCol(nStartRow
, nEndRow
);
278 void ScTable::InsertCol(
279 const sc::ColumnSet
& rRegroupCols
, SCCOL nStartCol
, SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
)
281 if (nStartRow
==0 && nEndRow
==MAXROW
)
283 if (pColWidth
&& pColFlags
)
285 memmove( &pColWidth
[nStartCol
+nSize
], &pColWidth
[nStartCol
],
286 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColWidth
[0]) );
287 memmove( &pColFlags
[nStartCol
+nSize
], &pColFlags
[nStartCol
],
288 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColFlags
[0]) );
291 pOutlineTable
->InsertCol( nStartCol
, nSize
);
293 mpHiddenCols
->insertSegment(nStartCol
, static_cast<SCCOL
>(nSize
), true);
294 mpFilteredCols
->insertSegment(nStartCol
, static_cast<SCCOL
>(nSize
), true);
296 if (!maColManualBreaks
.empty())
298 std::set
<SCCOL
>::reverse_iterator rit
= maColManualBreaks
.rbegin();
299 while (rit
!= maColManualBreaks
.rend())
302 if (nCol
< nStartCol
)
306 maColManualBreaks
.erase( (++rit
).base());
307 maColManualBreaks
.insert( static_cast<SCCOL
>( nCol
+ nSize
));
314 if ((nStartRow
== 0) && (nEndRow
== MAXROW
))
316 for (SCSIZE i
=0; i
< nSize
; i
++)
317 for (SCCOL nCol
= MAXCOL
; nCol
> nStartCol
; nCol
--)
318 aCol
[nCol
].SwapCol(aCol
[nCol
-1]);
322 for (SCSIZE i
=0; static_cast<SCCOL
>(i
+nSize
)+nStartCol
<= MAXCOL
; i
++)
323 aCol
[MAXCOL
- nSize
- i
].MoveTo(nStartRow
, nEndRow
, aCol
[MAXCOL
- i
]);
326 std::vector
<SCCOL
> aRegroupCols
;
327 rRegroupCols
.getColumns(nTab
, aRegroupCols
);
328 std::for_each(aRegroupCols
.begin(), aRegroupCols
.end(), ColumnRegroupFormulaCells(aCol
));
330 if (nStartCol
>0) // copy old attributes
332 sal_uInt16 nWhichArray
[2];
333 nWhichArray
[0] = ATTR_MERGE
;
336 sc::CopyToDocContext
aCxt(*pDocument
);
337 for (SCSIZE i
=0; i
<nSize
; i
++)
339 aCol
[nStartCol
-1].CopyToColumn(aCxt
, nStartRow
, nEndRow
, IDF_ATTRIB
,
340 false, aCol
[nStartCol
+i
] );
341 aCol
[nStartCol
+i
].RemoveFlags( nStartRow
, nEndRow
,
342 SC_MF_HOR
| SC_MF_VER
| SC_MF_AUTO
);
343 aCol
[nStartCol
+i
].ClearItems( nStartRow
, nEndRow
, nWhichArray
);
347 mpCondFormatList
->InsertCol(nTab
, nStartRow
, nEndRow
, nStartCol
, nSize
);
349 InvalidatePageBreaks();
352 // TODO: In the future we may want to check if the table has been
353 // really modified before setting the stream invalid.
354 SetStreamValid(false);
357 void ScTable::DeleteCol(
358 const sc::ColumnSet
& rRegroupCols
, SCCOL nStartCol
, SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
, bool* pUndoOutline
)
360 if (nStartRow
==0 && nEndRow
==MAXROW
)
362 if (pColWidth
&& pColFlags
)
364 memmove( &pColWidth
[nStartCol
], &pColWidth
[nStartCol
+nSize
],
365 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColWidth
[0]) );
366 memmove( &pColFlags
[nStartCol
], &pColFlags
[nStartCol
+nSize
],
367 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColFlags
[0]) );
370 if (pOutlineTable
->DeleteCol( nStartCol
, nSize
))
372 *pUndoOutline
= true;
374 SCCOL nRmSize
= nStartCol
+ static_cast<SCCOL
>(nSize
);
375 mpHiddenCols
->removeSegment(nStartCol
, nRmSize
);
376 mpFilteredCols
->removeSegment(nStartCol
, nRmSize
);
378 if (!maColManualBreaks
.empty())
380 std::set
<SCCOL
>::iterator it
= maColManualBreaks
.upper_bound( static_cast<SCCOL
>( nStartCol
+ nSize
- 1));
381 maColManualBreaks
.erase( maColManualBreaks
.lower_bound( nStartCol
), it
);
382 while (it
!= maColManualBreaks
.end())
385 maColManualBreaks
.erase( it
++);
386 maColManualBreaks
.insert( static_cast<SCCOL
>( nCol
- nSize
));
391 { // scope for bulk broadcast
392 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
393 for (SCSIZE i
= 0; i
< nSize
; i
++)
394 aCol
[nStartCol
+ i
].DeleteArea(nStartRow
, nEndRow
, IDF_ALL
);
397 if ((nStartRow
== 0) && (nEndRow
== MAXROW
))
399 for (SCSIZE i
=0; i
< nSize
; i
++)
400 for (SCCOL nCol
= nStartCol
; nCol
< MAXCOL
; nCol
++)
401 aCol
[nCol
].SwapCol(aCol
[nCol
+1]);
405 for (SCSIZE i
=0; static_cast<SCCOL
>(i
+nSize
)+nStartCol
<= MAXCOL
; i
++)
406 aCol
[nStartCol
+ nSize
+ i
].MoveTo(nStartRow
, nEndRow
, aCol
[nStartCol
+ i
]);
409 std::vector
<SCCOL
> aRegroupCols
;
410 rRegroupCols
.getColumns(nTab
, aRegroupCols
);
411 std::for_each(aRegroupCols
.begin(), aRegroupCols
.end(), ColumnRegroupFormulaCells(aCol
));
413 InvalidatePageBreaks();
416 // TODO: In the future we may want to check if the table has been
417 // really modified before setting the stream invalid.
418 SetStreamValid(false);
422 void ScTable::DeleteArea(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, sal_uInt16 nDelFlag
)
424 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
425 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
426 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
428 { // scope for bulk broadcast
429 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
430 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
431 aCol
[i
].DeleteArea(nRow1
, nRow2
, nDelFlag
);
435 // Zellschutz auf geschuetzter Tabelle nicht setzen
438 if ( IsProtected() && (nDelFlag
& IDF_ATTRIB
) )
440 ScPatternAttr
aPattern(pDocument
->GetPool());
441 aPattern
.GetItemSet().Put( ScProtectionAttr( false ) );
442 ApplyPatternArea( nCol1
, nRow1
, nCol2
, nRow2
, aPattern
);
445 if( nDelFlag
& IDF_ATTRIB
)
446 mpCondFormatList
->DeleteArea( nCol1
, nRow1
, nCol2
, nRow2
);
450 // TODO: In the future we may want to check if the table has been
451 // really modified before setting the stream invalid.
452 SetStreamValid(false);
456 void ScTable::DeleteSelection( sal_uInt16 nDelFlag
, const ScMarkData
& rMark
)
458 { // scope for bulk broadcast
459 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
460 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
461 aCol
[i
].DeleteSelection( nDelFlag
, rMark
);
464 ScRangeList aRangeList
;
465 rMark
.FillRangeListWithMarks(&aRangeList
, false);
467 for (size_t i
= 0; i
< aRangeList
.size(); ++i
)
469 ScRange
* pRange
= aRangeList
[i
];
471 if((nDelFlag
& IDF_ATTRIB
) && pRange
&& pRange
->aStart
.Tab() == nTab
)
472 mpCondFormatList
->DeleteArea( pRange
->aStart
.Col(), pRange
->aStart
.Row(), pRange
->aEnd
.Col(), pRange
->aEnd
.Row() );
476 // Zellschutz auf geschuetzter Tabelle nicht setzen
479 if ( IsProtected() && (nDelFlag
& IDF_ATTRIB
) )
481 ScDocumentPool
* pPool
= pDocument
->GetPool();
482 SfxItemSet
aSet( *pPool
, ATTR_PATTERN_START
, ATTR_PATTERN_END
);
483 aSet
.Put( ScProtectionAttr( false ) );
484 SfxItemPoolCache
aCache( pPool
, &aSet
);
485 ApplySelectionCache( &aCache
, rMark
);
489 // TODO: In the future we may want to check if the table has been
490 // really modified before setting the stream invalid.
491 SetStreamValid(false);
495 // pTable = Clipboard
496 void ScTable::CopyToClip(
497 sc::CopyToClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
500 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
503 //local range names need to be copied first for formula cells
504 if (!pTable
->mpRangeName
&& mpRangeName
)
505 pTable
->mpRangeName
= new ScRangeName(*mpRangeName
);
509 for ( i
= nCol1
; i
<= nCol2
; i
++)
510 aCol
[i
].CopyToClip(rCxt
, nRow1
, nRow2
, pTable
->aCol
[i
]); // notes are handled at column level
512 // copy widths/heights, and only "hidden", "filtered" and "manual" flags
513 // also for all preceding columns/rows, to have valid positions for drawing objects
515 if (pColWidth
&& pTable
->pColWidth
)
516 for (i
=0; i
<=nCol2
; i
++)
517 pTable
->pColWidth
[i
] = pColWidth
[i
];
519 pTable
->CopyColHidden(*this, 0, nCol2
);
520 pTable
->CopyColFiltered(*this, 0, nCol2
);
522 pTable
->SetAnonymousDBData(new ScDBData(*pDBDataNoName
));
525 if (pRowFlags
&& pTable
->pRowFlags
&& mpRowHeights
&& pTable
->mpRowHeights
)
527 pTable
->pRowFlags
->CopyFromAnded( *pRowFlags
, 0, nRow2
, CR_MANUALSIZE
);
528 pTable
->CopyRowHeight(*this, 0, nRow2
, 0);
531 pTable
->CopyRowHidden(*this, 0, nRow2
);
532 pTable
->CopyRowFiltered(*this, 0, nRow2
);
534 // ggf. Formeln durch Werte ersetzen
537 for (i
= nCol1
; i
<= nCol2
; i
++)
538 pTable
->aCol
[i
].RemoveProtected(nRow1
, nRow2
);
540 pTable
->mpCondFormatList
.reset(new ScConditionalFormatList(pTable
->pDocument
, *mpCondFormatList
));
544 void ScTable::CopyToClip(
545 sc::CopyToClipContext
& rCxt
, const ScRangeList
& rRanges
, ScTable
* pTable
)
547 ScRangeList
aRanges(rRanges
);
548 for ( size_t i
= 0, nListSize
= aRanges
.size(); i
< nListSize
; ++i
)
550 ScRange
* p
= aRanges
[ i
];
552 rCxt
, p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), pTable
);
556 void ScTable::CopyStaticToDocument(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, ScTable
* pDestTab
)
561 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
563 ScColumn
& rSrcCol
= aCol
[i
];
564 ScColumn
& rDestCol
= pDestTab
->aCol
[i
];
565 rSrcCol
.CopyStaticToDocument(nRow1
, nRow2
, rDestCol
);
569 void ScTable::CopyCellToDocument(SCCOL nSrcCol
, SCROW nSrcRow
, SCCOL nDestCol
, SCROW nDestRow
, ScTable
& rDestTab
)
571 if (!ValidColRow(nSrcCol
, nSrcRow
) || !ValidColRow(nDestCol
, nDestRow
))
574 ScColumn
& rSrcCol
= aCol
[nSrcCol
];
575 ScColumn
& rDestCol
= rDestTab
.aCol
[nDestCol
];
576 rSrcCol
.CopyCellToDocument(nSrcRow
, nDestRow
, rDestCol
);
579 void ScTable::CopyConditionalFormat( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
580 SCsCOL nDx
, SCsROW nDy
, ScTable
* pTable
)
582 ScRange
aOldRange( nCol1
- nDx
, nRow1
- nDy
, pTable
->nTab
, nCol2
- nDx
, nRow2
- nDy
, pTable
->nTab
);
583 ScRange
aNewRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
584 bool bSameDoc
= pDocument
== pTable
->pDocument
;
586 for(ScConditionalFormatList::const_iterator itr
= pTable
->mpCondFormatList
->begin(),
587 itrEnd
= pTable
->mpCondFormatList
->end(); itr
!= itrEnd
; ++itr
)
589 const ScRangeList
& rCondFormatRange
= itr
->GetRange();
590 if(!rCondFormatRange
.Intersects( aOldRange
))
593 ScRangeList aIntersectedRange
= rCondFormatRange
.GetIntersectedRange(aOldRange
);
594 ScConditionalFormat
* pNewFormat
= itr
->Clone(pDocument
);
596 pNewFormat
->AddRange(aIntersectedRange
);
597 sc::RefUpdateContext
aRefCxt(*pDocument
);
598 aRefCxt
.meMode
= URM_COPY
;
599 aRefCxt
.maRange
= aNewRange
;
600 aRefCxt
.mnColDelta
= nDx
;
601 aRefCxt
.mnRowDelta
= nDy
;
602 aRefCxt
.mnTabDelta
= nTab
- pTable
->nTab
;
603 pNewFormat
->UpdateReference(aRefCxt
, true);
606 for(ScConditionalFormatList::const_iterator itrCond
= mpCondFormatList
->begin();
607 itrCond
!= mpCondFormatList
->end(); ++itrCond
)
609 if(itrCond
->GetKey() > nMax
)
610 nMax
= itrCond
->GetKey();
612 pNewFormat
->SetKey(nMax
+ 1);
613 mpCondFormatList
->InsertNew(pNewFormat
);
617 for(size_t i
= 0, n
= pNewFormat
->size();
621 const ScFormatEntry
* pEntry
= pNewFormat
->GetEntry(i
);
622 if(pEntry
->GetType() == condformat::CONDITION
)
623 aStyleName
= static_cast<const ScCondFormatEntry
*>(pEntry
)->GetStyle();
624 else if(pEntry
->GetType() == condformat::DATE
)
625 aStyleName
= static_cast<const ScCondDateFormatEntry
*>(pEntry
)->GetStyleName();
627 if(!aStyleName
.isEmpty())
629 if(pDocument
->GetStyleSheetPool()->Find(aStyleName
, SFX_STYLE_FAMILY_PARA
))
632 pDocument
->GetStyleSheetPool()->CopyStyleFrom(
633 pTable
->pDocument
->GetStyleSheetPool(), aStyleName
, SFX_STYLE_FAMILY_PARA
);
638 pDocument
->AddCondFormatData( pNewFormat
->GetRange(), nTab
, pNewFormat
->GetKey() );
642 bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition
& rBlockPos
, SCCOL nCol
)
647 return aCol
[nCol
].InitBlockPosition(rBlockPos
);
650 void ScTable::CopyFromClip(
651 sc::CopyFromClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
652 SCsCOL nDx
, SCsROW nDy
, ScTable
* pTable
)
660 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
662 for ( SCCOL i
= nCol1
; i
<= nCol2
; i
++)
663 aCol
[i
].CopyFromClip(rCxt
, nRow1
, nRow2
, nDy
, pTable
->aCol
[i
- nDx
]); // notes are handles at column level
665 if (rCxt
.getInsertFlag() & IDF_ATTRIB
)
667 // make sure that there are no old references to the cond formats
668 sal_uInt16 nWhichArray
[2];
669 nWhichArray
[0] = ATTR_CONDITIONAL
;
671 for ( SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
672 aCol
[i
].ClearItems(nRow1
, nRow2
, nWhichArray
);
675 if ((rCxt
.getInsertFlag() & IDF_ATTRIB
) != 0)
677 if (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pTable
->pColWidth
)
678 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
679 pColWidth
[i
] = pTable
->pColWidth
[i
-nDx
];
681 if (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pTable
->mpRowHeights
&&
682 pRowFlags
&& pTable
->pRowFlags
)
684 CopyRowHeight(*pTable
, nRow1
, nRow2
, -nDy
);
685 // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
686 for (SCROW j
=nRow1
; j
<=nRow2
; j
++)
688 if ( pTable
->pRowFlags
->GetValue(j
-nDy
) & CR_MANUALSIZE
)
689 pRowFlags
->OrValue( j
, CR_MANUALSIZE
);
691 pRowFlags
->AndValue( j
, sal::static_int_cast
<sal_uInt8
>(~CR_MANUALSIZE
));
695 // Zellschutz auf geschuetzter Tabelle nicht setzen
696 if (IsProtected() && (rCxt
.getInsertFlag() & IDF_ATTRIB
))
698 ScPatternAttr
aPattern(pDocument
->GetPool());
699 aPattern
.GetItemSet().Put( ScProtectionAttr( false ) );
700 ApplyPatternArea( nCol1
, nRow1
, nCol2
, nRow2
, aPattern
);
703 // create deep copies for conditional formatting
704 CopyConditionalFormat( nCol1
, nRow1
, nCol2
, nRow2
, nDx
, nDy
, pTable
);
710 void ScTable::MixData(
711 sc::MixDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
712 sal_uInt16 nFunction
, bool bSkipEmpty
, const ScTable
* pSrcTab
)
714 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
715 aCol
[i
].MixData(rCxt
, nRow1
, nRow2
, nFunction
, bSkipEmpty
, pSrcTab
->aCol
[i
]);
719 // Markierung von diesem Dokument
720 void ScTable::MixMarked(
721 sc::MixDocContext
& rCxt
, const ScMarkData
& rMark
, sal_uInt16 nFunction
,
722 bool bSkipEmpty
, const ScTable
* pSrcTab
)
724 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
725 aCol
[i
].MixMarked(rCxt
, rMark
, nFunction
, bSkipEmpty
, pSrcTab
->aCol
[i
]);
730 class TransClipHandler
740 ScAddress
getDestPos(size_t nRow
) const
742 return ScAddress(static_cast<SCCOL
>(nRow
-mnTopRow
), mnTransRow
, mrClipTab
.GetTab());
745 ScFormulaCell
* createRefCell(size_t nSrcRow
, const ScAddress
& rDestPos
) const
747 ScAddress
aSrcPos(mnSrcCol
, nSrcRow
, mnSrcTab
);
748 ScSingleRefData aRef
;
749 aRef
.InitAddress(aSrcPos
); // Absolute reference.
750 aRef
.SetFlag3D(true);
753 aArr
.AddSingleReference(aRef
);
754 return new ScFormulaCell(&mrClipTab
.GetDoc(), rDestPos
, aArr
);
757 void setLink(size_t nRow
)
759 SCCOL nTransCol
= nRow
- mnTopRow
;
760 mrClipTab
.SetFormulaCell(
761 nTransCol
, mnTransRow
, createRefCell(nRow
, getDestPos(nRow
)));
765 TransClipHandler(ScTable
& rClipTab
, SCTAB nSrcTab
, SCCOL nSrcCol
, size_t nTopRow
, SCROW nTransRow
, bool bAsLink
, bool bWasCut
) :
766 mrClipTab(rClipTab
), mnSrcTab(nSrcTab
), mnSrcCol(nSrcCol
),
767 mnTopRow(nTopRow
), mnTransRow(nTransRow
), mbAsLink(bAsLink
), mbWasCut(bWasCut
) {}
769 void operator() (size_t nRow
, double fVal
)
777 SCCOL nTransCol
= nRow
- mnTopRow
;
778 mrClipTab
.SetValue(nTransCol
, mnTransRow
, fVal
);
781 void operator() (size_t nRow
, const svl::SharedString
& rStr
)
789 SCCOL nTransCol
= nRow
- mnTopRow
;
790 mrClipTab
.SetRawString(nTransCol
, mnTransRow
, rStr
);
793 void operator() (size_t nRow
, const EditTextObject
* p
)
801 SCCOL nTransCol
= nRow
- mnTopRow
;
802 mrClipTab
.SetEditText(nTransCol
, mnTransRow
, ScEditUtil::Clone(*p
, mrClipTab
.GetDoc()));
805 void operator() (size_t nRow
, const ScFormulaCell
* p
)
813 ScFormulaCell
* pNew
= new ScFormulaCell(
814 *p
, mrClipTab
.GetDoc(), getDestPos(nRow
), SC_CLONECELL_STARTLISTENING
);
817 // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
820 pNew
->TransposeReference();
822 SCCOL nTransCol
= nRow
- mnTopRow
;
823 mrClipTab
.SetFormulaCell(nTransCol
, mnTransRow
, pNew
);
829 void ScTable::TransposeClip( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
830 ScTable
* pTransClip
, sal_uInt16 nFlags
, bool bAsLink
)
832 bool bWasCut
= pDocument
->IsCutMode();
834 ScDocument
* pDestDoc
= pTransClip
->pDocument
;
836 for (SCCOL nCol
=nCol1
; nCol
<=nCol2
; nCol
++)
839 if ( bAsLink
&& nFlags
== IDF_ALL
)
841 // with IDF_ALL, also create links (formulas) for empty cells
843 for ( nRow
=nRow1
; nRow
<=nRow2
; nRow
++ )
845 // create simple formula, as in ScColumn::CreateRefCell
847 ScAddress
aDestPos( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
848 ScSingleRefData aRef
;
849 aRef
.InitAddress(ScAddress(nCol
,nRow
,nTab
));
850 aRef
.SetFlag3D(true);
852 aArr
.AddSingleReference( aRef
);
854 pTransClip
->SetFormulaCell(
855 static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
),
856 new ScFormulaCell(pDestDoc
, aDestPos
, aArr
));
861 TransClipHandler
aFunc(*pTransClip
, nTab
, nCol
, nRow1
, static_cast<SCROW
>(nCol
-nCol1
), bAsLink
, bWasCut
);
862 const sc::CellStoreType
& rCells
= aCol
[nCol
].maCells
;
863 sc::ParseAllNonEmpty(rCells
.begin(), rCells
, nRow1
, nRow2
, aFunc
);
870 const ScPatternAttr
* pPattern
;
871 boost::scoped_ptr
<ScAttrIterator
> pAttrIter(aCol
[nCol
].CreateAttrIterator( nRow1
, nRow2
));
872 while ( (pPattern
= pAttrIter
->Next( nAttrRow1
, nAttrRow2
)) != 0 )
874 if ( !IsDefaultItem( pPattern
) )
876 const SfxItemSet
& rSet
= pPattern
->GetItemSet();
877 if ( rSet
.GetItemState( ATTR_MERGE
, false ) == SFX_ITEM_DEFAULT
&&
878 rSet
.GetItemState( ATTR_MERGE_FLAG
, false ) == SFX_ITEM_DEFAULT
&&
879 rSet
.GetItemState( ATTR_BORDER
, false ) == SFX_ITEM_DEFAULT
)
881 // no borders or merge items involved - use pattern as-is
882 for (nRow
= nAttrRow1
; nRow
<=nAttrRow2
; nRow
++)
883 pTransClip
->SetPattern( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), *pPattern
, true );
887 // transpose borders and merge values, remove merge flags (refreshed after pasting)
888 ScPatternAttr
aNewPattern( *pPattern
);
889 SfxItemSet
& rNewSet
= aNewPattern
.GetItemSet();
891 const SvxBoxItem
& rOldBox
= (const SvxBoxItem
&)rSet
.Get(ATTR_BORDER
);
892 if ( rOldBox
.GetTop() || rOldBox
.GetBottom() || rOldBox
.GetLeft() || rOldBox
.GetRight() )
894 SvxBoxItem
aNew( ATTR_BORDER
);
895 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_TOP
), BOX_LINE_LEFT
);
896 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_LEFT
), BOX_LINE_TOP
);
897 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_BOTTOM
), BOX_LINE_RIGHT
);
898 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_RIGHT
), BOX_LINE_BOTTOM
);
899 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_TOP
), BOX_LINE_LEFT
);
900 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_LEFT
), BOX_LINE_TOP
);
901 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_BOTTOM
), BOX_LINE_RIGHT
);
902 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_RIGHT
), BOX_LINE_BOTTOM
);
906 const ScMergeAttr
& rOldMerge
= (const ScMergeAttr
&)rSet
.Get(ATTR_MERGE
);
907 if (rOldMerge
.IsMerged())
908 rNewSet
.Put( ScMergeAttr( std::min(
909 static_cast<SCsCOL
>(rOldMerge
.GetRowMerge()),
910 static_cast<SCsCOL
>(MAXCOL
+1 - (nAttrRow2
-nRow1
))),
912 static_cast<SCsROW
>(rOldMerge
.GetColMerge()),
913 static_cast<SCsROW
>(MAXROW
+1 - (nCol
-nCol1
)))));
914 const ScMergeFlagAttr
& rOldFlag
= (const ScMergeFlagAttr
&)rSet
.Get(ATTR_MERGE_FLAG
);
915 if (rOldFlag
.IsOverlapped())
917 sal_Int16 nNewFlags
= rOldFlag
.GetValue() & ~( SC_MF_HOR
| SC_MF_VER
);
919 rNewSet
.Put( ScMergeFlagAttr( nNewFlags
) );
921 rNewSet
.ClearItem( ATTR_MERGE_FLAG
);
924 for (nRow
= nAttrRow1
; nRow
<=nAttrRow2
; nRow
++)
925 pTransClip
->SetPattern( static_cast<SCCOL
>(nRow
-nRow1
),
926 static_cast<SCROW
>(nCol
-nCol1
), aNewPattern
, true);
931 // Cell Notes - fdo#68381 paste cell notes on Transpose
932 if ( pDocument
->HasColNotes(nCol
, nTab
) )
933 TransposeColNotes(pTransClip
, nCol1
, nCol
, nRow1
, nRow2
);
937 void ScTable::TransposeColNotes(ScTable
* pTransClip
, SCCOL nCol1
, SCCOL nCol
, SCROW nRow1
, SCROW nRow2
)
939 bool bCloneCaption
= true;
941 sc::CellNoteStoreType::const_iterator itBlk
= aCol
[nCol
].maCellNotes
.begin(), itBlkEnd
= aCol
[nCol
].maCellNotes
.end();
943 // Locate the top row position.
944 size_t nOffsetInBlock
= 0;
945 size_t nBlockStart
= 0, nBlockEnd
= 0, nRowPos
= static_cast<size_t>(nRow1
);
946 for (; itBlk
!= itBlkEnd
; ++itBlk
, nBlockStart
= nBlockEnd
)
948 nBlockEnd
= nBlockStart
+ itBlk
->size
;
949 if (nBlockStart
<= nRowPos
&& nRowPos
< nBlockEnd
)
952 nOffsetInBlock
= nRowPos
- nBlockStart
;
957 if (itBlk
!= itBlkEnd
)
958 // Specified range found
960 nRowPos
= static_cast<size_t>(nRow2
); // End row position.
962 // Keep processing until we hit the end row position.
963 sc::cellnote_block::const_iterator itData
, itDataEnd
;
964 for (; itBlk
!= itBlkEnd
; ++itBlk
, nBlockStart
= nBlockEnd
, nOffsetInBlock
= 0)
966 nBlockEnd
= nBlockStart
+ itBlk
->size
;
970 itData
= sc::cellnote_block::begin(*itBlk
->data
);
971 std::advance(itData
, nOffsetInBlock
);
973 if (nBlockStart
<= nRowPos
&& nRowPos
< nBlockEnd
)
975 // This block contains the end row. Only process partially.
976 size_t nOffsetEnd
= nRowPos
- nBlockStart
+ 1;
977 itDataEnd
= sc::cellnote_block::begin(*itBlk
->data
);
978 std::advance(itDataEnd
, nOffsetEnd
);
979 size_t curRow
= nBlockStart
+ nOffsetInBlock
;
980 for (; itData
!= itDataEnd
; ++itData
, ++curRow
)
982 ScAddress
aDestPos( static_cast<SCCOL
>(curRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
983 pTransClip
->pDocument
->ReleaseNote(aDestPos
);
984 ScPostIt
* pNote
= *itData
;
987 ScPostIt
* pClonedNote
= pNote
->Clone( ScAddress(nCol
, curRow
, nTab
), *pTransClip
->pDocument
, aDestPos
, bCloneCaption
);
988 pTransClip
->pDocument
->SetNote(aDestPos
, pClonedNote
);
991 break; // we reached the last valid block
995 itDataEnd
= sc::cellnote_block::end(*itBlk
->data
);
996 size_t curRow
= nBlockStart
+ nOffsetInBlock
;
997 for (; itData
!= itDataEnd
; ++itData
, ++curRow
)
999 ScAddress
aDestPos( static_cast<SCCOL
>(curRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
1000 pTransClip
->pDocument
->ReleaseNote(aDestPos
);
1001 ScPostIt
* pNote
= *itData
;
1004 ScPostIt
* pClonedNote
= pNote
->Clone( ScAddress(nCol
, curRow
, nTab
), *pTransClip
->pDocument
, aDestPos
, bCloneCaption
);
1005 pTransClip
->pDocument
->SetNote(aDestPos
, pClonedNote
);
1013 for ( curRow
= nBlockStart
+ nOffsetInBlock
; curRow
<= nBlockEnd
&& curRow
<= nRowPos
; ++curRow
)
1015 ScAddress
aDestPos( static_cast<SCCOL
>(curRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
1016 pTransClip
->pDocument
->ReleaseNote(aDestPos
);
1018 if (curRow
== nRowPos
)
1025 void ScTable::StartAllListeners()
1027 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1028 aCol
[i
].StartAllListeners();
1032 void ScTable::StartNeededListeners()
1034 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1035 aCol
[i
].StartNeededListeners();
1039 void ScTable::BroadcastInArea( SCCOL nCol1
, SCROW nRow1
,
1040 SCCOL nCol2
, SCROW nRow2
)
1042 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
1043 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
1044 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1045 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1046 aCol
[i
].SetDirty(nRow1
, nRow2
);
1050 void ScTable::StartListeningInArea(
1051 sc::StartListeningContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
1053 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
1054 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
1055 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1056 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1057 aCol
[i
].StartListeningInArea(rCxt
, nRow1
, nRow2
);
1061 void ScTable::CopyToTable(
1062 sc::CopyToDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1063 sal_uInt16 nFlags
, bool bMarked
, ScTable
* pDestTab
, const ScMarkData
* pMarkData
,
1064 bool bAsLink
, bool bColRowFlags
)
1066 if (!ValidColRow(nCol1
, nRow1
) || !ValidColRow(nCol2
, nRow2
))
1070 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1071 aCol
[i
].CopyToColumn(rCxt
, nRow1
, nRow2
, nFlags
, bMarked
,
1072 pDestTab
->aCol
[i
], pMarkData
, bAsLink
);
1074 if (!bColRowFlags
) // Spaltenbreiten/Zeilenhoehen/Flags
1077 if(pDestTab
->pDocument
->IsUndo() && (nFlags
& IDF_ATTRIB
))
1079 pDestTab
->mpCondFormatList
.reset(new ScConditionalFormatList(pDestTab
->pDocument
, *mpCondFormatList
));
1084 ScDBData
* pNewDBData
= new ScDBData(*pDBDataNoName
);
1088 pNewDBData
->GetArea(aTab
, aCol1
, aRow1
, aCol2
, aRow2
);
1089 pNewDBData
->MoveTo(pDestTab
->nTab
, aCol1
, aRow1
, aCol2
, aRow2
);
1090 pDestTab
->SetAnonymousDBData(pNewDBData
);
1092 // Charts muessen beim Ein-/Ausblenden angepasst werden
1093 ScChartListenerCollection
* pCharts
= pDestTab
->pDocument
->GetChartListenerCollection();
1095 bool bFlagChange
= false;
1097 bool bWidth
= (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pDestTab
->pColWidth
);
1098 bool bHeight
= (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pDestTab
->mpRowHeights
);
1100 if (bWidth
|| bHeight
)
1104 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
1106 bool bThisHidden
= ColHidden(i
);
1107 bool bHiddenChange
= (pDestTab
->ColHidden(i
) != bThisHidden
);
1108 bool bChange
= bHiddenChange
|| (pDestTab
->pColWidth
[i
] != pColWidth
[i
]);
1109 pDestTab
->pColWidth
[i
] = pColWidth
[i
];
1110 pDestTab
->pColFlags
[i
] = pColFlags
[i
];
1111 pDestTab
->SetColHidden(i
, i
, bThisHidden
);
1112 //! Aenderungen zusammenfassen?
1113 if (bHiddenChange
&& pCharts
)
1114 pCharts
->SetRangeDirty(ScRange( i
, 0, nTab
, i
, MAXROW
, nTab
));
1119 pDestTab
->SetColManualBreaks( maColManualBreaks
);
1124 bool bChange
= pDestTab
->GetRowHeight(nRow1
, nRow2
) != GetRowHeight(nRow1
, nRow2
);
1129 pDestTab
->CopyRowHeight(*this, nRow1
, nRow2
, 0);
1130 pDestTab
->pRowFlags
->CopyFrom(*pRowFlags
, nRow1
, nRow2
);
1133 for (SCROW i
= nRow1
; i
<= nRow2
; ++i
)
1136 bool bHidden
= RowHidden(i
, NULL
, &nLastRow
);
1137 if (nLastRow
>= nRow2
)
1138 // the last row shouldn't exceed the upper bound the caller specified.
1141 bool bHiddenChanged
= pDestTab
->SetRowHidden(i
, nLastRow
, bHidden
);
1142 if (bHiddenChanged
&& pCharts
)
1143 // Hidden flags differ.
1144 pCharts
->SetRangeDirty(ScRange(0, i
, nTab
, MAXCOL
, nLastRow
, nTab
));
1149 // Jump to the last row of the identical flag segment.
1154 for (SCROW i
= nRow1
; i
<= nRow2
; ++i
)
1157 bool bFiltered
= RowFiltered(i
, NULL
, &nLastRow
);
1158 if (nLastRow
>= nRow2
)
1159 // the last row shouldn't exceed the upper bound the caller specified.
1161 pDestTab
->SetRowFiltered(i
, nLastRow
, bFiltered
);
1164 pDestTab
->SetRowManualBreaks( maRowManualBreaks
);
1169 pDestTab
->InvalidatePageBreaks();
1171 if(nFlags
& IDF_ATTRIB
)
1173 pDestTab
->mpCondFormatList
->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
);
1174 pDestTab
->CopyConditionalFormat(nCol1
, nRow1
, nCol2
, nRow2
, 0, 0, this);
1177 if(nFlags
& IDF_OUTLINE
) // also only when bColRowFlags
1178 pDestTab
->SetOutlineTable( pOutlineTable
);
1182 void ScTable::UndoToTable(
1183 sc::CopyToDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1184 sal_uInt16 nFlags
, bool bMarked
, ScTable
* pDestTab
, const ScMarkData
* pMarkData
)
1186 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1188 bool bWidth
= (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pDestTab
->pColWidth
);
1189 bool bHeight
= (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pDestTab
->mpRowHeights
);
1191 for ( SCCOL i
= 0; i
<= MAXCOL
; i
++)
1193 if ( i
>= nCol1
&& i
<= nCol2
)
1194 aCol
[i
].UndoToColumn(rCxt
, nRow1
, nRow2
, nFlags
, bMarked
, pDestTab
->aCol
[i
], pMarkData
);
1196 aCol
[i
].CopyToColumn(rCxt
, 0, MAXROW
, IDF_FORMULA
, false, pDestTab
->aCol
[i
]);
1199 if (nFlags
& IDF_ATTRIB
)
1200 pDestTab
->mpCondFormatList
.reset(new ScConditionalFormatList(pDestTab
->pDocument
, *mpCondFormatList
));
1203 if (bWidth
||bHeight
)
1207 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
1208 pDestTab
->pColWidth
[i
] = pColWidth
[i
];
1209 pDestTab
->SetColManualBreaks( maColManualBreaks
);
1213 pDestTab
->CopyRowHeight(*this, nRow1
, nRow2
, 0);
1214 pDestTab
->SetRowManualBreaks( maRowManualBreaks
);
1221 void ScTable::CopyUpdated( const ScTable
* pPosTab
, ScTable
* pDestTab
) const
1223 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1224 aCol
[i
].CopyUpdated( pPosTab
->aCol
[i
], pDestTab
->aCol
[i
] );
1227 void ScTable::InvalidateTableArea()
1229 bTableAreaValid
= false;
1232 void ScTable::InvalidatePageBreaks()
1234 mbPageBreaksValid
= false;
1237 void ScTable::CopyScenarioTo( ScTable
* pDestTab
) const
1239 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1241 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1242 aCol
[i
].CopyScenarioTo( pDestTab
->aCol
[i
] );
1245 void ScTable::CopyScenarioFrom( const ScTable
* pSrcTab
)
1247 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1249 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1250 aCol
[i
].CopyScenarioFrom( pSrcTab
->aCol
[i
] );
1253 void ScTable::MarkScenarioIn( ScMarkData
& rDestMark
, sal_uInt16 nNeededBits
) const
1255 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1257 if ( ( nScenarioFlags
& nNeededBits
) != nNeededBits
) // alle Bits gesetzt?
1260 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1261 aCol
[i
].MarkScenarioIn( rDestMark
);
1264 bool ScTable::HasScenarioRange( const ScRange
& rRange
) const
1266 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1268 ScRange aTabRange
= rRange
;
1269 aTabRange
.aStart
.SetTab( nTab
);
1270 aTabRange
.aEnd
.SetTab( nTab
);
1272 const ScRangeList
* pList
= GetScenarioRanges();
1276 for ( size_t j
= 0, n
= pList
->size(); j
< n
; j
++ )
1278 const ScRange
* pR
= (*pList
)[j
];
1279 if ( pR
->Intersects( aTabRange
) )
1287 void ScTable::InvalidateScenarioRanges()
1289 delete pScenarioRanges
;
1290 pScenarioRanges
= NULL
;
1293 const ScRangeList
* ScTable::GetScenarioRanges() const
1295 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1297 if (!pScenarioRanges
)
1299 ((ScTable
*)this)->pScenarioRanges
= new ScRangeList
;
1301 MarkScenarioIn( aMark
, 0 ); // immer
1302 aMark
.FillRangeListWithMarks( pScenarioRanges
, false );
1304 return pScenarioRanges
;
1307 bool ScTable::TestCopyScenarioTo( const ScTable
* pDestTab
) const
1309 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1311 if (!pDestTab
->IsProtected())
1315 for (SCCOL i
=0; i
<=MAXCOL
&& bOk
; i
++)
1316 bOk
= aCol
[i
].TestCopyScenarioTo( pDestTab
->aCol
[i
] );
1320 bool ScTable::SetString( SCCOL nCol
, SCROW nRow
, SCTAB nTabP
, const OUString
& rString
,
1321 ScSetStringParam
* pParam
)
1323 if (ValidColRow(nCol
,nRow
))
1324 return aCol
[nCol
].SetString(
1325 nRow
, nTabP
, rString
, pDocument
->GetAddressConvention(), pParam
);
1330 void ScTable::SetEditText( SCCOL nCol
, SCROW nRow
, EditTextObject
* pEditText
)
1332 if (!ValidColRow(nCol
, nRow
))
1338 aCol
[nCol
].SetEditText(nRow
, pEditText
);
1341 void ScTable::SetEditText( SCCOL nCol
, SCROW nRow
, const EditTextObject
& rEditText
, const SfxItemPool
* pEditPool
)
1343 if (!ValidColRow(nCol
, nRow
))
1346 aCol
[nCol
].SetEditText(nRow
, rEditText
, pEditPool
);
1349 void ScTable::SetEmptyCell( SCCOL nCol
, SCROW nRow
)
1351 if (!ValidColRow(nCol
, nRow
))
1354 aCol
[nCol
].Delete(nRow
);
1357 void ScTable::SetFormula(
1358 SCCOL nCol
, SCROW nRow
, const ScTokenArray
& rArray
, formula::FormulaGrammar::Grammar eGram
)
1360 if (!ValidColRow(nCol
, nRow
))
1363 aCol
[nCol
].SetFormula(nRow
, rArray
, eGram
);
1366 void ScTable::SetFormula(
1367 SCCOL nCol
, SCROW nRow
, const OUString
& rFormula
, formula::FormulaGrammar::Grammar eGram
)
1369 if (!ValidColRow(nCol
, nRow
))
1372 aCol
[nCol
].SetFormula(nRow
, rFormula
, eGram
);
1375 ScFormulaCell
* ScTable::SetFormulaCell( SCCOL nCol
, SCROW nRow
, ScFormulaCell
* pCell
)
1377 if (!ValidColRow(nCol
, nRow
))
1383 return aCol
[nCol
].SetFormulaCell(nRow
, pCell
);
1386 svl::SharedString
ScTable::GetSharedString( SCCOL nCol
, SCROW nRow
) const
1388 if (!ValidColRow(nCol
, nRow
))
1389 return svl::SharedString();
1391 return aCol
[nCol
].GetSharedString(nRow
);
1394 void ScTable::SetValue( SCCOL nCol
, SCROW nRow
, const double& rVal
)
1396 if (ValidColRow(nCol
, nRow
))
1397 aCol
[nCol
].SetValue( nRow
, rVal
);
1400 void ScTable::SetRawString( SCCOL nCol
, SCROW nRow
, const OUString
& rStr
)
1402 if (ValidColRow(nCol
, nRow
))
1403 aCol
[nCol
].SetRawString(nRow
, rStr
);
1406 void ScTable::SetRawString( SCCOL nCol
, SCROW nRow
, const svl::SharedString
& rStr
)
1408 if (ValidColRow(nCol
, nRow
))
1409 aCol
[nCol
].SetRawString(nRow
, rStr
);
1412 void ScTable::GetString( SCCOL nCol
, SCROW nRow
, OUString
& rString
) const
1414 if (ValidColRow(nCol
,nRow
))
1415 aCol
[nCol
].GetString( nRow
, rString
);
1417 rString
= OUString();
1420 double* ScTable::GetValueCell( SCCOL nCol
, SCROW nRow
)
1422 if (!ValidColRow(nCol
,nRow
))
1425 return aCol
[nCol
].GetValueCell(nRow
);
1428 void ScTable::GetInputString( SCCOL nCol
, SCROW nRow
, OUString
& rString
) const
1430 if (ValidColRow(nCol
,nRow
))
1431 aCol
[nCol
].GetInputString( nRow
, rString
);
1433 rString
= OUString();
1437 double ScTable::GetValue( SCCOL nCol
, SCROW nRow
) const
1439 if (ValidColRow( nCol
, nRow
))
1440 return aCol
[nCol
].GetValue( nRow
);
1444 const EditTextObject
* ScTable::GetEditText( SCCOL nCol
, SCROW nRow
) const
1446 if (!ValidColRow(nCol
, nRow
))
1449 return aCol
[nCol
].GetEditText(nRow
);
1452 void ScTable::RemoveEditTextCharAttribs( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
)
1454 if (!ValidColRow(nCol
, nRow
))
1457 return aCol
[nCol
].RemoveEditTextCharAttribs(nRow
, rAttr
);
1460 void ScTable::GetFormula( SCCOL nCol
, SCROW nRow
, OUString
& rFormula
) const
1462 if (ValidColRow(nCol
,nRow
))
1463 aCol
[nCol
].GetFormula( nRow
, rFormula
);
1465 rFormula
= OUString();
1468 const ScTokenArray
* ScTable::GetFormulaTokens( SCCOL nCol
, SCROW nRow
) const
1470 if (!ValidColRow(nCol
, nRow
))
1473 return aCol
[nCol
].GetFormulaTokens(nRow
);
1476 const ScFormulaCell
* ScTable::GetFormulaCell( SCCOL nCol
, SCROW nRow
) const
1478 if (!ValidColRow(nCol
, nRow
))
1481 return aCol
[nCol
].GetFormulaCell(nRow
);
1484 ScFormulaCell
* ScTable::GetFormulaCell( SCCOL nCol
, SCROW nRow
)
1486 if (!ValidColRow(nCol
, nRow
))
1489 return aCol
[nCol
].GetFormulaCell(nRow
);
1492 ScPostIt
* ScTable::GetNote(const SCCOL nCol
, const SCROW nRow
)
1494 return pDocument
->GetNote(nCol
, nRow
, nTab
);
1497 size_t ScTable::GetNoteCount( SCCOL nCol
) const
1499 if (!ValidCol(nCol
))
1502 return aCol
[nCol
].GetNoteCount();
1505 SCROW
ScTable::GetNotePosition( SCCOL nCol
, size_t nIndex
) const
1507 if (!ValidCol(nCol
))
1510 return aCol
[nCol
].GetNotePosition(nIndex
);
1513 void ScTable::GetAllNoteEntries( std::vector
<sc::NoteEntry
>& rNotes
) const
1515 for (SCCOL nCol
= 0; nCol
< MAXCOLCOUNT
; ++nCol
)
1516 aCol
[nCol
].GetAllNoteEntries(rNotes
);
1519 void ScTable::GetNotesInRange( const ScRange
& rRange
, std::vector
<sc::NoteEntry
>& rNotes
) const
1521 SCROW nStartRow
= rRange
.aStart
.Row();
1522 SCROW nEndRow
= rRange
.aEnd
.Row();
1523 for (SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= rRange
.aEnd
.Col(); ++nCol
)
1525 aCol
[nCol
].GetNotesInRange(nStartRow
, nEndRow
, rNotes
);
1529 bool ScTable::ContainsNotesInRange( const ScRange
& rRange
) const
1531 SCROW nStartRow
= rRange
.aStart
.Row();
1532 SCROW nEndRow
= rRange
.aEnd
.Row();
1533 for (SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= rRange
.aEnd
.Col(); ++nCol
)
1535 bool bContainsNote
= !aCol
[nCol
].IsNotesEmptyBlock(nStartRow
, nEndRow
);
1543 CellType
ScTable::GetCellType( SCCOL nCol
, SCROW nRow
) const
1545 if (ValidColRow( nCol
, nRow
))
1546 return aCol
[nCol
].GetCellType( nRow
);
1547 return CELLTYPE_NONE
;
1550 ScRefCellValue
ScTable::GetCellValue( SCCOL nCol
, SCROW nRow
) const
1552 if (!ValidColRow(nCol
, nRow
))
1553 return ScRefCellValue();
1555 return aCol
[nCol
].GetCellValue(nRow
);
1558 void ScTable::GetFirstDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
1562 while (aCol
[rCol
].IsEmptyData() && rCol
< MAXCOL
)
1565 while (nCol
<= MAXCOL
&& rRow
> 0)
1567 if (!aCol
[nCol
].IsEmptyData())
1568 rRow
= ::std::min( rRow
, aCol
[nCol
].GetFirstDataPos());
1573 void ScTable::GetLastDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
1577 while (aCol
[rCol
].IsEmptyData() && (rCol
> 0))
1580 while (nCol
>= 0 && rRow
< MAXROW
)
1581 rRow
= ::std::max( rRow
, aCol
[nCol
--].GetLastDataPos());
1585 bool ScTable::HasData( SCCOL nCol
, SCROW nRow
) const
1587 if (ValidColRow(nCol
,nRow
))
1588 return aCol
[nCol
].HasDataAt( nRow
);
1594 bool ScTable::HasStringData( SCCOL nCol
, SCROW nRow
) const
1596 if (ValidColRow(nCol
,nRow
))
1597 return aCol
[nCol
].HasStringData( nRow
);
1603 bool ScTable::HasValueData( SCCOL nCol
, SCROW nRow
) const
1605 if (ValidColRow(nCol
,nRow
))
1606 return aCol
[nCol
].HasValueData( nRow
);
1612 bool ScTable::HasStringCells( SCCOL nStartCol
, SCROW nStartRow
,
1613 SCCOL nEndCol
, SCROW nEndRow
) const
1615 if ( ValidCol(nEndCol
) )
1616 for ( SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++ )
1617 if (aCol
[nCol
].HasStringCells(nStartRow
, nEndRow
))
1624 void ScTable::SetDirtyVar()
1626 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1627 aCol
[i
].SetDirtyVar();
1631 void ScTable::SetDirty()
1633 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1634 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1635 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1637 pDocument
->SetAutoCalc( bOldAutoCalc
);
1641 void ScTable::SetDirty( const ScRange
& rRange
)
1643 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1644 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1645 SCCOL nCol2
= rRange
.aEnd
.Col();
1646 for (SCCOL i
=rRange
.aStart
.Col(); i
<=nCol2
; i
++)
1647 aCol
[i
].SetDirty(rRange
.aStart
.Row(), rRange
.aEnd
.Row());
1648 pDocument
->SetAutoCalc( bOldAutoCalc
);
1652 void ScTable::SetTableOpDirty( const ScRange
& rRange
)
1654 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1655 pDocument
->SetAutoCalc( false ); // no multiple recalculation
1656 SCCOL nCol2
= rRange
.aEnd
.Col();
1657 for (SCCOL i
=rRange
.aStart
.Col(); i
<=nCol2
; i
++)
1658 aCol
[i
].SetTableOpDirty( rRange
);
1659 pDocument
->SetAutoCalc( bOldAutoCalc
);
1663 void ScTable::SetDirtyAfterLoad()
1665 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1666 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1667 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1668 aCol
[i
].SetDirtyAfterLoad();
1669 pDocument
->SetAutoCalc( bOldAutoCalc
);
1673 void ScTable::SetDirtyIfPostponed()
1675 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1676 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1677 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1678 aCol
[i
].SetDirtyIfPostponed();
1679 pDocument
->SetAutoCalc( bOldAutoCalc
);
1682 void ScTable::BroadcastRecalcOnRefMove()
1684 sc::AutoCalcSwitch
aSwitch(*pDocument
, false);
1685 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1686 aCol
[i
].BroadcastRecalcOnRefMove();
1689 void ScTable::SetLoadingMedium(bool bLoading
)
1691 mpRowHeights
->enableTreeSearch(!bLoading
);
1695 void ScTable::CalcAll()
1697 for (SCCOL i
=0; i
<=MAXCOL
; i
++) aCol
[i
].CalcAll();
1701 void ScTable::CompileAll()
1703 for (SCCOL i
=0; i
<= MAXCOL
; i
++) aCol
[i
].CompileAll();
1705 if(mpCondFormatList
)
1706 mpCondFormatList
->CompileAll();
1710 void ScTable::CompileXML( ScProgress
& rProgress
)
1713 mpRangeName
->CompileUnresolvedXML();
1715 for (SCCOL i
=0; i
<= MAXCOL
; i
++)
1717 aCol
[i
].CompileXML( rProgress
);
1720 if(mpCondFormatList
)
1721 mpCondFormatList
->CompileXML();
1724 bool ScTable::CompileErrorCells(sal_uInt16 nErrCode
)
1726 bool bCompiled
= false;
1727 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1729 if (aCol
[i
].CompileErrorCells(nErrCode
))
1736 void ScTable::CalcAfterLoad()
1738 for (SCCOL i
=0; i
<= MAXCOL
; i
++) aCol
[i
].CalcAfterLoad();
1741 bool ScTable::IsEmptyData( SCCOL nCol
) const
1743 if (!ValidCol(nCol
))
1746 return aCol
[nCol
].IsEmptyData();
1749 void ScTable::ResetChanged( const ScRange
& rRange
)
1751 SCCOL nStartCol
= rRange
.aStart
.Col();
1752 SCROW nStartRow
= rRange
.aStart
.Row();
1753 SCCOL nEndCol
= rRange
.aEnd
.Col();
1754 SCROW nEndRow
= rRange
.aEnd
.Row();
1756 for (SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
1757 aCol
[nCol
].ResetChanged(nStartRow
, nEndRow
);
1762 const SfxPoolItem
* ScTable::GetAttr( SCCOL nCol
, SCROW nRow
, sal_uInt16 nWhich
) const
1764 if (ValidColRow(nCol
,nRow
))
1765 return aCol
[nCol
].GetAttr( nRow
, nWhich
);
1770 sal_uInt32
ScTable::GetNumberFormat( const ScAddress
& rPos
) const
1772 return ValidColRow(rPos
.Col(),rPos
.Row()) ?
1773 aCol
[rPos
.Col()].GetNumberFormat( rPos
.Row() ) :
1777 sal_uInt32
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nRow
) const
1779 if (ValidColRow(nCol
,nRow
))
1780 return aCol
[nCol
].GetNumberFormat( nRow
);
1785 sal_uInt32
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
) const
1787 if (!ValidCol(nCol
) || !ValidRow(nStartRow
) || !ValidRow(nEndRow
))
1790 return aCol
[nCol
].GetNumberFormat(nStartRow
, nEndRow
);
1793 void ScTable::SetNumberFormat( SCCOL nCol
, SCROW nRow
, sal_uInt32 nNumberFormat
)
1795 if (!ValidColRow(nCol
, nRow
))
1798 aCol
[nCol
].SetNumberFormat(nRow
, nNumberFormat
);
1801 const ScPatternAttr
* ScTable::GetPattern( SCCOL nCol
, SCROW nRow
) const
1803 if (ValidColRow(nCol
,nRow
))
1804 return aCol
[nCol
].GetPattern( nRow
);
1807 OSL_FAIL("wrong column or row");
1808 return pDocument
->GetDefPattern(); // for safety
1813 const ScPatternAttr
* ScTable::GetMostUsedPattern( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
) const
1815 if ( ValidColRow( nCol
, nStartRow
) && ValidRow( nEndRow
) && (nStartRow
<= nEndRow
) )
1816 return aCol
[nCol
].GetMostUsedPattern( nStartRow
, nEndRow
);
1822 bool ScTable::HasAttrib( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, sal_uInt16 nMask
) const
1824 bool bFound
= false;
1825 for (SCCOL i
=nCol1
; i
<=nCol2
&& !bFound
; i
++)
1826 bFound
|= aCol
[i
].HasAttrib( nRow1
, nRow2
, nMask
);
1831 bool ScTable::HasAttribSelection( const ScMarkData
& rMark
, sal_uInt16 nMask
) const
1833 bool bFound
= false;
1834 for (SCCOL i
=0; i
<=MAXCOL
&& !bFound
; i
++)
1835 bFound
|= aCol
[i
].HasAttribSelection( rMark
, nMask
);
1840 bool ScTable::ExtendMerge( SCCOL nStartCol
, SCROW nStartRow
,
1841 SCCOL
& rEndCol
, SCROW
& rEndRow
,
1844 if (!(ValidCol(nStartCol
) && ValidCol(rEndCol
)))
1846 OSL_FAIL("ScTable::ExtendMerge: invalid column number");
1849 bool bFound
= false;
1850 SCCOL nOldEndX
= rEndCol
;
1851 SCROW nOldEndY
= rEndRow
;
1852 for (SCCOL i
=nStartCol
; i
<=nOldEndX
; i
++)
1853 bFound
|= aCol
[i
].ExtendMerge( i
, nStartRow
, nOldEndY
, rEndCol
, rEndRow
, bRefresh
);
1858 bool ScTable::IsBlockEmpty( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, bool bIgnoreNotes
) const
1860 if (!(ValidCol(nCol1
) && ValidCol(nCol2
)))
1862 OSL_FAIL("ScTable::IsBlockEmpty: invalid column number");
1866 for (SCCOL i
=nCol1
; i
<=nCol2
&& bEmpty
; i
++)
1868 bEmpty
= aCol
[i
].IsEmptyBlock( nRow1
, nRow2
);
1869 if (!bIgnoreNotes
&& bEmpty
)
1871 bEmpty
= aCol
[i
].IsNotesEmptyBlock(nRow1
, nRow2
);
1877 SCSIZE
ScTable::FillMaxRot( RowInfo
* pRowInfo
, SCSIZE nArrCount
, SCCOL nX1
, SCCOL nX2
,
1878 SCCOL nCol
, SCROW nAttrRow1
, SCROW nAttrRow2
, SCSIZE nArrY
,
1879 const ScPatternAttr
* pPattern
, const SfxItemSet
* pCondSet
)
1881 // Rueckgabe = neues nArrY
1883 sal_uInt8 nRotDir
= pPattern
->GetRotateDir( pCondSet
);
1884 if ( nRotDir
!= SC_ROTDIR_NONE
)
1887 if ( nCol
+1 < nX1
) // column to the left
1888 bHit
= ( nRotDir
!= SC_ROTDIR_LEFT
);
1889 else if ( nCol
> nX2
+1 ) // column to the right
1890 bHit
= ( nRotDir
!= SC_ROTDIR_RIGHT
); // SC_ROTDIR_STANDARD may now also be extended to the left
1894 double nFactor
= 0.0;
1897 long nRotVal
= ((const SfxInt32Item
&) pPattern
->
1898 GetItem( ATTR_ROTATE_VALUE
, pCondSet
)).GetValue();
1899 double nRealOrient
= nRotVal
* F_PI18000
; // 1/100 Grad
1900 double nCos
= cos( nRealOrient
);
1901 double nSin
= sin( nRealOrient
);
1903 //! zusaetzlich Faktor fuer unterschiedliche PPT X/Y !!!
1905 // bei SC_ROTDIR_LEFT kommt immer ein negativer Wert heraus,
1906 // wenn der Modus beruecksichtigt wird
1907 nFactor
= -fabs( nCos
/ nSin
);
1910 for ( SCROW nRow
= nAttrRow1
; nRow
<= nAttrRow2
; nRow
++ )
1912 if (!RowHidden(nRow
))
1914 bool bHitOne
= true;
1917 // reicht die gedrehte Zelle bis in den sichtbaren Bereich?
1919 SCCOL nTouchedCol
= nCol
;
1920 long nWidth
= static_cast<long>(mpRowHeights
->getValue(nRow
) * nFactor
);
1921 OSL_ENSURE(nWidth
<= 0, "Wrong direction");
1922 while ( nWidth
< 0 && nTouchedCol
> 0 )
1925 nWidth
+= GetColWidth( nTouchedCol
);
1927 if ( nTouchedCol
> nX2
)
1933 while ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
< nRow
)
1935 if ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
== nRow
)
1936 pRowInfo
[nArrY
].nRotMaxCol
= nCol
;
1946 void ScTable::FindMaxRotCol( RowInfo
* pRowInfo
, SCSIZE nArrCount
, SCCOL nX1
, SCCOL nX2
)
1948 if ( !pColWidth
|| !mpRowHeights
|| !pColFlags
|| !pRowFlags
)
1950 OSL_FAIL( "Row/column info missing" );
1954 // nRotMaxCol ist auf SC_ROTMAX_NONE initialisiert, nRowNo ist schon gesetzt
1956 SCROW nY1
= pRowInfo
[0].nRowNo
;
1957 SCROW nY2
= pRowInfo
[nArrCount
-1].nRowNo
;
1959 for (SCCOL nCol
=0; nCol
<=MAXCOL
; nCol
++)
1961 if (!ColHidden(nCol
))
1964 ScDocAttrIterator
aIter( pDocument
, nTab
, nCol
, nY1
, nCol
, nY2
);
1966 SCROW nAttrRow1
, nAttrRow2
;
1967 const ScPatternAttr
* pPattern
= aIter
.GetNext( nAttrCol
, nAttrRow1
, nAttrRow2
);
1970 const SfxPoolItem
* pCondItem
;
1971 if ( pPattern
->GetItemSet().GetItemState( ATTR_CONDITIONAL
, true, &pCondItem
)
1974 // alle Formate durchgehen, damit die Zellen nicht einzeln
1975 // angeschaut werden muessen
1977 const std::vector
<sal_uInt32
>& rCondFormatData
= static_cast<const ScCondFormatItem
*>(pCondItem
)->GetCondFormatData();
1978 ScStyleSheetPool
* pStylePool
= pDocument
->GetStyleSheetPool();
1979 if (mpCondFormatList
&& pStylePool
&& !rCondFormatData
.empty())
1981 for(std::vector
<sal_uInt32
>::const_iterator itr
= rCondFormatData
.begin(), itrEnd
= rCondFormatData
.end();
1982 itr
!= itrEnd
; ++itr
)
1984 const ScConditionalFormat
* pFormat
= mpCondFormatList
->GetFormat(*itr
);
1987 size_t nEntryCount
= pFormat
->size();
1988 for (size_t nEntry
=0; nEntry
<nEntryCount
; nEntry
++)
1990 const ScFormatEntry
* pEntry
= pFormat
->GetEntry(nEntry
);
1991 if(pEntry
->GetType() != condformat::CONDITION
)
1994 OUString aStyleName
= static_cast<const ScCondFormatEntry
*>(pEntry
)->GetStyle();
1995 if (!aStyleName
.isEmpty())
1997 SfxStyleSheetBase
* pStyleSheet
=
1998 pStylePool
->Find( aStyleName
, SFX_STYLE_FAMILY_PARA
);
2001 FillMaxRot( pRowInfo
, nArrCount
, nX1
, nX2
,
2002 nCol
, nAttrRow1
, nAttrRow2
,
2003 nArrY
, pPattern
, &pStyleSheet
->GetItemSet() );
2004 // nArrY nicht veraendern
2013 nArrY
= FillMaxRot( pRowInfo
, nArrCount
, nX1
, nX2
,
2014 nCol
, nAttrRow1
, nAttrRow2
,
2015 nArrY
, pPattern
, NULL
);
2017 pPattern
= aIter
.GetNext( nAttrCol
, nAttrRow1
, nAttrRow2
);
2023 bool ScTable::HasBlockMatrixFragment( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
2027 sal_uInt16 nEdges
= 0;
2029 if ( nCol1
== nCol2
)
2030 { // linke und rechte Spalte
2031 const sal_uInt16 n
= MatrixEdgeLeft
| MatrixEdgeRight
;
2032 nEdges
= aCol
[nCol1
].GetBlockMatrixEdges( nRow1
, nRow2
, n
);
2033 // nicht (4 und 16) oder 1 oder 32
2034 if (nEdges
&& (((nEdges
& n
) != n
) || (nEdges
& (MatrixEdgeInside
|MatrixEdgeOpen
))))
2035 return true; // linke oder rechte Kante fehlt oder offen
2039 nEdges
= aCol
[nCol1
].GetBlockMatrixEdges(nRow1
, nRow2
, MatrixEdgeLeft
);
2040 // nicht 4 oder 1 oder 32
2041 if (nEdges
&& (((nEdges
& MatrixEdgeLeft
) != MatrixEdgeLeft
) || (nEdges
& (MatrixEdgeInside
|MatrixEdgeOpen
))))
2042 return true; // linke Kante fehlt oder offen
2044 nEdges
= aCol
[nCol2
].GetBlockMatrixEdges(nRow1
, nRow2
, MatrixEdgeRight
);
2045 // nicht 16 oder 1 oder 32
2046 if (nEdges
&& (((nEdges
& MatrixEdgeRight
) != MatrixEdgeRight
) || (nEdges
& (MatrixEdgeInside
|MatrixEdgeOpen
))))
2047 return true; // rechte Kante fehlt oder offen
2050 if ( nRow1
== nRow2
)
2051 { // obere und untere Zeile
2053 const sal_uInt16 n
= MatrixEdgeBottom
| MatrixEdgeTop
;
2054 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2056 nEdges
= aCol
[i
].GetBlockMatrixEdges( nRow1
, nRow1
, n
);
2059 if ( (nEdges
& n
) != n
)
2060 return true; // obere oder untere Kante fehlt
2061 if (nEdges
& MatrixEdgeLeft
)
2062 bOpen
= true; // linke Kante oeffnet, weitersehen
2064 return true; // es gibt was, was nicht geoeffnet wurde
2065 if (nEdges
& MatrixEdgeRight
)
2066 bOpen
= false; // rechte Kante schliesst
2070 return true; // es geht noch weiter
2076 // erst obere Zeile, dann untere Zeile
2077 for ( j
=0, nR
=nRow1
, n
=8; j
<2; j
++, nR
=nRow2
, n
=2 )
2080 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2082 nEdges
= aCol
[i
].GetBlockMatrixEdges( nR
, nR
, n
);
2085 // in oberere Zeile keine obere Kante bzw.
2086 // in unterer Zeile keine untere Kante
2087 if ( (nEdges
& n
) != n
)
2089 if (nEdges
& MatrixEdgeLeft
)
2090 bOpen
= true; // linke Kante oeffnet, weitersehen
2092 return true; // es gibt was, was nicht geoeffnet wurde
2093 if (nEdges
& MatrixEdgeRight
)
2094 bOpen
= false; // rechte Kante schliesst
2098 return true; // es geht noch weiter
2105 bool ScTable::HasSelectionMatrixFragment( const ScMarkData
& rMark
) const
2107 bool bFound
= false;
2108 for (SCCOL i
=0; i
<=MAXCOL
&& !bFound
; i
++)
2109 bFound
|= aCol
[i
].HasSelectionMatrixFragment(rMark
);
2114 bool ScTable::IsBlockEditable( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
,
2115 SCROW nRow2
, bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
2117 if ( !ValidColRow( nCol2
, nRow2
) )
2119 OSL_FAIL("IsBlockEditable: invalid column or row");
2120 if (pOnlyNotBecauseOfMatrix
)
2121 *pOnlyNotBecauseOfMatrix
= false;
2125 bool bIsEditable
= true;
2127 bIsEditable
= false;
2128 else if ( IsProtected() && !pDocument
->IsScenario(nTab
) )
2130 bIsEditable
= !HasAttrib( nCol1
, nRow1
, nCol2
, nRow2
, HASATTR_PROTECTED
);
2133 // If Sheet is protected and cells are not protected then
2134 // check the active scenario protect flag if this range is
2135 // on the active scenario range. Note the 'copy back' must also
2136 // be set to apply protection.
2137 sal_uInt16 nScenTab
= nTab
+1;
2138 while(pDocument
->IsScenario(nScenTab
))
2140 ScRange
aEditRange(nCol1
, nRow1
, nScenTab
, nCol2
, nRow2
, nScenTab
);
2141 if(pDocument
->IsActiveScenario(nScenTab
) && pDocument
->HasScenarioRange(nScenTab
, aEditRange
))
2144 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
2145 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
2152 else if (pDocument
->IsScenario(nTab
))
2154 // Determine if the preceding sheet is protected
2155 SCTAB nActualTab
= nTab
;
2160 while(pDocument
->IsScenario(nActualTab
));
2162 if(pDocument
->IsTabProtected(nActualTab
))
2164 ScRange
aEditRange(nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
2165 if(pDocument
->HasScenarioRange(nTab
, aEditRange
))
2168 pDocument
->GetScenarioFlags(nTab
,nFlags
);
2169 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
2175 if ( HasBlockMatrixFragment( nCol1
, nRow1
, nCol2
, nRow2
) )
2177 bIsEditable
= false;
2178 if ( pOnlyNotBecauseOfMatrix
)
2179 *pOnlyNotBecauseOfMatrix
= true;
2181 else if ( pOnlyNotBecauseOfMatrix
)
2182 *pOnlyNotBecauseOfMatrix
= false;
2184 else if ( pOnlyNotBecauseOfMatrix
)
2185 *pOnlyNotBecauseOfMatrix
= false;
2190 bool ScTable::IsSelectionEditable( const ScMarkData
& rMark
,
2191 bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
2193 bool bIsEditable
= true;
2195 bIsEditable
= false;
2196 else if ( IsProtected() && !pDocument
->IsScenario(nTab
) )
2198 if((bIsEditable
= !HasAttribSelection( rMark
, HASATTR_PROTECTED
)) != false)
2200 // If Sheet is protected and cells are not protected then
2201 // check the active scenario protect flag if this area is
2202 // in the active scenario range.
2203 ScRangeList aRanges
;
2204 rMark
.FillRangeListWithMarks( &aRanges
, false );
2205 SCTAB nScenTab
= nTab
+1;
2206 while(pDocument
->IsScenario(nScenTab
) && bIsEditable
)
2208 if(pDocument
->IsActiveScenario(nScenTab
))
2210 for (size_t i
=0, nRange
= aRanges
.size(); (i
< nRange
) && bIsEditable
; i
++ )
2212 ScRange aRange
= *aRanges
[ i
];
2213 if(pDocument
->HasScenarioRange(nScenTab
, aRange
))
2216 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
2217 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
2225 else if (pDocument
->IsScenario(nTab
))
2227 // Determine if the preceding sheet is protected
2228 SCTAB nActualTab
= nTab
;
2233 while(pDocument
->IsScenario(nActualTab
));
2235 if(pDocument
->IsTabProtected(nActualTab
))
2237 ScRangeList aRanges
;
2238 rMark
.FillRangeListWithMarks( &aRanges
, false );
2239 for (size_t i
= 0, nRange
= aRanges
.size(); (i
< nRange
) && bIsEditable
; i
++)
2241 ScRange aRange
= *aRanges
[ i
];
2242 if(pDocument
->HasScenarioRange(nTab
, aRange
))
2245 pDocument
->GetScenarioFlags(nTab
,nFlags
);
2246 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
2253 if ( HasSelectionMatrixFragment( rMark
) )
2255 bIsEditable
= false;
2256 if ( pOnlyNotBecauseOfMatrix
)
2257 *pOnlyNotBecauseOfMatrix
= true;
2259 else if ( pOnlyNotBecauseOfMatrix
)
2260 *pOnlyNotBecauseOfMatrix
= false;
2262 else if ( pOnlyNotBecauseOfMatrix
)
2263 *pOnlyNotBecauseOfMatrix
= false;
2269 void ScTable::LockTable()
2275 void ScTable::UnlockTable()
2281 OSL_FAIL("UnlockTable without LockTable");
2286 void ScTable::MergeSelectionPattern( ScMergePatternState
& rState
, const ScMarkData
& rMark
, bool bDeep
) const
2288 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2289 aCol
[i
].MergeSelectionPattern( rState
, rMark
, bDeep
);
2293 void ScTable::MergePatternArea( ScMergePatternState
& rState
, SCCOL nCol1
, SCROW nRow1
,
2294 SCCOL nCol2
, SCROW nRow2
, bool bDeep
) const
2296 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2297 aCol
[i
].MergePatternArea( rState
, nRow1
, nRow2
, bDeep
);
2301 void ScTable::MergeBlockFrame( SvxBoxItem
* pLineOuter
, SvxBoxInfoItem
* pLineInner
, ScLineFlags
& rFlags
,
2302 SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
) const
2304 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2306 PutInOrder(nStartCol
, nEndCol
);
2307 PutInOrder(nStartRow
, nEndRow
);
2308 for (SCCOL i
=nStartCol
; i
<=nEndCol
; i
++)
2309 aCol
[i
].MergeBlockFrame( pLineOuter
, pLineInner
, rFlags
,
2310 nStartRow
, nEndRow
, (i
==nStartCol
), nEndCol
-i
);
2315 void ScTable::ApplyBlockFrame( const SvxBoxItem
* pLineOuter
, const SvxBoxInfoItem
* pLineInner
,
2316 SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
)
2318 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2320 PutInOrder(nStartCol
, nEndCol
);
2321 PutInOrder(nStartRow
, nEndRow
);
2322 for (SCCOL i
=nStartCol
; i
<=nEndCol
; i
++)
2323 aCol
[i
].ApplyBlockFrame( pLineOuter
, pLineInner
,
2324 nStartRow
, nEndRow
, (i
==nStartCol
), nEndCol
-i
);
2329 void ScTable::ApplyPattern( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
)
2331 if (ValidColRow(nCol
,nRow
))
2332 aCol
[nCol
].ApplyPattern( nRow
, rAttr
);
2336 void ScTable::ApplyPatternArea( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2337 const ScPatternAttr
& rAttr
, ScEditDataArray
* pDataArray
)
2339 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2341 PutInOrder(nStartCol
, nEndCol
);
2342 PutInOrder(nStartRow
, nEndRow
);
2343 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2344 aCol
[i
].ApplyPatternArea(nStartRow
, nEndRow
, rAttr
, pDataArray
);
2348 bool ScTable::SetAttrEntries(SCCOL nCol
, ScAttrEntry
* pData
, SCSIZE nSize
)
2350 if (!ValidCol(nCol
))
2353 return aCol
[nCol
].SetAttrEntries(pData
, nSize
);
2356 void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange
& rRange
,
2357 const ScPatternAttr
& rPattern
, short nNewType
)
2359 SCCOL nEndCol
= rRange
.aEnd
.Col();
2360 for ( SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= nEndCol
; nCol
++ )
2362 aCol
[nCol
].ApplyPatternIfNumberformatIncompatible( rRange
, rPattern
, nNewType
);
2366 void ScTable::AddCondFormatData( const ScRangeList
& rRange
, sal_uInt32 nIndex
)
2368 size_t n
= rRange
.size();
2369 for(size_t i
= 0; i
< n
; ++i
)
2371 const ScRange
* pRange
= rRange
[i
];
2372 SCCOL nColStart
= pRange
->aStart
.Col();
2373 SCCOL nColEnd
= pRange
->aEnd
.Col();
2374 SCROW nRowStart
= pRange
->aStart
.Row();
2375 SCROW nRowEnd
= pRange
->aEnd
.Row();
2376 for(SCCOL nCol
= nColStart
; nCol
<= nColEnd
; ++nCol
)
2378 aCol
[nCol
].AddCondFormat(nRowStart
, nRowEnd
, nIndex
);
2383 void ScTable::RemoveCondFormatData( const ScRangeList
& rRange
, sal_uInt32 nIndex
)
2385 size_t n
= rRange
.size();
2386 for(size_t i
= 0; i
< n
; ++i
)
2388 const ScRange
* pRange
= rRange
[i
];
2389 SCCOL nColStart
= pRange
->aStart
.Col();
2390 SCCOL nColEnd
= pRange
->aEnd
.Col();
2391 SCROW nRowStart
= pRange
->aStart
.Row();
2392 SCROW nRowEnd
= pRange
->aEnd
.Row();
2393 for(SCCOL nCol
= nColStart
; nCol
<= nColEnd
; ++nCol
)
2395 aCol
[nCol
].RemoveCondFormat(nRowStart
, nRowEnd
, nIndex
);
2402 void ScTable::ApplyStyle( SCCOL nCol
, SCROW nRow
, const ScStyleSheet
& rStyle
)
2404 if (ValidColRow(nCol
,nRow
))
2405 aCol
[nCol
].ApplyStyle( nRow
, rStyle
);
2409 void ScTable::ApplyStyleArea( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
, const ScStyleSheet
& rStyle
)
2411 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2413 PutInOrder(nStartCol
, nEndCol
);
2414 PutInOrder(nStartRow
, nEndRow
);
2415 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2416 aCol
[i
].ApplyStyleArea(nStartRow
, nEndRow
, rStyle
);
2421 void ScTable::ApplySelectionStyle(const ScStyleSheet
& rStyle
, const ScMarkData
& rMark
)
2423 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2424 aCol
[i
].ApplySelectionStyle( rStyle
, rMark
);
2428 void ScTable::ApplySelectionLineStyle( const ScMarkData
& rMark
,
2429 const ::editeng::SvxBorderLine
* pLine
, bool bColorOnly
)
2431 if ( bColorOnly
&& !pLine
)
2434 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2435 aCol
[i
].ApplySelectionLineStyle( rMark
, pLine
, bColorOnly
);
2439 const ScStyleSheet
* ScTable::GetStyle( SCCOL nCol
, SCROW nRow
) const
2441 if (ValidColRow(nCol
, nRow
))
2442 return aCol
[nCol
].GetStyle(nRow
);
2448 const ScStyleSheet
* ScTable::GetSelectionStyle( const ScMarkData
& rMark
, bool& rFound
) const
2455 const ScStyleSheet
* pStyle
= NULL
;
2456 const ScStyleSheet
* pNewStyle
;
2458 for (SCCOL i
=0; i
<=MAXCOL
&& bEqual
; i
++)
2459 if (rMark
.HasMultiMarks(i
))
2461 pNewStyle
= aCol
[i
].GetSelectionStyle( rMark
, bColFound
);
2465 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
2466 bEqual
= false; // unterschiedliche
2471 return bEqual
? pStyle
: NULL
;
2475 const ScStyleSheet
* ScTable::GetAreaStyle( bool& rFound
, SCCOL nCol1
, SCROW nRow1
,
2476 SCCOL nCol2
, SCROW nRow2
) const
2483 const ScStyleSheet
* pStyle
= NULL
;
2484 const ScStyleSheet
* pNewStyle
;
2486 for (SCCOL i
=nCol1
; i
<=nCol2
&& bEqual
; i
++)
2488 pNewStyle
= aCol
[i
].GetAreaStyle(bColFound
, nRow1
, nRow2
);
2492 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
2493 bEqual
= false; // unterschiedliche
2498 return bEqual
? pStyle
: NULL
;
2502 bool ScTable::IsStyleSheetUsed( const ScStyleSheet
& rStyle
, bool bGatherAllStyles
) const
2504 bool bIsUsed
= false;
2506 for ( SCCOL i
=0; i
<=MAXCOL
; i
++ )
2508 if ( aCol
[i
].IsStyleSheetUsed( rStyle
, bGatherAllStyles
) )
2510 if ( !bGatherAllStyles
)
2520 void ScTable::StyleSheetChanged( const SfxStyleSheetBase
* pStyleSheet
, bool bRemoved
,
2522 double nPPTX
, double nPPTY
,
2523 const Fraction
& rZoomX
, const Fraction
& rZoomY
)
2525 ScFlatBoolRowSegments aUsedRows
;
2526 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
2527 aCol
[i
].FindStyleSheet(pStyleSheet
, aUsedRows
, bRemoved
);
2530 while (nRow
<= MAXROW
)
2532 ScFlatBoolRowSegments::RangeData aData
;
2533 if (!aUsedRows
.getRangeData(nRow
, aData
))
2537 SCROW nEndRow
= aData
.mnRow2
;
2539 SetOptimalHeight(nRow
, nEndRow
, 0, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, false);
2546 bool ScTable::ApplyFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2549 bool bChanged
= false;
2550 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2551 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2552 bChanged
|= aCol
[i
].ApplyFlags(nStartRow
, nEndRow
, nFlags
);
2557 bool ScTable::RemoveFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2560 bool bChanged
= false;
2561 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2562 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2563 bChanged
|= aCol
[i
].RemoveFlags(nStartRow
, nEndRow
, nFlags
);
2568 void ScTable::SetPattern( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
, bool bPutToPool
)
2570 if (ValidColRow(nCol
,nRow
))
2571 aCol
[nCol
].SetPattern( nRow
, rAttr
, bPutToPool
);
2575 void ScTable::ApplyAttr( SCCOL nCol
, SCROW nRow
, const SfxPoolItem
& rAttr
)
2577 if (ValidColRow(nCol
,nRow
))
2578 aCol
[nCol
].ApplyAttr( nRow
, rAttr
);
2582 void ScTable::ApplySelectionCache( SfxItemPoolCache
* pCache
, const ScMarkData
& rMark
,
2583 ScEditDataArray
* pDataArray
)
2585 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2586 aCol
[i
].ApplySelectionCache( pCache
, rMark
, pDataArray
);
2590 void ScTable::ChangeSelectionIndent( bool bIncrement
, const ScMarkData
& rMark
)
2592 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2593 aCol
[i
].ChangeSelectionIndent( bIncrement
, rMark
);
2597 void ScTable::ClearSelectionItems( const sal_uInt16
* pWhich
, const ScMarkData
& rMark
)
2599 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2600 aCol
[i
].ClearSelectionItems( pWhich
, rMark
);
2604 // Spaltenbreiten / Zeilenhoehen
2606 void ScTable::SetColWidth( SCCOL nCol
, sal_uInt16 nNewWidth
)
2608 if (ValidCol(nCol
) && pColWidth
)
2612 nNewWidth
= STD_COL_WIDTH
;
2615 if ( nNewWidth
!= pColWidth
[nCol
] )
2617 pColWidth
[nCol
] = nNewWidth
;
2618 InvalidatePageBreaks();
2623 OSL_FAIL("Invalid column number or no widths");
2627 void ScTable::SetColWidthOnly( SCCOL nCol
, sal_uInt16 nNewWidth
)
2629 if (!ValidCol(nCol
) || !pColWidth
)
2633 nNewWidth
= STD_COL_WIDTH
;
2635 if (nNewWidth
!= pColWidth
[nCol
])
2636 pColWidth
[nCol
] = nNewWidth
;
2639 void ScTable::SetRowHeight( SCROW nRow
, sal_uInt16 nNewHeight
)
2641 if (ValidRow(nRow
) && mpRowHeights
)
2645 OSL_FAIL("SetRowHeight: Row height zero");
2646 nNewHeight
= ScGlobal::nStdRowHeight
;
2649 sal_uInt16 nOldHeight
= mpRowHeights
->getValue(nRow
);
2650 if ( nNewHeight
!= nOldHeight
)
2652 mpRowHeights
->setValue(nRow
, nRow
, nNewHeight
);
2653 InvalidatePageBreaks();
2658 OSL_FAIL("Invalid row number or no heights");
2665 * Check if the new pixel size is different from the old size between
2668 bool lcl_pixelSizeChanged(
2669 ScFlatUInt16RowSegments
& rRowHeights
, SCROW nStartRow
, SCROW nEndRow
,
2670 sal_uInt16 nNewHeight
, double nPPTY
)
2672 long nNewPix
= static_cast<long>(nNewHeight
* nPPTY
);
2674 ScFlatUInt16RowSegments::ForwardIterator
aFwdIter(rRowHeights
);
2675 for (SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
2678 if (!aFwdIter
.getValue(nRow
, nHeight
))
2681 if (nHeight
!= nNewHeight
)
2683 bool bChanged
= (nNewPix
!= static_cast<long>(nHeight
* nPPTY
));
2688 // Skip ahead to the last position of the current range.
2689 nRow
= aFwdIter
.getLastPos();
2696 bool ScTable::SetRowHeightRange( SCROW nStartRow
, SCROW nEndRow
, sal_uInt16 nNewHeight
,
2697 double /* nPPTX */, double nPPTY
)
2699 bool bChanged
= false;
2700 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2704 OSL_FAIL("SetRowHeight: Row height zero");
2705 nNewHeight
= ScGlobal::nStdRowHeight
;
2708 bool bSingle
= false; // true = process every row for its own
2709 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2711 if (pDrawLayer
->HasObjectsInRows( nTab
, nStartRow
, nEndRow
))
2716 ScFlatUInt16RowSegments::RangeData aData
;
2717 mpRowHeights
->getRangeData(nStartRow
, aData
);
2718 if (nNewHeight
== aData
.mnValue
&& nEndRow
<= aData
.mnRow2
)
2719 bSingle
= false; // no difference in this range
2723 if (nEndRow
-nStartRow
< 20)
2726 bChanged
= lcl_pixelSizeChanged(*mpRowHeights
, nStartRow
, nEndRow
, nNewHeight
, nPPTY
);
2728 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2732 SCROW nMid
= (nStartRow
+nEndRow
) / 2;
2733 if (SetRowHeightRange( nStartRow
, nMid
, nNewHeight
, 1.0, 1.0 ))
2735 if (SetRowHeightRange( nMid
+1, nEndRow
, nNewHeight
, 1.0, 1.0 ))
2742 bChanged
= lcl_pixelSizeChanged(*mpRowHeights
, nStartRow
, nEndRow
, nNewHeight
, nPPTY
);
2744 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2748 InvalidatePageBreaks();
2752 OSL_FAIL("Invalid row number or no heights");
2758 void ScTable::SetRowHeightOnly( SCROW nStartRow
, SCROW nEndRow
, sal_uInt16 nNewHeight
)
2760 if (!ValidRow(nStartRow
) || !ValidRow(nEndRow
) || !mpRowHeights
)
2764 nNewHeight
= ScGlobal::nStdRowHeight
;
2766 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2769 void ScTable::SetManualHeight( SCROW nStartRow
, SCROW nEndRow
, bool bManual
)
2771 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && pRowFlags
)
2774 pRowFlags
->OrValue( nStartRow
, nEndRow
, CR_MANUALSIZE
);
2776 pRowFlags
->AndValue( nStartRow
, nEndRow
, sal::static_int_cast
<sal_uInt8
>(~CR_MANUALSIZE
));
2780 OSL_FAIL("Invalid row number or no column flags");
2785 sal_uInt16
ScTable::GetColWidth( SCCOL nCol
, bool bHiddenAsZero
) const
2787 OSL_ENSURE(ValidCol(nCol
),"wrong column number");
2789 if (ValidCol(nCol
) && pColFlags
&& pColWidth
)
2791 if (bHiddenAsZero
&& ColHidden(nCol
))
2794 return pColWidth
[nCol
];
2797 return (sal_uInt16
) STD_COL_WIDTH
;
2801 sal_uInt16
ScTable::GetOriginalWidth( SCCOL nCol
) const // immer die eingestellte
2803 OSL_ENSURE(ValidCol(nCol
),"wrong column number");
2805 if (ValidCol(nCol
) && pColWidth
)
2806 return pColWidth
[nCol
];
2808 return (sal_uInt16
) STD_COL_WIDTH
;
2812 sal_uInt16
ScTable::GetCommonWidth( SCCOL nEndCol
) const
2814 // get the width that is used in the largest continuous column range (up to nEndCol)
2816 if ( !ValidCol(nEndCol
) )
2818 OSL_FAIL("wrong column");
2822 sal_uInt16 nMaxWidth
= 0;
2823 sal_uInt16 nMaxCount
= 0;
2824 SCCOL nRangeStart
= 0;
2825 while ( nRangeStart
<= nEndCol
)
2827 // skip hidden columns
2828 while ( nRangeStart
<= nEndCol
&& ColHidden(nRangeStart
) )
2830 if ( nRangeStart
<= nEndCol
)
2832 sal_uInt16 nThisCount
= 0;
2833 sal_uInt16 nThisWidth
= pColWidth
[nRangeStart
];
2834 SCCOL nRangeEnd
= nRangeStart
;
2835 while ( nRangeEnd
<= nEndCol
&& pColWidth
[nRangeEnd
] == nThisWidth
)
2840 // skip hidden columns
2841 while ( nRangeEnd
<= nEndCol
&& ColHidden(nRangeEnd
) )
2845 if ( nThisCount
> nMaxCount
)
2847 nMaxCount
= nThisCount
;
2848 nMaxWidth
= nThisWidth
;
2851 nRangeStart
= nRangeEnd
; // next range
2859 sal_uInt16
ScTable::GetRowHeight( SCROW nRow
, SCROW
* pStartRow
, SCROW
* pEndRow
, bool bHiddenAsZero
) const
2861 OSL_ENSURE(ValidRow(nRow
),"Invalid row number");
2863 if (ValidRow(nRow
) && mpRowHeights
)
2865 if (bHiddenAsZero
&& RowHidden( nRow
, pStartRow
, pEndRow
))
2869 ScFlatUInt16RowSegments::RangeData aData
;
2870 if (!mpRowHeights
->getRangeData(nRow
, aData
))
2876 // TODO: What should we return in case the search fails?
2880 // If bHiddenAsZero, pStartRow and pEndRow were initialized to
2881 // boundaries of a non-hidden segment. Assume that the previous and
2882 // next segment are hidden then and limit the current height
2885 *pStartRow
= (bHiddenAsZero
? std::max( *pStartRow
, aData
.mnRow1
) : aData
.mnRow1
);
2887 *pEndRow
= (bHiddenAsZero
? std::min( *pEndRow
, aData
.mnRow2
) : aData
.mnRow2
);
2888 return aData
.mnValue
;
2897 return (sal_uInt16
) ScGlobal::nStdRowHeight
;
2902 sal_uLong
ScTable::GetRowHeight( SCROW nStartRow
, SCROW nEndRow
, bool bHiddenAsZero
) const
2904 OSL_ENSURE(ValidRow(nStartRow
) && ValidRow(nEndRow
),"wrong row number");
2906 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2908 sal_uLong nHeight
= 0;
2909 SCROW nRow
= nStartRow
;
2910 while (nRow
<= nEndRow
)
2912 SCROW nLastRow
= -1;
2913 if (!( ( RowHidden(nRow
, NULL
, &nLastRow
) ) && bHiddenAsZero
) )
2915 if (nLastRow
> nEndRow
)
2917 nHeight
+= mpRowHeights
->getSumValue(nRow
, nLastRow
);
2919 nRow
= nLastRow
+ 1;
2924 return (sal_uLong
) ((nEndRow
- nStartRow
+ 1) * ScGlobal::nStdRowHeight
);
2928 sal_uLong
ScTable::GetScaledRowHeight( SCROW nStartRow
, SCROW nEndRow
, double fScale
) const
2930 OSL_ENSURE(ValidRow(nStartRow
) && ValidRow(nEndRow
),"wrong row number");
2932 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2934 sal_uLong nHeight
= 0;
2935 SCROW nRow
= nStartRow
;
2936 while (nRow
<= nEndRow
)
2938 SCROW nLastRow
= -1;
2939 if (!RowHidden(nRow
, NULL
, &nLastRow
))
2941 if (nLastRow
> nEndRow
)
2944 // #i117315# can't use getSumValue, because individual values must be rounded
2945 while (nRow
<= nLastRow
)
2947 ScFlatUInt16RowSegments::RangeData aData
;
2948 if (!mpRowHeights
->getRangeData(nRow
, aData
))
2949 return nHeight
; // shouldn't happen
2951 SCROW nSegmentEnd
= std::min( nLastRow
, aData
.mnRow2
);
2953 // round-down a single height value, multiply resulting (pixel) values
2954 sal_uLong nOneHeight
= static_cast<sal_uLong
>( aData
.mnValue
* fScale
);
2955 nHeight
+= nOneHeight
* ( nSegmentEnd
+ 1 - nRow
);
2957 nRow
= nSegmentEnd
+ 1;
2960 nRow
= nLastRow
+ 1;
2965 return (sal_uLong
) ((nEndRow
- nStartRow
+ 1) * ScGlobal::nStdRowHeight
* fScale
);
2969 sal_uInt16
ScTable::GetOriginalHeight( SCROW nRow
) const // non-0 even if hidden
2971 OSL_ENSURE(ValidRow(nRow
),"wrong row number");
2973 if (ValidRow(nRow
) && mpRowHeights
)
2974 return mpRowHeights
->getValue(nRow
);
2976 return (sal_uInt16
) ScGlobal::nStdRowHeight
;
2980 // Spalten-/Zeilen-Flags
2983 SCROW
ScTable::GetHiddenRowCount( SCROW nRow
) const
2985 if (!ValidRow(nRow
))
2988 SCROW nLastRow
= -1;
2989 if (!RowHidden(nRow
, NULL
, &nLastRow
) || !ValidRow(nLastRow
))
2992 return nLastRow
- nRow
+ 1;
2996 //! ShowRows / DBShowRows zusammenfassen
2998 void ScTable::ShowCol(SCCOL nCol
, bool bShow
)
3002 bool bWasVis
= !ColHidden(nCol
);
3003 if (bWasVis
!= bShow
)
3005 SetColHidden(nCol
, nCol
, !bShow
);
3007 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3009 pCharts
->SetRangeDirty(ScRange( nCol
, 0, nTab
, nCol
, MAXROW
, nTab
));
3014 OSL_FAIL("Invalid column number or no flags");
3019 void ScTable::ShowRow(SCROW nRow
, bool bShow
)
3021 if (ValidRow(nRow
) && pRowFlags
)
3023 bool bWasVis
= !RowHidden(nRow
);
3024 if (bWasVis
!= bShow
)
3026 SetRowHidden(nRow
, nRow
, !bShow
);
3028 SetRowFiltered(nRow
, nRow
, false);
3029 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3031 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
3033 InvalidatePageBreaks();
3038 OSL_FAIL("Invalid row number or no flags");
3043 void ScTable::DBShowRow(SCROW nRow
, bool bShow
)
3045 if (ValidRow(nRow
) && pRowFlags
)
3047 // Filter-Flag immer setzen, auch wenn Hidden unveraendert
3048 bool bChanged
= SetRowHidden(nRow
, nRow
, !bShow
);
3049 SetRowFiltered(nRow
, nRow
, !bShow
);
3053 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3055 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
3058 UpdateOutlineRow( nRow
, nRow
, bShow
);
3060 InvalidatePageBreaks();
3065 OSL_FAIL("Invalid row number or no flags");
3070 void ScTable::DBShowRows(SCROW nRow1
, SCROW nRow2
, bool bShow
)
3072 SCROW nStartRow
= nRow1
;
3073 while (nStartRow
<= nRow2
)
3076 bool bWasVis
= !RowHiddenLeaf(nStartRow
, NULL
, &nEndRow
);
3077 if (nEndRow
> nRow2
)
3080 bool bChanged
= ( bWasVis
!= bShow
);
3082 SetRowHidden(nStartRow
, nEndRow
, !bShow
);
3083 SetRowFiltered(nStartRow
, nEndRow
, !bShow
);
3087 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3089 pCharts
->SetRangeDirty(ScRange( 0, nStartRow
, nTab
, MAXCOL
, nEndRow
, nTab
));
3092 nStartRow
= nEndRow
+ 1;
3095 // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
3096 // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
3099 UpdateOutlineRow( nRow1
, nRow2
, bShow
);
3103 void ScTable::ShowRows(SCROW nRow1
, SCROW nRow2
, bool bShow
)
3105 SCROW nStartRow
= nRow1
;
3107 // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
3108 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
3109 bool bHasObjects
= pDrawLayer
&& pDrawLayer
->HasObjectsInRows( nTab
, nRow1
, nRow2
);
3111 while (nStartRow
<= nRow2
)
3114 bool bWasVis
= !RowHiddenLeaf(nStartRow
, NULL
, &nEndRow
);
3115 if (nEndRow
> nRow2
)
3118 bool bChanged
= ( bWasVis
!= bShow
);
3120 SetRowHidden(nStartRow
, nEndRow
, !bShow
);
3122 SetRowFiltered(nStartRow
, nEndRow
, false);
3126 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3128 pCharts
->SetRangeDirty(ScRange( 0, nStartRow
, nTab
, MAXCOL
, nEndRow
, nTab
));
3130 InvalidatePageBreaks();
3133 nStartRow
= nEndRow
+ 1;
3138 // #i116164# set the flags for the whole range at once
3139 SetRowHidden(nRow1
, nRow2
, !bShow
);
3141 SetRowFiltered(nRow1
, nRow2
, false);
3145 bool ScTable::IsDataFiltered(SCCOL nColStart
, SCROW nRowStart
, SCCOL nColEnd
, SCROW nRowEnd
) const
3147 for (SCROW i
= nRowStart
; i
<= nRowEnd
; ++i
)
3152 for (SCCOL i
= nColStart
; i
<= nColEnd
; ++i
)
3160 bool ScTable::IsDataFiltered(const ScRange
& rRange
) const
3162 return IsDataFiltered(rRange
.aStart
.Col(), rRange
.aStart
.Row(),
3163 rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
3166 void ScTable::SetRowFlags( SCROW nRow
, sal_uInt8 nNewFlags
)
3168 if (ValidRow(nRow
) && pRowFlags
)
3169 pRowFlags
->SetValue( nRow
, nNewFlags
);
3172 OSL_FAIL("Invalid row number or no flags");
3177 void ScTable::SetRowFlags( SCROW nStartRow
, SCROW nEndRow
, sal_uInt8 nNewFlags
)
3179 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && pRowFlags
)
3180 pRowFlags
->SetValue( nStartRow
, nEndRow
, nNewFlags
);
3183 OSL_FAIL("Invalid row number(s) or no flags");
3188 sal_uInt8
ScTable::GetColFlags( SCCOL nCol
) const
3190 if (ValidCol(nCol
) && pColFlags
)
3191 return pColFlags
[nCol
];
3197 sal_uInt8
ScTable::GetRowFlags( SCROW nRow
) const
3199 if (ValidRow(nRow
) && pRowFlags
)
3200 return pRowFlags
->GetValue(nRow
);
3206 SCROW
ScTable::GetLastFlaggedRow() const
3208 SCROW nLastFound
= 0;
3211 SCROW nRow
= pRowFlags
->GetLastAnyBitAccess( 0, sal::static_int_cast
<sal_uInt8
>(CR_ALL
) );
3216 if (!maRowManualBreaks
.empty())
3217 nLastFound
= ::std::max(nLastFound
, *maRowManualBreaks
.rbegin());
3221 SCROW nRow
= mpHiddenRows
->findLastNotOf(false);
3223 nLastFound
= ::std::max(nLastFound
, nRow
);
3228 SCROW nRow
= mpFilteredRows
->findLastNotOf(false);
3230 nLastFound
= ::std::max(nLastFound
, nRow
);
3237 SCCOL
ScTable::GetLastChangedCol() const
3242 SCCOL nLastFound
= 0;
3243 for (SCCOL nCol
= 1; nCol
<= MAXCOL
; nCol
++)
3244 if ((pColFlags
[nCol
] & CR_ALL
) || (pColWidth
[nCol
] != STD_COL_WIDTH
))
3251 SCROW
ScTable::GetLastChangedRow() const
3256 SCROW nLastFlags
= GetLastFlaggedRow();
3258 // Find the last row position where the height is NOT the standard row
3260 // KOHEI: Test this to make sure it does what it's supposed to.
3261 SCROW nLastHeight
= mpRowHeights
->findLastNotOf(ScGlobal::nStdRowHeight
);
3262 if (!ValidRow(nLastHeight
))
3265 return std::max( nLastFlags
, nLastHeight
);
3269 bool ScTable::UpdateOutlineCol( SCCOL nStartCol
, SCCOL nEndCol
, bool bShow
)
3271 if (pOutlineTable
&& pColFlags
)
3273 ScBitMaskCompressedArray
< SCCOLROW
, sal_uInt8
> aArray( MAXCOL
, pColFlags
, MAXCOLCOUNT
);
3274 return pOutlineTable
->GetColArray()->ManualAction( nStartCol
, nEndCol
, bShow
, *this, true );
3281 bool ScTable::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, bool bShow
)
3283 if (pOutlineTable
&& pRowFlags
)
3284 return pOutlineTable
->GetRowArray()->ManualAction( nStartRow
, nEndRow
, bShow
, *this, false );
3290 void ScTable::ExtendHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
3292 // Column-wise expansion
3294 while (rX1
> 0 && ColHidden(rX1
-1))
3297 while (rX2
< MAXCOL
&& ColHidden(rX2
+1))
3300 // Row-wise expansion
3304 ScFlatBoolRowSegments::RangeData aData
;
3305 if (mpHiddenRows
->getRangeData(rY1
-1, aData
) && aData
.mbValue
)
3307 SCROW nStartRow
= aData
.mnRow1
;
3308 if (ValidRow(nStartRow
))
3315 if (RowHidden(rY2
+1, NULL
, &nEndRow
) && ValidRow(nEndRow
))
3321 void ScTable::StripHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
3323 while ( rX2
>rX1
&& ColHidden(rX2
) )
3325 while ( rX2
>rX1
&& ColHidden(rX1
) )
3330 ScFlatBoolRowSegments::RangeData aData
;
3331 if (mpHiddenRows
->getRangeData(rY2
, aData
) && aData
.mbValue
)
3333 SCROW nStartRow
= aData
.mnRow1
;
3334 if (ValidRow(nStartRow
) && nStartRow
>= rY1
)
3342 if (RowHidden(rY1
, NULL
, &nEndRow
) && ValidRow(nEndRow
) && nEndRow
<= rY2
)
3350 template< typename T
>
3351 short DiffSign( T a
, T b
)
3359 class OutlineArrayFinder
3364 ScOutlineArray
* mpArray
;
3368 OutlineArrayFinder(const ScRange
& rRef
, SCCOL nCol
, SCTAB nTab
, ScOutlineArray
* pArray
, bool bSizeChanged
) :
3369 maRef(rRef
), mnCol(nCol
), mnTab(nTab
), mpArray(pArray
),
3370 mbSizeChanged(bSizeChanged
) {}
3372 bool operator() (size_t nRow
, const ScFormulaCell
* pCell
)
3374 SCROW nRow2
= static_cast<SCROW
>(nRow
);
3376 if (!pCell
->HasRefListExpressibleAsOneReference(maRef
))
3379 if (maRef
.aStart
.Row() != nRow2
|| maRef
.aEnd
.Row() != nRow2
||
3380 maRef
.aStart
.Tab() != mnTab
|| maRef
.aEnd
.Tab() != mnTab
)
3383 if (DiffSign(maRef
.aStart
.Col(), mnCol
) != DiffSign(maRef
.aEnd
.Col(), mnCol
))
3386 return mpArray
->Insert(maRef
.aStart
.Col(), maRef
.aEnd
.Col(), mbSizeChanged
);
3392 void ScTable::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
)
3394 typedef mdds::flat_segment_tree
<SCROW
, bool> UsedRowsType
;
3396 bool bSizeChanged
= false;
3401 ScOutlineArray
* pArray
;
3404 StartOutlineTable();
3408 UsedRowsType
aUsed(0, MAXROW
+1, false);
3409 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3410 aCol
[nCol
].FindUsed(nStartRow
, nEndRow
, aUsed
);
3413 pArray
= pOutlineTable
->GetRowArray();
3414 for (nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
3417 SCROW nLastRow
= nRow
;
3418 aUsed
.search_tree(nRow
, bUsed
, NULL
, &nLastRow
);
3426 for (nCol
=nStartCol
; nCol
<=nEndCol
&& !bFound
; nCol
++)
3428 ScRefCellValue aCell
= aCol
[nCol
].GetCellValue(nRow
);
3430 if (aCell
.meType
!= CELLTYPE_FORMULA
)
3433 if (!aCell
.mpFormula
->HasRefListExpressibleAsOneReference(aRef
))
3436 if ( aRef
.aStart
.Col() == nCol
&& aRef
.aEnd
.Col() == nCol
&&
3437 aRef
.aStart
.Tab() == nTab
&& aRef
.aEnd
.Tab() == nTab
&&
3438 DiffSign( aRef
.aStart
.Row(), nRow
) ==
3439 DiffSign( aRef
.aEnd
.Row(), nRow
) )
3441 if (pArray
->Insert( aRef
.aStart
.Row(), aRef
.aEnd
.Row(), bSizeChanged
))
3450 pArray
= pOutlineTable
->GetColArray();
3451 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3453 if (aCol
[nCol
].IsEmptyData())
3456 OutlineArrayFinder
aFunc(aRef
, nCol
, nTab
, pArray
, bSizeChanged
);
3457 sc::FindFormula(aCol
[nCol
].maCells
, nStartRow
, nEndRow
, aFunc
);
3461 // CopyData - fuer Query in anderen Bereich
3463 void ScTable::CopyData( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
3464 SCCOL nDestCol
, SCROW nDestRow
, SCTAB nDestTab
)
3466 //! wenn fuer mehrere Zeilen benutzt, nach Spalten optimieren!
3468 ScAddress
aSrc( nStartCol
, nStartRow
, nTab
);
3469 ScAddress
aDest( nDestCol
, nDestRow
, nDestTab
);
3470 ScRange
aRange( aSrc
, aDest
);
3471 bool bThisTab
= ( nDestTab
== nTab
);
3472 SCROW nDestY
= nDestRow
;
3473 for (SCROW nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
3475 aSrc
.SetRow( nRow
);
3476 aDest
.SetRow( nDestY
);
3477 SCCOL nDestX
= nDestCol
;
3478 for (SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3480 aSrc
.SetCol( nCol
);
3481 aDest
.SetCol( nDestX
);
3483 aCell
.assign(*pDocument
, ScAddress(nCol
, nRow
, nTab
));
3485 if (aCell
.meType
== CELLTYPE_FORMULA
)
3487 sc::RefUpdateContext
aCxt(*pDocument
);
3488 aCxt
.meMode
= URM_COPY
;
3489 aCxt
.maRange
= aRange
;
3490 aCxt
.mnColDelta
= nDestCol
- nStartCol
;
3491 aCxt
.mnRowDelta
= nDestRow
- nStartRow
;
3492 aCxt
.mnTabDelta
= nDestTab
- nTab
;
3493 aCell
.mpFormula
->UpdateReference(aCxt
);
3494 aCell
.mpFormula
->aPos
= aDest
;
3499 aCell
.release(aCol
[nDestX
], nDestY
);
3500 SetPattern( nDestX
, nDestY
, *GetPattern( nCol
, nRow
), true );
3504 aCell
.release(*pDocument
, aDest
);
3505 pDocument
->SetPattern( aDest
, *GetPattern( nCol
, nRow
), true );
3515 bool ScTable::RefVisible(ScFormulaCell
* pCell
)
3519 if (pCell
->HasOneReference(aRef
))
3521 if (aRef
.aStart
.Col()==aRef
.aEnd
.Col() && aRef
.aStart
.Tab()==aRef
.aEnd
.Tab())
3524 if (!RowFiltered(aRef
.aStart
.Row(), NULL
, &nEndRow
))
3525 // row not filtered.
3526 nEndRow
= ::std::numeric_limits
<SCROW
>::max();
3528 if (!ValidRow(nEndRow
) || nEndRow
< aRef
.aEnd
.Row())
3529 return true; // at least partly visible
3530 return false; // completely invisible
3534 return true; // irgendwie anders
3538 void ScTable::GetUpperCellString(SCCOL nCol
, SCROW nRow
, OUString
& rStr
)
3540 GetInputString(nCol
, nRow
, rStr
);
3541 rStr
= ScGlobal::pCharClass
->uppercase(rStr
.trim());
3545 // Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
3547 void ScTable::SetDrawPageSize(bool bResetStreamValid
, bool bUpdateNoteCaptionPos
)
3549 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
3552 double fValX
= GetColOffset( MAXCOL
+ 1 ) * HMM_PER_TWIPS
;
3553 double fValY
= GetRowOffset( MAXROW
+ 1 ) * HMM_PER_TWIPS
;
3554 const long nMax
= ::std::numeric_limits
<long>::max();
3555 // #i113884# Avoid int32 overflow with possible negative results than can cause bad effects.
3556 // If the draw page size is smaller than all rows, only the bottom of the sheet is affected.
3557 long x
= ( fValX
> (double)nMax
) ? nMax
: (long) fValX
;
3558 long y
= ( fValY
> (double)nMax
) ? nMax
: (long) fValY
;
3560 if ( IsLayoutRTL() ) // IsNegativePage
3563 pDrawLayer
->SetPageSize( static_cast<sal_uInt16
>(nTab
), Size( x
, y
), bUpdateNoteCaptionPos
);
3566 // #i102616# actions that modify the draw page size count as sheet modification
3567 // (exception: InitDrawLayer)
3568 if (bResetStreamValid
&& IsStreamValid())
3569 SetStreamValid(false);
3572 void ScTable::SetRangeName(ScRangeName
* pNew
)
3577 //fdo#39792: mark stream as invalid, otherwise new ScRangeName will not be written to file
3578 if (IsStreamValid())
3579 SetStreamValid(false);
3582 ScRangeName
* ScTable::GetRangeName() const
3585 mpRangeName
= new ScRangeName
;
3590 sal_uLong
ScTable::GetRowOffset( SCROW nRow
, bool bHiddenAsZero
) const
3593 if ( mpHiddenRows
&& mpRowHeights
)
3598 return GetRowHeight(0, NULL
, NULL
, bHiddenAsZero
);
3600 n
= GetTotalRowHeight(0, nRow
-1, bHiddenAsZero
);
3601 #if OSL_DEBUG_LEVEL > 0
3602 if (n
== ::std::numeric_limits
<unsigned long>::max())
3603 OSL_FAIL("ScTable::GetRowOffset: row heights overflow");
3608 OSL_FAIL("GetRowOffset: Data missing");
3613 SCROW
ScTable::GetRowForHeight(sal_uLong nHeight
) const
3615 sal_uInt32 nSum
= 0;
3617 ScFlatBoolRowSegments::RangeData aData
;
3618 for (SCROW nRow
= 0; nRow
<= MAXROW
; ++nRow
)
3620 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
3625 nRow
= aData
.mnRow2
;
3629 sal_uInt32 nNew
= mpRowHeights
->getValue(nRow
);
3633 return nRow
< MAXROW
? nRow
+ 1 : MAXROW
;
3640 sal_uLong
ScTable::GetColOffset( SCCOL nCol
, bool bHiddenAsZero
) const
3646 for( i
= 0; i
< nCol
; i
++ )
3647 if (!( bHiddenAsZero
&& ColHidden(i
) ))
3652 OSL_FAIL("GetColumnOffset: Data missing");
3657 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */