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"
52 #include "tabprotection.hxx"
53 #include "columnspanset.hxx"
54 #include <rowheightcontext.hxx>
55 #include <refhint.hxx>
57 #include "scitems.hxx"
58 #include <editeng/boxitem.hxx>
59 #include <editeng/editobj.hxx>
60 #include <svl/poolcach.hxx>
61 #include <unotools/charclass.hxx>
63 #include <svl/PasswordHelper.hxx>
64 #include <unotools/transliterationwrapper.hxx>
68 class ColumnRegroupFormulaCells
71 std::vector
<ScAddress
>* mpGroupPos
;
74 ColumnRegroupFormulaCells( ScColumn
* pCols
, std::vector
<ScAddress
>* pGroupPos
) :
75 mpCols(pCols
), mpGroupPos(pGroupPos
) {}
77 void operator() (SCCOL nCol
)
79 mpCols
[nCol
].RegroupFormulaCells(mpGroupPos
);
85 sal_uInt16
ScTable::GetTextWidth(SCCOL nCol
, SCROW nRow
) const
87 return aCol
[nCol
].GetTextWidth(nRow
);
90 bool ScTable::SetOutlineTable( const ScOutlineTable
* pNewOutline
)
92 sal_uInt16 nOldSizeX
= 0;
93 sal_uInt16 nOldSizeY
= 0;
94 sal_uInt16 nNewSizeX
= 0;
95 sal_uInt16 nNewSizeY
= 0;
99 nOldSizeX
= pOutlineTable
->GetColArray().GetDepth();
100 nOldSizeY
= pOutlineTable
->GetRowArray().GetDepth();
101 delete pOutlineTable
;
106 pOutlineTable
= new ScOutlineTable( *pNewOutline
);
107 nNewSizeX
= pOutlineTable
->GetColArray().GetDepth();
108 nNewSizeY
= pOutlineTable
->GetRowArray().GetDepth();
111 pOutlineTable
= NULL
;
113 return ( nNewSizeX
!= nOldSizeX
|| nNewSizeY
!= nOldSizeY
); // changed size?
116 void ScTable::StartOutlineTable()
119 pOutlineTable
= new ScOutlineTable
;
122 void ScTable::SetSheetEvents( const ScSheetEvents
* pNew
)
126 pSheetEvents
= new ScSheetEvents(*pNew
);
130 SetCalcNotification( false ); // discard notifications before the events were set
133 SetStreamValid(false);
136 void ScTable::SetCalcNotification( bool bSet
)
138 bCalcNotification
= bSet
;
141 bool ScTable::TestInsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
) const
145 if ( nStartCol
==0 && nEndCol
==MAXCOL
&& pOutlineTable
)
146 bTest
= pOutlineTable
->TestInsertRow(nSize
);
148 for (SCCOL i
=nStartCol
; (i
<=nEndCol
) && bTest
; i
++)
149 bTest
= aCol
[i
].TestInsertRow(nStartRow
, nSize
);
154 void ScTable::InsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
)
156 if (nStartCol
==0 && nEndCol
==MAXCOL
)
158 if (mpRowHeights
&& pRowFlags
)
160 mpRowHeights
->insertSegment(nStartRow
, nSize
, false);
161 sal_uInt8 nNewFlags
= pRowFlags
->Insert( nStartRow
, nSize
);
162 // only copy manual size flag, clear all others
163 if (nNewFlags
&& (nNewFlags
!= CR_MANUALSIZE
))
164 pRowFlags
->SetValue( nStartRow
, nStartRow
+ nSize
- 1,
165 nNewFlags
& CR_MANUALSIZE
);
169 pOutlineTable
->InsertRow( nStartRow
, nSize
);
171 mpFilteredRows
->insertSegment(nStartRow
, nSize
, true);
172 mpHiddenRows
->insertSegment(nStartRow
, nSize
, true);
174 if (!maRowManualBreaks
.empty())
176 // Copy all breaks up to nStartRow (non-inclusive).
177 ::std::set
<SCROW
>::iterator itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
178 ::std::set
<SCROW
> aNewBreaks(maRowManualBreaks
.begin(), itr1
);
180 // Copy all breaks from nStartRow (inclusive) to the last element,
181 // but add nSize to each value.
182 ::std::set
<SCROW
>::iterator itr2
= maRowManualBreaks
.end();
183 for (; itr1
!= itr2
; ++itr1
)
184 aNewBreaks
.insert(static_cast<SCROW
>(*itr1
+ nSize
));
186 maRowManualBreaks
.swap(aNewBreaks
);
190 for (SCCOL j
=nStartCol
; j
<=nEndCol
; j
++)
191 aCol
[j
].InsertRow( nStartRow
, nSize
);
193 mpCondFormatList
->InsertRow(nTab
, nStartCol
, nEndCol
, nStartRow
, nSize
);
195 InvalidatePageBreaks();
198 // TODO: In the future we may want to check if the table has been
199 // really modified before setting the stream invalid.
200 SetStreamValid(false);
203 void ScTable::DeleteRow(
204 const sc::ColumnSet
& rRegroupCols
, SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
,
205 bool* pUndoOutline
, std::vector
<ScAddress
>* pGroupPos
)
207 if (nStartCol
==0 && nEndCol
==MAXCOL
)
210 pRowFlags
->Remove( nStartRow
, nSize
);
213 mpRowHeights
->removeSegment(nStartRow
, nStartRow
+nSize
);
216 if (pOutlineTable
->DeleteRow( nStartRow
, nSize
))
218 *pUndoOutline
= true;
220 mpFilteredRows
->removeSegment(nStartRow
, nStartRow
+nSize
);
221 mpHiddenRows
->removeSegment(nStartRow
, nStartRow
+nSize
);
223 if (!maRowManualBreaks
.empty())
225 // Erase all manual breaks between nStartRow and nStartRow + nSize - 1 (inclusive).
226 std::set
<SCROW
>::iterator itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
227 std::set
<SCROW
>::iterator itr2
= maRowManualBreaks
.upper_bound(static_cast<SCROW
>(nStartRow
+ nSize
- 1));
228 maRowManualBreaks
.erase(itr1
, itr2
);
230 // Copy all breaks from the 1st element up to nStartRow to the new container.
231 itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
232 ::std::set
<SCROW
> aNewBreaks(maRowManualBreaks
.begin(), itr1
);
234 // Copy all breaks from nStartRow to the last element, but subtract each value by nSize.
235 itr2
= maRowManualBreaks
.end();
236 for (; itr1
!= itr2
; ++itr1
)
237 aNewBreaks
.insert(static_cast<SCROW
>(*itr1
- nSize
));
239 maRowManualBreaks
.swap(aNewBreaks
);
243 { // scope for bulk broadcast
244 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
245 for (SCCOL j
=nStartCol
; j
<=nEndCol
; j
++)
246 aCol
[j
].DeleteRow(nStartRow
, nSize
, pGroupPos
);
249 std::vector
<SCCOL
> aRegroupCols
;
250 rRegroupCols
.getColumns(nTab
, aRegroupCols
);
252 aRegroupCols
.begin(), aRegroupCols
.end(), ColumnRegroupFormulaCells(aCol
, pGroupPos
));
254 InvalidatePageBreaks();
257 // TODO: In the future we may want to check if the table has been
258 // really modified before setting the stream invalid.
259 SetStreamValid(false);
262 bool ScTable::TestInsertCol( SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
) const
266 if ( nStartRow
==0 && nEndRow
==MAXROW
&& pOutlineTable
)
267 bTest
= pOutlineTable
->TestInsertCol(nSize
);
269 if ( nSize
> static_cast<SCSIZE
>(MAXCOL
) )
272 for (SCCOL i
=MAXCOL
; (i
+static_cast<SCCOL
>(nSize
)>MAXCOL
) && bTest
; i
--)
273 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 // Copy all breaks up to nStartCol (non-inclusive).
299 ::std::set
<SCCOL
>::iterator itr1
= maColManualBreaks
.lower_bound(nStartCol
);
300 ::std::set
<SCCOL
> aNewBreaks(maColManualBreaks
.begin(), itr1
);
302 // Copy all breaks from nStartCol (inclusive) to the last element,
303 // but add nSize to each value.
304 ::std::set
<SCCOL
>::iterator itr2
= maColManualBreaks
.end();
305 for (; itr1
!= itr2
; ++itr1
)
306 aNewBreaks
.insert(static_cast<SCCOL
>(*itr1
+ nSize
));
308 maColManualBreaks
.swap(aNewBreaks
);
312 if ((nStartRow
== 0) && (nEndRow
== MAXROW
))
314 for (SCSIZE i
=0; i
< nSize
; i
++)
315 for (SCCOL nCol
= MAXCOL
; nCol
> nStartCol
; nCol
--)
316 aCol
[nCol
].SwapCol(aCol
[nCol
-1]);
320 for (SCSIZE i
=0; static_cast<SCCOL
>(i
+nSize
)+nStartCol
<= MAXCOL
; i
++)
321 aCol
[MAXCOL
- nSize
- i
].MoveTo(nStartRow
, nEndRow
, aCol
[MAXCOL
- i
]);
324 std::vector
<SCCOL
> aRegroupCols
;
325 rRegroupCols
.getColumns(nTab
, aRegroupCols
);
326 std::for_each(aRegroupCols
.begin(), aRegroupCols
.end(), ColumnRegroupFormulaCells(aCol
, NULL
));
328 if (nStartCol
>0) // copy old attributes
330 sal_uInt16 nWhichArray
[2];
331 nWhichArray
[0] = ATTR_MERGE
;
334 sc::CopyToDocContext
aCxt(*pDocument
);
335 for (SCSIZE i
=0; i
<nSize
; i
++)
337 aCol
[nStartCol
-1].CopyToColumn(aCxt
, nStartRow
, nEndRow
, IDF_ATTRIB
,
338 false, aCol
[nStartCol
+i
] );
339 aCol
[nStartCol
+i
].RemoveFlags( nStartRow
, nEndRow
,
340 SC_MF_HOR
| SC_MF_VER
| SC_MF_AUTO
);
341 aCol
[nStartCol
+i
].ClearItems( nStartRow
, nEndRow
, nWhichArray
);
345 mpCondFormatList
->InsertCol(nTab
, nStartRow
, nEndRow
, nStartCol
, nSize
);
347 InvalidatePageBreaks();
350 // TODO: In the future we may want to check if the table has been
351 // really modified before setting the stream invalid.
352 SetStreamValid(false);
355 void ScTable::DeleteCol(
356 const sc::ColumnSet
& rRegroupCols
, SCCOL nStartCol
, SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
, bool* pUndoOutline
)
358 if (nStartRow
==0 && nEndRow
==MAXROW
)
360 if (pColWidth
&& pColFlags
)
362 memmove( &pColWidth
[nStartCol
], &pColWidth
[nStartCol
+nSize
],
363 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColWidth
[0]) );
364 memmove( &pColFlags
[nStartCol
], &pColFlags
[nStartCol
+nSize
],
365 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColFlags
[0]) );
368 if (pOutlineTable
->DeleteCol( nStartCol
, nSize
))
370 *pUndoOutline
= true;
372 SCCOL nRmSize
= nStartCol
+ static_cast<SCCOL
>(nSize
);
373 mpHiddenCols
->removeSegment(nStartCol
, nRmSize
);
374 mpFilteredCols
->removeSegment(nStartCol
, nRmSize
);
376 if (!maColManualBreaks
.empty())
378 // Erase all manual breaks between nStartCol and nStartCol + nSize - 1 (inclusive).
379 std::set
<SCCOL
>::iterator itr1
= maColManualBreaks
.lower_bound(nStartCol
);
380 std::set
<SCCOL
>::iterator itr2
= maColManualBreaks
.upper_bound(static_cast<SCCOL
>(nStartCol
+ nSize
- 1));
381 maColManualBreaks
.erase(itr1
, itr2
);
383 // Copy all breaks from the 1st element up to nStartCol to the new container.
384 itr1
= maColManualBreaks
.lower_bound(nStartCol
);
385 ::std::set
<SCCOL
> aNewBreaks(maColManualBreaks
.begin(), itr1
);
387 // Copy all breaks from nStartCol to the last element, but subtract each value by nSize.
388 itr2
= maColManualBreaks
.end();
389 for (; itr1
!= itr2
; ++itr1
)
390 aNewBreaks
.insert(static_cast<SCCOL
>(*itr1
- nSize
));
392 maColManualBreaks
.swap(aNewBreaks
);
396 for (SCSIZE i
= 0; i
< nSize
; i
++)
397 aCol
[nStartCol
+ i
].DeleteArea(nStartRow
, nEndRow
, IDF_ALL
, false);
399 if ((nStartRow
== 0) && (nEndRow
== MAXROW
))
401 for (SCSIZE i
=0; i
< nSize
; i
++)
402 for (SCCOL nCol
= nStartCol
; nCol
< MAXCOL
; nCol
++)
403 aCol
[nCol
].SwapCol(aCol
[nCol
+1]);
407 for (SCSIZE i
=0; static_cast<SCCOL
>(i
+nSize
)+nStartCol
<= MAXCOL
; i
++)
408 aCol
[nStartCol
+ nSize
+ i
].MoveTo(nStartRow
, nEndRow
, aCol
[nStartCol
+ i
]);
411 std::vector
<SCCOL
> aRegroupCols
;
412 rRegroupCols
.getColumns(nTab
, aRegroupCols
);
413 std::for_each(aRegroupCols
.begin(), aRegroupCols
.end(), ColumnRegroupFormulaCells(aCol
, NULL
));
415 InvalidatePageBreaks();
418 // TODO: In the future we may want to check if the table has been
419 // really modified before setting the stream invalid.
420 SetStreamValid(false);
423 void ScTable::DeleteArea(
424 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, InsertDeleteFlags nDelFlag
,
425 bool bBroadcast
, sc::ColumnSpanSet
* pBroadcastSpans
)
427 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
428 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
429 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
431 { // scope for bulk broadcast
432 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
433 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
434 aCol
[i
].DeleteArea(nRow1
, nRow2
, nDelFlag
, bBroadcast
, pBroadcastSpans
);
437 // Zellschutz auf geschuetzter Tabelle nicht setzen
439 if ( IsProtected() && (nDelFlag
& IDF_ATTRIB
) )
441 ScPatternAttr
aPattern(pDocument
->GetPool());
442 aPattern
.GetItemSet().Put( ScProtectionAttr( false ) );
443 ApplyPatternArea( nCol1
, nRow1
, nCol2
, nRow2
, aPattern
);
446 if( nDelFlag
& IDF_ATTRIB
)
447 mpCondFormatList
->DeleteArea( nCol1
, nRow1
, nCol2
, nRow2
);
451 // TODO: In the future we may want to check if the table has been
452 // really modified before setting the stream invalid.
453 SetStreamValid(false);
456 void ScTable::DeleteSelection( InsertDeleteFlags nDelFlag
, const ScMarkData
& rMark
, bool bBroadcast
)
458 { // scope for bulk broadcast
459 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
460 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
461 aCol
[i
].DeleteSelection(nDelFlag
, rMark
, bBroadcast
);
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() );
475 // Do not set protected cell in a protected sheet
477 if ( IsProtected() && (nDelFlag
& IDF_ATTRIB
) )
479 ScDocumentPool
* pPool
= pDocument
->GetPool();
480 SfxItemSet
aSet( *pPool
, ATTR_PATTERN_START
, ATTR_PATTERN_END
);
481 aSet
.Put( ScProtectionAttr( false ) );
482 SfxItemPoolCache
aCache( pPool
, &aSet
);
483 ApplySelectionCache( &aCache
, rMark
);
487 // TODO: In the future we may want to check if the table has been
488 // really modified before setting the stream invalid.
489 SetStreamValid(false);
492 // pTable = Clipboard
493 void ScTable::CopyToClip(
494 sc::CopyToClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
497 if (!ValidColRow(nCol1
, nRow1
) || !ValidColRow(nCol2
, nRow2
))
501 //local range names need to be copied first for formula cells
502 if (!pTable
->mpRangeName
&& mpRangeName
)
503 pTable
->mpRangeName
= new ScRangeName(*mpRangeName
);
507 for ( i
= nCol1
; i
<= nCol2
; i
++)
508 aCol
[i
].CopyToClip(rCxt
, nRow1
, nRow2
, pTable
->aCol
[i
]); // notes are handled at column level
510 // copy widths/heights, and only "hidden", "filtered" and "manual" flags
511 // also for all preceding columns/rows, to have valid positions for drawing objects
513 if (pColWidth
&& pTable
->pColWidth
)
514 for (i
=0; i
<=nCol2
; i
++)
515 pTable
->pColWidth
[i
] = pColWidth
[i
];
517 pTable
->CopyColHidden(*this, 0, nCol2
);
518 pTable
->CopyColFiltered(*this, 0, nCol2
);
520 pTable
->SetAnonymousDBData(new ScDBData(*pDBDataNoName
));
522 if (pRowFlags
&& pTable
->pRowFlags
&& mpRowHeights
&& pTable
->mpRowHeights
)
524 pTable
->pRowFlags
->CopyFromAnded( *pRowFlags
, 0, nRow2
, CR_MANUALSIZE
);
525 pTable
->CopyRowHeight(*this, 0, nRow2
, 0);
528 pTable
->CopyRowHidden(*this, 0, nRow2
);
529 pTable
->CopyRowFiltered(*this, 0, nRow2
);
531 // If necessary replace formulas with values
534 for (i
= nCol1
; i
<= nCol2
; i
++)
535 pTable
->aCol
[i
].RemoveProtected(nRow1
, nRow2
);
537 pTable
->mpCondFormatList
.reset(new ScConditionalFormatList(pTable
->pDocument
, *mpCondFormatList
));
540 void ScTable::CopyToClip(
541 sc::CopyToClipContext
& rCxt
, const ScRangeList
& rRanges
, ScTable
* pTable
)
543 ScRangeList
aRanges(rRanges
);
544 for ( size_t i
= 0, nListSize
= aRanges
.size(); i
< nListSize
; ++i
)
546 ScRange
* p
= aRanges
[ i
];
548 rCxt
, p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), pTable
);
552 void ScTable::CopyStaticToDocument(
553 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, const SvNumberFormatterMergeMap
& rMap
, ScTable
* pDestTab
)
558 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
560 ScColumn
& rSrcCol
= aCol
[i
];
561 ScColumn
& rDestCol
= pDestTab
->aCol
[i
];
562 rSrcCol
.CopyStaticToDocument(nRow1
, nRow2
, rMap
, rDestCol
);
566 void ScTable::CopyCellToDocument(SCCOL nSrcCol
, SCROW nSrcRow
, SCCOL nDestCol
, SCROW nDestRow
, ScTable
& rDestTab
)
568 if (!ValidColRow(nSrcCol
, nSrcRow
) || !ValidColRow(nDestCol
, nDestRow
))
571 ScColumn
& rSrcCol
= aCol
[nSrcCol
];
572 ScColumn
& rDestCol
= rDestTab
.aCol
[nDestCol
];
573 rSrcCol
.CopyCellToDocument(nSrcRow
, nDestRow
, rDestCol
);
576 void ScTable::CopyConditionalFormat( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
577 SCsCOL nDx
, SCsROW nDy
, ScTable
* pTable
)
579 ScRange
aOldRange( nCol1
- nDx
, nRow1
- nDy
, pTable
->nTab
, nCol2
- nDx
, nRow2
- nDy
, pTable
->nTab
);
580 ScRange
aNewRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
581 bool bSameDoc
= pDocument
== pTable
->pDocument
;
583 for(ScConditionalFormatList::const_iterator itr
= pTable
->mpCondFormatList
->begin(),
584 itrEnd
= pTable
->mpCondFormatList
->end(); itr
!= itrEnd
; ++itr
)
586 const ScRangeList
& rCondFormatRange
= itr
->GetRange();
587 if(!rCondFormatRange
.Intersects( aOldRange
))
590 ScRangeList aIntersectedRange
= rCondFormatRange
.GetIntersectedRange(aOldRange
);
591 ScConditionalFormat
* pNewFormat
= itr
->Clone(pDocument
);
593 pNewFormat
->SetRange(aIntersectedRange
);
594 sc::RefUpdateContext
aRefCxt(*pDocument
);
595 aRefCxt
.meMode
= URM_COPY
;
596 aRefCxt
.maRange
= aNewRange
;
597 aRefCxt
.mnColDelta
= nDx
;
598 aRefCxt
.mnRowDelta
= nDy
;
599 aRefCxt
.mnTabDelta
= nTab
- pTable
->nTab
;
600 pNewFormat
->UpdateReference(aRefCxt
, true);
603 for(ScConditionalFormatList::const_iterator itrCond
= mpCondFormatList
->begin();
604 itrCond
!= mpCondFormatList
->end(); ++itrCond
)
606 if(itrCond
->GetKey() > nMax
)
607 nMax
= itrCond
->GetKey();
609 pNewFormat
->SetKey(nMax
+ 1);
610 mpCondFormatList
->InsertNew(pNewFormat
);
614 for(size_t i
= 0, n
= pNewFormat
->size();
618 const ScFormatEntry
* pEntry
= pNewFormat
->GetEntry(i
);
619 if(pEntry
->GetType() == condformat::CONDITION
)
620 aStyleName
= static_cast<const ScCondFormatEntry
*>(pEntry
)->GetStyle();
621 else if(pEntry
->GetType() == condformat::DATE
)
622 aStyleName
= static_cast<const ScCondDateFormatEntry
*>(pEntry
)->GetStyleName();
624 if(!aStyleName
.isEmpty())
626 if(pDocument
->GetStyleSheetPool()->Find(aStyleName
, SFX_STYLE_FAMILY_PARA
))
629 pDocument
->GetStyleSheetPool()->CopyStyleFrom(
630 pTable
->pDocument
->GetStyleSheetPool(), aStyleName
, SFX_STYLE_FAMILY_PARA
);
635 pDocument
->AddCondFormatData( pNewFormat
->GetRange(), nTab
, pNewFormat
->GetKey() );
639 bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition
& rBlockPos
, SCCOL nCol
)
644 return aCol
[nCol
].InitBlockPosition(rBlockPos
);
647 void ScTable::CopyFromClip(
648 sc::CopyFromClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
649 SCsCOL nDx
, SCsROW nDy
, ScTable
* pTable
)
657 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
659 for ( SCCOL i
= nCol1
; i
<= nCol2
; i
++)
660 aCol
[i
].CopyFromClip(rCxt
, nRow1
, nRow2
, nDy
, pTable
->aCol
[i
- nDx
]); // notes are handles at column level
662 if (rCxt
.getInsertFlag() & IDF_ATTRIB
)
664 // make sure that there are no old references to the cond formats
665 sal_uInt16 nWhichArray
[2];
666 nWhichArray
[0] = ATTR_CONDITIONAL
;
668 for ( SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
669 aCol
[i
].ClearItems(nRow1
, nRow2
, nWhichArray
);
672 if ((rCxt
.getInsertFlag() & IDF_ATTRIB
) != IDF_NONE
)
674 if (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pTable
->pColWidth
)
675 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
676 pColWidth
[i
] = pTable
->pColWidth
[i
-nDx
];
678 if (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pTable
->mpRowHeights
&&
679 pRowFlags
&& pTable
->pRowFlags
)
681 CopyRowHeight(*pTable
, nRow1
, nRow2
, -nDy
);
682 // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
683 for (SCROW j
=nRow1
; j
<=nRow2
; j
++)
685 if ( pTable
->pRowFlags
->GetValue(j
-nDy
) & CR_MANUALSIZE
)
686 pRowFlags
->OrValue( j
, CR_MANUALSIZE
);
688 pRowFlags
->AndValue( j
, sal::static_int_cast
<sal_uInt8
>(~CR_MANUALSIZE
));
692 // Do not set protected cell in a protected sheet
693 if (IsProtected() && (rCxt
.getInsertFlag() & IDF_ATTRIB
))
695 ScPatternAttr
aPattern(pDocument
->GetPool());
696 aPattern
.GetItemSet().Put( ScProtectionAttr( false ) );
697 ApplyPatternArea( nCol1
, nRow1
, nCol2
, nRow2
, aPattern
);
700 // create deep copies for conditional formatting
701 CopyConditionalFormat( nCol1
, nRow1
, nCol2
, nRow2
, nDx
, nDy
, pTable
);
706 void ScTable::MixData(
707 sc::MixDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
708 sal_uInt16 nFunction
, bool bSkipEmpty
, const ScTable
* pSrcTab
)
710 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
711 aCol
[i
].MixData(rCxt
, nRow1
, nRow2
, nFunction
, bSkipEmpty
, pSrcTab
->aCol
[i
]);
714 // Selection form this document
715 void ScTable::MixMarked(
716 sc::MixDocContext
& rCxt
, const ScMarkData
& rMark
, sal_uInt16 nFunction
,
717 bool bSkipEmpty
, const ScTable
* pSrcTab
)
719 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
720 aCol
[i
].MixMarked(rCxt
, rMark
, nFunction
, bSkipEmpty
, pSrcTab
->aCol
[i
]);
725 class TransClipHandler
735 ScAddress
getDestPos(size_t nRow
) const
737 return ScAddress(static_cast<SCCOL
>(nRow
-mnTopRow
), mnTransRow
, mrClipTab
.GetTab());
740 ScFormulaCell
* createRefCell(size_t nSrcRow
, const ScAddress
& rDestPos
) const
742 ScAddress
aSrcPos(mnSrcCol
, nSrcRow
, mnSrcTab
);
743 ScSingleRefData aRef
;
744 aRef
.InitAddress(aSrcPos
); // Absolute reference.
745 aRef
.SetFlag3D(true);
748 aArr
.AddSingleReference(aRef
);
749 return new ScFormulaCell(&mrClipTab
.GetDoc(), rDestPos
, aArr
);
752 void setLink(size_t nRow
)
754 SCCOL nTransCol
= nRow
- mnTopRow
;
755 mrClipTab
.SetFormulaCell(
756 nTransCol
, mnTransRow
, createRefCell(nRow
, getDestPos(nRow
)));
760 TransClipHandler(ScTable
& rClipTab
, SCTAB nSrcTab
, SCCOL nSrcCol
, size_t nTopRow
, SCROW nTransRow
, bool bAsLink
, bool bWasCut
) :
761 mrClipTab(rClipTab
), mnSrcTab(nSrcTab
), mnSrcCol(nSrcCol
),
762 mnTopRow(nTopRow
), mnTransRow(nTransRow
), mbAsLink(bAsLink
), mbWasCut(bWasCut
) {}
764 void operator() (size_t nRow
, double fVal
)
772 SCCOL nTransCol
= nRow
- mnTopRow
;
773 mrClipTab
.SetValue(nTransCol
, mnTransRow
, fVal
);
776 void operator() (size_t nRow
, const svl::SharedString
& rStr
)
784 SCCOL nTransCol
= nRow
- mnTopRow
;
785 mrClipTab
.SetRawString(nTransCol
, mnTransRow
, rStr
);
788 void operator() (size_t nRow
, const EditTextObject
* p
)
796 SCCOL nTransCol
= nRow
- mnTopRow
;
797 mrClipTab
.SetEditText(nTransCol
, mnTransRow
, ScEditUtil::Clone(*p
, mrClipTab
.GetDoc()));
800 void operator() (size_t nRow
, const ScFormulaCell
* p
)
808 ScFormulaCell
* pNew
= new ScFormulaCell(
809 *p
, mrClipTab
.GetDoc(), getDestPos(nRow
), SC_CLONECELL_STARTLISTENING
);
812 // for Cut, the referneces are later adjusted through UpdateTranspose
815 pNew
->TransposeReference();
817 SCCOL nTransCol
= nRow
- mnTopRow
;
818 mrClipTab
.SetFormulaCell(nTransCol
, mnTransRow
, pNew
);
824 void ScTable::TransposeClip( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
825 ScTable
* pTransClip
, InsertDeleteFlags nFlags
, bool bAsLink
)
827 bool bWasCut
= pDocument
->IsCutMode();
829 ScDocument
* pDestDoc
= pTransClip
->pDocument
;
831 for (SCCOL nCol
=nCol1
; nCol
<=nCol2
; nCol
++)
834 if ( bAsLink
&& nFlags
== IDF_ALL
)
836 // with IDF_ALL, also create links (formulas) for empty cells
838 for ( nRow
=nRow1
; nRow
<=nRow2
; nRow
++ )
840 // create simple formula, as in ScColumn::CreateRefCell
842 ScAddress
aDestPos( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
843 ScSingleRefData aRef
;
844 aRef
.InitAddress(ScAddress(nCol
,nRow
,nTab
));
845 aRef
.SetFlag3D(true);
847 aArr
.AddSingleReference( aRef
);
849 pTransClip
->SetFormulaCell(
850 static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
),
851 new ScFormulaCell(pDestDoc
, aDestPos
, aArr
));
856 TransClipHandler
aFunc(*pTransClip
, nTab
, nCol
, nRow1
, static_cast<SCROW
>(nCol
-nCol1
), bAsLink
, bWasCut
);
857 const sc::CellStoreType
& rCells
= aCol
[nCol
].maCells
;
858 sc::ParseAllNonEmpty(rCells
.begin(), rCells
, nRow1
, nRow2
, aFunc
);
865 const ScPatternAttr
* pPattern
;
866 boost::scoped_ptr
<ScAttrIterator
> pAttrIter(aCol
[nCol
].CreateAttrIterator( nRow1
, nRow2
));
867 while ( (pPattern
= pAttrIter
->Next( nAttrRow1
, nAttrRow2
)) != 0 )
869 if ( !IsDefaultItem( pPattern
) )
871 const SfxItemSet
& rSet
= pPattern
->GetItemSet();
872 if ( rSet
.GetItemState( ATTR_MERGE
, false ) == SfxItemState::DEFAULT
&&
873 rSet
.GetItemState( ATTR_MERGE_FLAG
, false ) == SfxItemState::DEFAULT
&&
874 rSet
.GetItemState( ATTR_BORDER
, false ) == SfxItemState::DEFAULT
)
876 // no borders or merge items involved - use pattern as-is
877 for (nRow
= nAttrRow1
; nRow
<=nAttrRow2
; nRow
++)
878 pTransClip
->SetPattern( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), *pPattern
, true );
882 // transpose borders and merge values, remove merge flags (refreshed after pasting)
883 ScPatternAttr
aNewPattern( *pPattern
);
884 SfxItemSet
& rNewSet
= aNewPattern
.GetItemSet();
886 const SvxBoxItem
& rOldBox
= static_cast<const SvxBoxItem
&>(rSet
.Get(ATTR_BORDER
));
887 if ( rOldBox
.GetTop() || rOldBox
.GetBottom() || rOldBox
.GetLeft() || rOldBox
.GetRight() )
889 SvxBoxItem
aNew( ATTR_BORDER
);
890 aNew
.SetLine( rOldBox
.GetLine( SvxBoxItemLine::TOP
), SvxBoxItemLine::LEFT
);
891 aNew
.SetLine( rOldBox
.GetLine( SvxBoxItemLine::LEFT
), SvxBoxItemLine::TOP
);
892 aNew
.SetLine( rOldBox
.GetLine( SvxBoxItemLine::BOTTOM
), SvxBoxItemLine::RIGHT
);
893 aNew
.SetLine( rOldBox
.GetLine( SvxBoxItemLine::RIGHT
), SvxBoxItemLine::BOTTOM
);
894 aNew
.SetDistance( rOldBox
.GetDistance( SvxBoxItemLine::TOP
), SvxBoxItemLine::LEFT
);
895 aNew
.SetDistance( rOldBox
.GetDistance( SvxBoxItemLine::LEFT
), SvxBoxItemLine::TOP
);
896 aNew
.SetDistance( rOldBox
.GetDistance( SvxBoxItemLine::BOTTOM
), SvxBoxItemLine::RIGHT
);
897 aNew
.SetDistance( rOldBox
.GetDistance( SvxBoxItemLine::RIGHT
), SvxBoxItemLine::BOTTOM
);
901 const ScMergeAttr
& rOldMerge
= static_cast<const ScMergeAttr
&>(rSet
.Get(ATTR_MERGE
));
902 if (rOldMerge
.IsMerged())
903 rNewSet
.Put( ScMergeAttr( std::min(
904 static_cast<SCsCOL
>(rOldMerge
.GetRowMerge()),
905 static_cast<SCsCOL
>(MAXCOL
+1 - (nAttrRow2
-nRow1
))),
907 static_cast<SCsROW
>(rOldMerge
.GetColMerge()),
908 static_cast<SCsROW
>(MAXROW
+1 - (nCol
-nCol1
)))));
909 const ScMergeFlagAttr
& rOldFlag
= static_cast<const ScMergeFlagAttr
&>(rSet
.Get(ATTR_MERGE_FLAG
));
910 if (rOldFlag
.IsOverlapped())
912 sal_Int16 nNewFlags
= rOldFlag
.GetValue() & ~( SC_MF_HOR
| SC_MF_VER
);
914 rNewSet
.Put( ScMergeFlagAttr( nNewFlags
) );
916 rNewSet
.ClearItem( ATTR_MERGE_FLAG
);
919 for (nRow
= nAttrRow1
; nRow
<=nAttrRow2
; nRow
++)
920 pTransClip
->SetPattern( static_cast<SCCOL
>(nRow
-nRow1
),
921 static_cast<SCROW
>(nCol
-nCol1
), aNewPattern
, true);
926 // Cell Notes - fdo#68381 paste cell notes on Transpose
927 if ( pDocument
->HasColNotes(nCol
, nTab
) )
928 TransposeColNotes(pTransClip
, nCol1
, nCol
, nRow1
, nRow2
);
932 void ScTable::TransposeColNotes(ScTable
* pTransClip
, SCCOL nCol1
, SCCOL nCol
, SCROW nRow1
, SCROW nRow2
)
934 bool bCloneCaption
= true;
936 sc::CellNoteStoreType::const_iterator itBlk
= aCol
[nCol
].maCellNotes
.begin(), itBlkEnd
= aCol
[nCol
].maCellNotes
.end();
938 // Locate the top row position.
939 size_t nOffsetInBlock
= 0;
940 size_t nBlockStart
= 0, nBlockEnd
= 0, nRowPos
= static_cast<size_t>(nRow1
);
941 for (; itBlk
!= itBlkEnd
; ++itBlk
, nBlockStart
= nBlockEnd
)
943 nBlockEnd
= nBlockStart
+ itBlk
->size
;
944 if (nBlockStart
<= nRowPos
&& nRowPos
< nBlockEnd
)
947 nOffsetInBlock
= nRowPos
- nBlockStart
;
952 if (itBlk
!= itBlkEnd
)
953 // Specified range found
955 nRowPos
= static_cast<size_t>(nRow2
); // End row position.
957 // Keep processing until we hit the end row position.
958 sc::cellnote_block::const_iterator itData
, itDataEnd
;
959 for (; itBlk
!= itBlkEnd
; ++itBlk
, nBlockStart
= nBlockEnd
, nOffsetInBlock
= 0)
961 nBlockEnd
= nBlockStart
+ itBlk
->size
;
965 itData
= sc::cellnote_block::begin(*itBlk
->data
);
966 std::advance(itData
, nOffsetInBlock
);
968 if (nBlockStart
<= nRowPos
&& nRowPos
< nBlockEnd
)
970 // This block contains the end row. Only process partially.
971 size_t nOffsetEnd
= nRowPos
- nBlockStart
+ 1;
972 itDataEnd
= sc::cellnote_block::begin(*itBlk
->data
);
973 std::advance(itDataEnd
, nOffsetEnd
);
974 size_t curRow
= nBlockStart
+ nOffsetInBlock
;
975 for (; itData
!= itDataEnd
; ++itData
, ++curRow
)
977 ScAddress
aDestPos( static_cast<SCCOL
>(curRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
978 pTransClip
->pDocument
->ReleaseNote(aDestPos
);
979 ScPostIt
* pNote
= *itData
;
982 ScPostIt
* pClonedNote
= pNote
->Clone( ScAddress(nCol
, curRow
, nTab
), *pTransClip
->pDocument
, aDestPos
, bCloneCaption
);
983 pTransClip
->pDocument
->SetNote(aDestPos
, pClonedNote
);
986 break; // we reached the last valid block
990 itDataEnd
= sc::cellnote_block::end(*itBlk
->data
);
991 size_t curRow
= nBlockStart
+ nOffsetInBlock
;
992 for (; itData
!= itDataEnd
; ++itData
, ++curRow
)
994 ScAddress
aDestPos( static_cast<SCCOL
>(curRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
995 pTransClip
->pDocument
->ReleaseNote(aDestPos
);
996 ScPostIt
* pNote
= *itData
;
999 ScPostIt
* pClonedNote
= pNote
->Clone( ScAddress(nCol
, curRow
, nTab
), *pTransClip
->pDocument
, aDestPos
, bCloneCaption
);
1000 pTransClip
->pDocument
->SetNote(aDestPos
, pClonedNote
);
1008 for ( curRow
= nBlockStart
+ nOffsetInBlock
; curRow
<= nBlockEnd
&& curRow
<= nRowPos
; ++curRow
)
1010 ScAddress
aDestPos( static_cast<SCCOL
>(curRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
1011 pTransClip
->pDocument
->ReleaseNote(aDestPos
);
1013 if (curRow
== nRowPos
)
1020 ScColumn
* ScTable::FetchColumn( SCCOL nCol
)
1022 if (!ValidCol(nCol
))
1028 const ScColumn
* ScTable::FetchColumn( SCCOL nCol
) const
1030 if (!ValidCol(nCol
))
1036 void ScTable::StartListeners( sc::StartListeningContext
& rCxt
, bool bAll
)
1038 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1039 aCol
[i
].StartListeners(rCxt
, bAll
);
1042 void ScTable::AttachFormulaCells(
1043 sc::StartListeningContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
1045 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
1046 aCol
[nCol
].AttachFormulaCells(rCxt
, nRow1
, nRow2
);
1049 void ScTable::DetachFormulaCells(
1050 sc::EndListeningContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
1052 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
1053 aCol
[nCol
].DetachFormulaCells(rCxt
, nRow1
, nRow2
);
1056 void ScTable::SetDirtyFromClip(
1057 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, sc::ColumnSpanSet
& rBroadcastSpans
)
1059 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
1060 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
1061 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1062 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1063 aCol
[i
].SetDirtyFromClip(nRow1
, nRow2
, rBroadcastSpans
);
1066 void ScTable::StartListeningFormulaCells(
1067 sc::StartListeningContext
& rStartCxt
, sc::EndListeningContext
& rEndCxt
,
1068 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
1070 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
1071 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
1072 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1073 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1074 aCol
[i
].StartListeningFormulaCells(rStartCxt
, rEndCxt
, nRow1
, nRow2
);
1077 void ScTable::EndListeningFormulaCells(
1078 sc::EndListeningContext
& rEndCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
1080 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
1081 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
1082 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1083 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
1084 aCol
[i
].EndListeningFormulaCells(rEndCxt
, nRow1
, nRow2
);
1087 void ScTable::CopyToTable(
1088 sc::CopyToDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1089 InsertDeleteFlags nFlags
, bool bMarked
, ScTable
* pDestTab
, const ScMarkData
* pMarkData
,
1090 bool bAsLink
, bool bColRowFlags
)
1092 if (!ValidColRow(nCol1
, nRow1
) || !ValidColRow(nCol2
, nRow2
))
1096 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1097 aCol
[i
].CopyToColumn(rCxt
, nRow1
, nRow2
, nFlags
, bMarked
,
1098 pDestTab
->aCol
[i
], pMarkData
, bAsLink
);
1100 if (!bColRowFlags
) // Column widths/Row heights/Flags
1103 if(pDestTab
->pDocument
->IsUndo() && (nFlags
& IDF_ATTRIB
))
1105 pDestTab
->mpCondFormatList
.reset(new ScConditionalFormatList(pDestTab
->pDocument
, *mpCondFormatList
));
1110 ScDBData
* pNewDBData
= new ScDBData(*pDBDataNoName
);
1114 pNewDBData
->GetArea(aTab
, aCol1
, aRow1
, aCol2
, aRow2
);
1115 pNewDBData
->MoveTo(pDestTab
->nTab
, aCol1
, aRow1
, aCol2
, aRow2
);
1116 pDestTab
->SetAnonymousDBData(pNewDBData
);
1118 // Charts have to be adjusted when hide/show
1119 ScChartListenerCollection
* pCharts
= pDestTab
->pDocument
->GetChartListenerCollection();
1121 bool bFlagChange
= false;
1123 bool bWidth
= (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pDestTab
->pColWidth
);
1124 bool bHeight
= (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pDestTab
->mpRowHeights
);
1126 if (bWidth
|| bHeight
)
1130 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
1132 bool bThisHidden
= ColHidden(i
);
1133 bool bHiddenChange
= (pDestTab
->ColHidden(i
) != bThisHidden
);
1134 bool bChange
= bHiddenChange
|| (pDestTab
->pColWidth
[i
] != pColWidth
[i
]);
1135 pDestTab
->pColWidth
[i
] = pColWidth
[i
];
1136 pDestTab
->pColFlags
[i
] = pColFlags
[i
];
1137 pDestTab
->SetColHidden(i
, i
, bThisHidden
);
1138 //TODO: collect changes?
1139 if (bHiddenChange
&& pCharts
)
1140 pCharts
->SetRangeDirty(ScRange( i
, 0, nTab
, i
, MAXROW
, nTab
));
1145 pDestTab
->SetColManualBreaks( maColManualBreaks
);
1150 bool bChange
= pDestTab
->GetRowHeight(nRow1
, nRow2
) != GetRowHeight(nRow1
, nRow2
);
1155 pDestTab
->CopyRowHeight(*this, nRow1
, nRow2
, 0);
1156 pDestTab
->pRowFlags
->CopyFrom(*pRowFlags
, nRow1
, nRow2
);
1159 for (SCROW i
= nRow1
; i
<= nRow2
; ++i
)
1162 bool bHidden
= RowHidden(i
, NULL
, &nLastRow
);
1163 if (nLastRow
>= nRow2
)
1164 // the last row shouldn't exceed the upper bound the caller specified.
1167 bool bHiddenChanged
= pDestTab
->SetRowHidden(i
, nLastRow
, bHidden
);
1168 if (bHiddenChanged
&& pCharts
)
1169 // Hidden flags differ.
1170 pCharts
->SetRangeDirty(ScRange(0, i
, nTab
, MAXCOL
, nLastRow
, nTab
));
1175 // Jump to the last row of the identical flag segment.
1180 for (SCROW i
= nRow1
; i
<= nRow2
; ++i
)
1183 bool bFiltered
= RowFiltered(i
, NULL
, &nLastRow
);
1184 if (nLastRow
>= nRow2
)
1185 // the last row shouldn't exceed the upper bound the caller specified.
1187 pDestTab
->SetRowFiltered(i
, nLastRow
, bFiltered
);
1190 pDestTab
->SetRowManualBreaks( maRowManualBreaks
);
1195 pDestTab
->InvalidatePageBreaks();
1197 if(nFlags
& IDF_ATTRIB
)
1199 pDestTab
->mpCondFormatList
->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
);
1200 pDestTab
->CopyConditionalFormat(nCol1
, nRow1
, nCol2
, nRow2
, 0, 0, this);
1203 if(nFlags
& IDF_OUTLINE
) // also only when bColRowFlags
1204 pDestTab
->SetOutlineTable( pOutlineTable
);
1207 void ScTable::UndoToTable(
1208 sc::CopyToDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1209 InsertDeleteFlags nFlags
, bool bMarked
, ScTable
* pDestTab
, const ScMarkData
* pMarkData
)
1211 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1213 bool bWidth
= (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pDestTab
->pColWidth
);
1214 bool bHeight
= (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pDestTab
->mpRowHeights
);
1216 for ( SCCOL i
= 0; i
<= MAXCOL
; i
++)
1218 if ( i
>= nCol1
&& i
<= nCol2
)
1219 aCol
[i
].UndoToColumn(rCxt
, nRow1
, nRow2
, nFlags
, bMarked
, pDestTab
->aCol
[i
], pMarkData
);
1221 aCol
[i
].CopyToColumn(rCxt
, 0, MAXROW
, IDF_FORMULA
, false, pDestTab
->aCol
[i
]);
1224 if (nFlags
& IDF_ATTRIB
)
1225 pDestTab
->mpCondFormatList
.reset(new ScConditionalFormatList(pDestTab
->pDocument
, *mpCondFormatList
));
1227 if (bWidth
||bHeight
)
1231 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
1232 pDestTab
->pColWidth
[i
] = pColWidth
[i
];
1233 pDestTab
->SetColManualBreaks( maColManualBreaks
);
1237 pDestTab
->CopyRowHeight(*this, nRow1
, nRow2
, 0);
1238 pDestTab
->SetRowManualBreaks( maRowManualBreaks
);
1244 void ScTable::CopyUpdated( const ScTable
* pPosTab
, ScTable
* pDestTab
) const
1246 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1247 aCol
[i
].CopyUpdated( pPosTab
->aCol
[i
], pDestTab
->aCol
[i
] );
1250 void ScTable::InvalidateTableArea()
1252 bTableAreaValid
= false;
1255 void ScTable::InvalidatePageBreaks()
1257 mbPageBreaksValid
= false;
1260 void ScTable::CopyScenarioTo( ScTable
* pDestTab
) const
1262 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1264 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1265 aCol
[i
].CopyScenarioTo( pDestTab
->aCol
[i
] );
1268 void ScTable::CopyScenarioFrom( const ScTable
* pSrcTab
)
1270 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1272 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1273 aCol
[i
].CopyScenarioFrom( pSrcTab
->aCol
[i
] );
1276 void ScTable::MarkScenarioIn( ScMarkData
& rDestMark
, sal_uInt16 nNeededBits
) const
1278 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1280 if ( ( nScenarioFlags
& nNeededBits
) != nNeededBits
) // Are all Bits set?
1283 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1284 aCol
[i
].MarkScenarioIn( rDestMark
);
1287 bool ScTable::HasScenarioRange( const ScRange
& rRange
) const
1289 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1291 ScRange aTabRange
= rRange
;
1292 aTabRange
.aStart
.SetTab( nTab
);
1293 aTabRange
.aEnd
.SetTab( nTab
);
1295 const ScRangeList
* pList
= GetScenarioRanges();
1299 for ( size_t j
= 0, n
= pList
->size(); j
< n
; j
++ )
1301 const ScRange
* pR
= (*pList
)[j
];
1302 if ( pR
->Intersects( aTabRange
) )
1310 void ScTable::InvalidateScenarioRanges()
1312 delete pScenarioRanges
;
1313 pScenarioRanges
= NULL
;
1316 const ScRangeList
* ScTable::GetScenarioRanges() const
1318 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1320 if (!pScenarioRanges
)
1322 const_cast<ScTable
*>(this)->pScenarioRanges
= new ScRangeList
;
1324 MarkScenarioIn( aMark
, 0 ); // always
1325 aMark
.FillRangeListWithMarks( pScenarioRanges
, false );
1327 return pScenarioRanges
;
1330 bool ScTable::TestCopyScenarioTo( const ScTable
* pDestTab
) const
1332 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1334 if (!pDestTab
->IsProtected())
1338 for (SCCOL i
=0; i
<=MAXCOL
&& bOk
; i
++)
1339 bOk
= aCol
[i
].TestCopyScenarioTo( pDestTab
->aCol
[i
] );
1343 bool ScTable::SetString( SCCOL nCol
, SCROW nRow
, SCTAB nTabP
, const OUString
& rString
,
1344 ScSetStringParam
* pParam
)
1346 if (ValidColRow(nCol
,nRow
))
1347 return aCol
[nCol
].SetString(
1348 nRow
, nTabP
, rString
, pDocument
->GetAddressConvention(), pParam
);
1353 bool ScTable::SetEditText( SCCOL nCol
, SCROW nRow
, EditTextObject
* pEditText
)
1355 if (!ValidColRow(nCol
, nRow
))
1361 aCol
[nCol
].SetEditText(nRow
, pEditText
);
1365 void ScTable::SetEditText( SCCOL nCol
, SCROW nRow
, const EditTextObject
& rEditText
, const SfxItemPool
* pEditPool
)
1367 if (!ValidColRow(nCol
, nRow
))
1370 aCol
[nCol
].SetEditText(nRow
, rEditText
, pEditPool
);
1373 SCROW
ScTable::GetFirstEditTextRow( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
1375 if (!ValidCol(nCol1
) || !ValidCol(nCol2
) || nCol2
< nCol1
)
1378 if (!ValidRow(nRow1
) || !ValidRow(nRow2
) || nRow2
< nRow1
)
1381 SCROW nFirst
= MAXROW
+1;
1382 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
1384 const ScColumn
& rCol
= aCol
[i
];
1385 SCROW nThisFirst
= -1;
1386 if (const_cast<ScColumn
&>(rCol
).HasEditCells(nRow1
, nRow2
, nThisFirst
))
1388 if (nThisFirst
== nRow1
)
1391 if (nThisFirst
< nFirst
)
1392 nFirst
= nThisFirst
;
1396 return nFirst
== (MAXROW
+1) ? -1 : nFirst
;
1399 void ScTable::SetEmptyCell( SCCOL nCol
, SCROW nRow
)
1401 if (!ValidColRow(nCol
, nRow
))
1404 aCol
[nCol
].Delete(nRow
);
1407 void ScTable::SetFormula(
1408 SCCOL nCol
, SCROW nRow
, const ScTokenArray
& rArray
, formula::FormulaGrammar::Grammar eGram
)
1410 if (!ValidColRow(nCol
, nRow
))
1413 aCol
[nCol
].SetFormula(nRow
, rArray
, eGram
);
1416 void ScTable::SetFormula(
1417 SCCOL nCol
, SCROW nRow
, const OUString
& rFormula
, formula::FormulaGrammar::Grammar eGram
)
1419 if (!ValidColRow(nCol
, nRow
))
1422 aCol
[nCol
].SetFormula(nRow
, rFormula
, eGram
);
1425 ScFormulaCell
* ScTable::SetFormulaCell( SCCOL nCol
, SCROW nRow
, ScFormulaCell
* pCell
)
1427 if (!ValidColRow(nCol
, nRow
))
1433 return aCol
[nCol
].SetFormulaCell(nRow
, pCell
, sc::ConvertToGroupListening
);
1436 bool ScTable::SetFormulaCells( SCCOL nCol
, SCROW nRow
, std::vector
<ScFormulaCell
*>& rCells
)
1438 if (!ValidCol(nCol
))
1441 return aCol
[nCol
].SetFormulaCells(nRow
, rCells
);
1444 svl::SharedString
ScTable::GetSharedString( SCCOL nCol
, SCROW nRow
) const
1446 if (!ValidColRow(nCol
, nRow
))
1447 return svl::SharedString();
1449 return aCol
[nCol
].GetSharedString(nRow
);
1452 void ScTable::SetValue( SCCOL nCol
, SCROW nRow
, const double& rVal
)
1454 if (ValidColRow(nCol
, nRow
))
1455 aCol
[nCol
].SetValue( nRow
, rVal
);
1458 void ScTable::SetRawString( SCCOL nCol
, SCROW nRow
, const svl::SharedString
& rStr
)
1460 if (ValidColRow(nCol
, nRow
))
1461 aCol
[nCol
].SetRawString(nRow
, rStr
);
1464 void ScTable::GetString( SCCOL nCol
, SCROW nRow
, OUString
& rString
) const
1466 if (ValidColRow(nCol
,nRow
))
1467 aCol
[nCol
].GetString( nRow
, rString
);
1472 double* ScTable::GetValueCell( SCCOL nCol
, SCROW nRow
)
1474 if (!ValidColRow(nCol
,nRow
))
1477 return aCol
[nCol
].GetValueCell(nRow
);
1480 void ScTable::GetInputString( SCCOL nCol
, SCROW nRow
, OUString
& rString
) const
1482 if (ValidColRow(nCol
,nRow
))
1483 aCol
[nCol
].GetInputString( nRow
, rString
);
1488 double ScTable::GetValue( SCCOL nCol
, SCROW nRow
) const
1490 if (ValidColRow( nCol
, nRow
))
1491 return aCol
[nCol
].GetValue( nRow
);
1495 const EditTextObject
* ScTable::GetEditText( SCCOL nCol
, SCROW nRow
) const
1497 if (!ValidColRow(nCol
, nRow
))
1500 return aCol
[nCol
].GetEditText(nRow
);
1503 void ScTable::RemoveEditTextCharAttribs( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
)
1505 if (!ValidColRow(nCol
, nRow
))
1508 return aCol
[nCol
].RemoveEditTextCharAttribs(nRow
, rAttr
);
1511 void ScTable::GetFormula( SCCOL nCol
, SCROW nRow
, OUString
& rFormula
) const
1513 if (ValidColRow(nCol
,nRow
))
1514 aCol
[nCol
].GetFormula( nRow
, rFormula
);
1519 const ScFormulaCell
* ScTable::GetFormulaCell( SCCOL nCol
, SCROW nRow
) const
1521 if (!ValidColRow(nCol
, nRow
))
1524 return aCol
[nCol
].GetFormulaCell(nRow
);
1527 ScFormulaCell
* ScTable::GetFormulaCell( SCCOL nCol
, SCROW nRow
)
1529 if (!ValidColRow(nCol
, nRow
))
1532 return aCol
[nCol
].GetFormulaCell(nRow
);
1535 ScPostIt
* ScTable::ReleaseNote( SCCOL nCol
, SCROW nRow
)
1537 if (!ValidCol(nCol
))
1540 return aCol
[nCol
].ReleaseNote(nRow
);
1543 size_t ScTable::GetNoteCount( SCCOL nCol
) const
1545 if (!ValidCol(nCol
))
1548 return aCol
[nCol
].GetNoteCount();
1551 SCROW
ScTable::GetNotePosition( SCCOL nCol
, size_t nIndex
) const
1553 if (!ValidCol(nCol
))
1556 return aCol
[nCol
].GetNotePosition(nIndex
);
1559 void ScTable::CreateAllNoteCaptions()
1561 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1562 aCol
[i
].CreateAllNoteCaptions();
1565 void ScTable::ForgetNoteCaptions( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
1567 if (!ValidCol(nCol1
) || !ValidCol(nCol2
))
1570 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
1571 aCol
[i
].ForgetNoteCaptions(nRow1
, nRow2
);
1574 void ScTable::GetAllNoteEntries( std::vector
<sc::NoteEntry
>& rNotes
) const
1576 for (SCCOL nCol
= 0; nCol
< MAXCOLCOUNT
; ++nCol
)
1577 aCol
[nCol
].GetAllNoteEntries(rNotes
);
1580 void ScTable::GetNotesInRange( const ScRange
& rRange
, std::vector
<sc::NoteEntry
>& rNotes
) const
1582 SCROW nStartRow
= rRange
.aStart
.Row();
1583 SCROW nEndRow
= rRange
.aEnd
.Row();
1584 for (SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= rRange
.aEnd
.Col(); ++nCol
)
1586 aCol
[nCol
].GetNotesInRange(nStartRow
, nEndRow
, rNotes
);
1590 bool ScTable::ContainsNotesInRange( const ScRange
& rRange
) const
1592 SCROW nStartRow
= rRange
.aStart
.Row();
1593 SCROW nEndRow
= rRange
.aEnd
.Row();
1594 for (SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= rRange
.aEnd
.Col(); ++nCol
)
1596 bool bContainsNote
= !aCol
[nCol
].IsNotesEmptyBlock(nStartRow
, nEndRow
);
1604 CellType
ScTable::GetCellType( SCCOL nCol
, SCROW nRow
) const
1606 if (ValidColRow( nCol
, nRow
))
1607 return aCol
[nCol
].GetCellType( nRow
);
1608 return CELLTYPE_NONE
;
1611 ScRefCellValue
ScTable::GetCellValue( SCCOL nCol
, SCROW nRow
) const
1613 if (!ValidColRow(nCol
, nRow
))
1614 return ScRefCellValue();
1616 return aCol
[nCol
].GetCellValue(nRow
);
1619 void ScTable::GetFirstDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
1623 while (aCol
[rCol
].IsEmptyData() && rCol
< MAXCOL
)
1626 while (nCol
<= MAXCOL
&& rRow
> 0)
1628 if (!aCol
[nCol
].IsEmptyData())
1629 rRow
= ::std::min( rRow
, aCol
[nCol
].GetFirstDataPos());
1634 void ScTable::GetLastDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
1638 while (aCol
[rCol
].IsEmptyData() && (rCol
> 0))
1641 while (nCol
>= 0 && rRow
< MAXROW
)
1642 rRow
= ::std::max( rRow
, aCol
[nCol
--].GetLastDataPos());
1645 bool ScTable::HasData( SCCOL nCol
, SCROW nRow
) const
1647 if (ValidColRow(nCol
,nRow
))
1648 return aCol
[nCol
].HasDataAt( nRow
);
1653 bool ScTable::HasStringData( SCCOL nCol
, SCROW nRow
) const
1655 if (ValidColRow(nCol
,nRow
))
1656 return aCol
[nCol
].HasStringData( nRow
);
1661 bool ScTable::HasValueData( SCCOL nCol
, SCROW nRow
) const
1663 if (ValidColRow(nCol
,nRow
))
1664 return aCol
[nCol
].HasValueData( nRow
);
1669 bool ScTable::HasStringCells( SCCOL nStartCol
, SCROW nStartRow
,
1670 SCCOL nEndCol
, SCROW nEndRow
) const
1672 if ( ValidCol(nEndCol
) )
1673 for ( SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++ )
1674 if (aCol
[nCol
].HasStringCells(nStartRow
, nEndRow
))
1680 void ScTable::SetDirtyVar()
1682 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1683 aCol
[i
].SetDirtyVar();
1686 void ScTable::SetAllFormulasDirty( const sc::SetFormulaDirtyContext
& rCxt
)
1688 sc::AutoCalcSwitch
aACSwitch(*pDocument
, false);
1690 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1691 aCol
[i
].SetAllFormulasDirty(rCxt
);
1694 void ScTable::SetDirty( const ScRange
& rRange
, ScColumn::BroadcastMode eMode
)
1696 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1697 pDocument
->SetAutoCalc( false ); // avoid multiple recalculations
1698 SCCOL nCol2
= rRange
.aEnd
.Col();
1699 for (SCCOL i
=rRange
.aStart
.Col(); i
<=nCol2
; i
++)
1700 aCol
[i
].SetDirty(rRange
.aStart
.Row(), rRange
.aEnd
.Row(), eMode
);
1701 pDocument
->SetAutoCalc( bOldAutoCalc
);
1704 void ScTable::SetTableOpDirty( const ScRange
& rRange
)
1706 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1707 pDocument
->SetAutoCalc( false ); // no multiple recalculation
1708 SCCOL nCol2
= rRange
.aEnd
.Col();
1709 for (SCCOL i
=rRange
.aStart
.Col(); i
<=nCol2
; i
++)
1710 aCol
[i
].SetTableOpDirty( rRange
);
1711 pDocument
->SetAutoCalc( bOldAutoCalc
);
1714 void ScTable::SetDirtyAfterLoad()
1716 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1717 pDocument
->SetAutoCalc( false ); // avoid multiple recalculations
1718 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1719 aCol
[i
].SetDirtyAfterLoad();
1720 pDocument
->SetAutoCalc( bOldAutoCalc
);
1723 void ScTable::SetDirtyIfPostponed()
1725 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1726 pDocument
->SetAutoCalc( false ); // avoid multiple recalculations
1727 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1728 aCol
[i
].SetDirtyIfPostponed();
1729 pDocument
->SetAutoCalc( bOldAutoCalc
);
1732 void ScTable::BroadcastRecalcOnRefMove()
1734 sc::AutoCalcSwitch
aSwitch(*pDocument
, false);
1735 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1736 aCol
[i
].BroadcastRecalcOnRefMove();
1739 bool ScTable::BroadcastBroadcasters( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, ScHint
& rHint
)
1741 bool bBroadcasted
= false;
1742 sc::AutoCalcSwitch
aSwitch(*pDocument
, false);
1743 rHint
.GetAddress().SetTab(nTab
);
1744 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
1745 bBroadcasted
|= aCol
[nCol
].BroadcastBroadcasters( nRow1
, nRow2
, rHint
);
1746 return bBroadcasted
;
1749 void ScTable::TransferListeners(
1750 ScTable
& rDestTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1751 SCCOL nColDelta
, SCROW nRowDelta
)
1753 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
1755 ScColumn
& rSrcCol
= aCol
[nCol
];
1756 ScColumn
& rDestCol
= rDestTab
.aCol
[nCol
+nColDelta
];
1757 rSrcCol
.TransferListeners(rDestCol
, nRow1
, nRow2
, nRowDelta
);
1761 void ScTable::SetLoadingMedium(bool bLoading
)
1763 mpRowHeights
->enableTreeSearch(!bLoading
);
1766 void ScTable::CalcAll()
1768 for (SCCOL i
=0; i
<=MAXCOL
; i
++) aCol
[i
].CalcAll();
1771 void ScTable::CompileAll( sc::CompileFormulaContext
& rCxt
)
1773 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1774 aCol
[i
].CompileAll(rCxt
);
1776 if(mpCondFormatList
)
1777 mpCondFormatList
->CompileAll();
1780 void ScTable::CompileXML( sc::CompileFormulaContext
& rCxt
, ScProgress
& rProgress
)
1783 mpRangeName
->CompileUnresolvedXML(rCxt
);
1785 for (SCCOL i
=0; i
<= MAXCOL
; i
++)
1787 aCol
[i
].CompileXML(rCxt
, rProgress
);
1790 if(mpCondFormatList
)
1791 mpCondFormatList
->CompileXML();
1794 bool ScTable::CompileErrorCells( sc::CompileFormulaContext
& rCxt
, sal_uInt16 nErrCode
)
1796 bool bCompiled
= false;
1797 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1799 if (aCol
[i
].CompileErrorCells(rCxt
, nErrCode
))
1806 void ScTable::CalcAfterLoad( sc::CompileFormulaContext
& rCxt
, bool bStartListening
)
1808 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1809 aCol
[i
].CalcAfterLoad(rCxt
, bStartListening
);
1812 void ScTable::ResetChanged( const ScRange
& rRange
)
1814 SCCOL nStartCol
= rRange
.aStart
.Col();
1815 SCROW nStartRow
= rRange
.aStart
.Row();
1816 SCCOL nEndCol
= rRange
.aEnd
.Col();
1817 SCROW nEndRow
= rRange
.aEnd
.Row();
1819 for (SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
1820 aCol
[nCol
].ResetChanged(nStartRow
, nEndRow
);
1825 const SfxPoolItem
* ScTable::GetAttr( SCCOL nCol
, SCROW nRow
, sal_uInt16 nWhich
) const
1827 if (ValidColRow(nCol
,nRow
))
1828 return aCol
[nCol
].GetAttr( nRow
, nWhich
);
1833 sal_uInt32
ScTable::GetNumberFormat( const ScAddress
& rPos
) const
1835 return ValidColRow(rPos
.Col(),rPos
.Row()) ?
1836 aCol
[rPos
.Col()].GetNumberFormat( rPos
.Row() ) :
1840 sal_uInt32
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nRow
) const
1842 if (ValidColRow(nCol
,nRow
))
1843 return aCol
[nCol
].GetNumberFormat( nRow
);
1848 sal_uInt32
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
) const
1850 if (!ValidCol(nCol
) || !ValidRow(nStartRow
) || !ValidRow(nEndRow
))
1853 return aCol
[nCol
].GetNumberFormat(nStartRow
, nEndRow
);
1856 void ScTable::SetNumberFormat( SCCOL nCol
, SCROW nRow
, sal_uInt32 nNumberFormat
)
1858 if (!ValidColRow(nCol
, nRow
))
1861 aCol
[nCol
].SetNumberFormat(nRow
, nNumberFormat
);
1864 const ScPatternAttr
* ScTable::GetPattern( SCCOL nCol
, SCROW nRow
) const
1866 if (ValidColRow(nCol
,nRow
))
1867 return aCol
[nCol
].GetPattern( nRow
);
1870 OSL_FAIL("wrong column or row");
1871 return pDocument
->GetDefPattern(); // for safety
1875 const ScPatternAttr
* ScTable::GetMostUsedPattern( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
) const
1877 if ( ValidColRow( nCol
, nStartRow
) && ValidRow( nEndRow
) && (nStartRow
<= nEndRow
) )
1878 return aCol
[nCol
].GetMostUsedPattern( nStartRow
, nEndRow
);
1883 bool ScTable::HasAttrib( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, sal_uInt16 nMask
) const
1885 bool bFound
= false;
1886 for (SCCOL i
=nCol1
; i
<=nCol2
&& !bFound
; i
++)
1887 bFound
|= aCol
[i
].HasAttrib( nRow1
, nRow2
, nMask
);
1891 bool ScTable::HasAttribSelection( const ScMarkData
& rMark
, sal_uInt16 nMask
) const
1893 std::vector
<sc::ColRowSpan
> aSpans
= rMark
.GetMarkedColSpans();
1895 for (size_t i
= 0; i
< aSpans
.size(); ++i
)
1897 for (SCCOLROW j
= aSpans
[i
].mnStart
; j
< aSpans
[i
].mnEnd
; ++j
)
1899 if (aCol
[j
].HasAttribSelection(rMark
, nMask
))
1906 bool ScTable::ExtendMerge( SCCOL nStartCol
, SCROW nStartRow
,
1907 SCCOL
& rEndCol
, SCROW
& rEndRow
,
1910 if (!(ValidCol(nStartCol
) && ValidCol(rEndCol
)))
1912 OSL_FAIL("ScTable::ExtendMerge: invalid column number");
1915 bool bFound
= false;
1916 SCCOL nOldEndX
= rEndCol
;
1917 SCROW nOldEndY
= rEndRow
;
1918 for (SCCOL i
=nStartCol
; i
<=nOldEndX
; i
++)
1919 bFound
|= aCol
[i
].ExtendMerge( i
, nStartRow
, nOldEndY
, rEndCol
, rEndRow
, bRefresh
);
1923 bool ScTable::IsBlockEmpty( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, bool bIgnoreNotes
) const
1925 if (!(ValidCol(nCol1
) && ValidCol(nCol2
)))
1927 OSL_FAIL("ScTable::IsBlockEmpty: invalid column number");
1931 for (SCCOL i
=nCol1
; i
<=nCol2
&& bEmpty
; i
++)
1933 bEmpty
= aCol
[i
].IsEmptyBlock( nRow1
, nRow2
);
1934 if (!bIgnoreNotes
&& bEmpty
)
1936 bEmpty
= aCol
[i
].IsNotesEmptyBlock(nRow1
, nRow2
);
1942 SCSIZE
ScTable::FillMaxRot( RowInfo
* pRowInfo
, SCSIZE nArrCount
, SCCOL nX1
, SCCOL nX2
,
1943 SCCOL nCol
, SCROW nAttrRow1
, SCROW nAttrRow2
, SCSIZE nArrY
,
1944 const ScPatternAttr
* pPattern
, const SfxItemSet
* pCondSet
)
1946 // Return value = new nArrY
1948 sal_uInt8 nRotDir
= pPattern
->GetRotateDir( pCondSet
);
1949 if ( nRotDir
!= SC_ROTDIR_NONE
)
1952 if ( nCol
+1 < nX1
) // column to the left
1953 bHit
= ( nRotDir
!= SC_ROTDIR_LEFT
);
1954 else if ( nCol
> nX2
+1 ) // column to the right
1955 bHit
= ( nRotDir
!= SC_ROTDIR_RIGHT
); // SC_ROTDIR_STANDARD may now also be extended to the left
1959 double nFactor
= 0.0;
1962 long nRotVal
= static_cast<const SfxInt32Item
&>( pPattern
->
1963 GetItem( ATTR_ROTATE_VALUE
, pCondSet
)).GetValue();
1964 double nRealOrient
= nRotVal
* F_PI18000
; // 1/100 Grad
1965 double nCos
= cos( nRealOrient
);
1966 double nSin
= sin( nRealOrient
);
1968 //TODO: additional factor for varying PPT X/Y !!!
1970 // for SC_ROTDIR_LEFT this gives a negative value,
1971 // if the Modus is considered
1972 nFactor
= -fabs( nCos
/ nSin
);
1975 for ( SCROW nRow
= nAttrRow1
; nRow
<= nAttrRow2
; nRow
++ )
1977 if (!RowHidden(nRow
))
1979 bool bHitOne
= true;
1982 // Does the rotated cell extend into the visable range?
1984 SCCOL nTouchedCol
= nCol
;
1985 long nWidth
= static_cast<long>(mpRowHeights
->getValue(nRow
) * nFactor
);
1986 OSL_ENSURE(nWidth
<= 0, "Wrong direction");
1987 while ( nWidth
< 0 && nTouchedCol
> 0 )
1990 nWidth
+= GetColWidth( nTouchedCol
);
1992 if ( nTouchedCol
> nX2
)
1998 while ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
< nRow
)
2000 if ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
== nRow
)
2001 pRowInfo
[nArrY
].nRotMaxCol
= nCol
;
2011 void ScTable::FindMaxRotCol( RowInfo
* pRowInfo
, SCSIZE nArrCount
, SCCOL nX1
, SCCOL nX2
)
2013 if ( !pColWidth
|| !mpRowHeights
|| !pColFlags
|| !pRowFlags
)
2015 OSL_FAIL( "Row/column info missing" );
2019 // nRotMaxCol is initalized to SC_ROTMAX_NONE, nRowNo is already set
2021 SCROW nY1
= pRowInfo
[0].nRowNo
;
2022 SCROW nY2
= pRowInfo
[nArrCount
-1].nRowNo
;
2024 for (SCCOL nCol
=0; nCol
<=MAXCOL
; nCol
++)
2026 if (!ColHidden(nCol
))
2029 ScDocAttrIterator
aIter( pDocument
, nTab
, nCol
, nY1
, nCol
, nY2
);
2031 SCROW nAttrRow1
, nAttrRow2
;
2032 const ScPatternAttr
* pPattern
= aIter
.GetNext( nAttrCol
, nAttrRow1
, nAttrRow2
);
2035 const SfxPoolItem
* pCondItem
;
2036 if ( pPattern
->GetItemSet().GetItemState( ATTR_CONDITIONAL
, true, &pCondItem
)
2037 == SfxItemState::SET
)
2039 // Run through all formats, so that each cell does not have to be
2040 // handled individually
2042 const std::vector
<sal_uInt32
>& rCondFormatData
= static_cast<const ScCondFormatItem
*>(pCondItem
)->GetCondFormatData();
2043 ScStyleSheetPool
* pStylePool
= pDocument
->GetStyleSheetPool();
2044 if (mpCondFormatList
&& pStylePool
&& !rCondFormatData
.empty())
2046 for(std::vector
<sal_uInt32
>::const_iterator itr
= rCondFormatData
.begin(), itrEnd
= rCondFormatData
.end();
2047 itr
!= itrEnd
; ++itr
)
2049 const ScConditionalFormat
* pFormat
= mpCondFormatList
->GetFormat(*itr
);
2052 size_t nEntryCount
= pFormat
->size();
2053 for (size_t nEntry
=0; nEntry
<nEntryCount
; nEntry
++)
2055 const ScFormatEntry
* pEntry
= pFormat
->GetEntry(nEntry
);
2056 if(pEntry
->GetType() != condformat::CONDITION
)
2059 OUString aStyleName
= static_cast<const ScCondFormatEntry
*>(pEntry
)->GetStyle();
2060 if (!aStyleName
.isEmpty())
2062 SfxStyleSheetBase
* pStyleSheet
=
2063 pStylePool
->Find( aStyleName
, SFX_STYLE_FAMILY_PARA
);
2066 FillMaxRot( pRowInfo
, nArrCount
, nX1
, nX2
,
2067 nCol
, nAttrRow1
, nAttrRow2
,
2068 nArrY
, pPattern
, &pStyleSheet
->GetItemSet() );
2069 // not changing nArrY
2078 nArrY
= FillMaxRot( pRowInfo
, nArrCount
, nX1
, nX2
,
2079 nCol
, nAttrRow1
, nAttrRow2
,
2080 nArrY
, pPattern
, NULL
);
2082 pPattern
= aIter
.GetNext( nAttrCol
, nAttrRow1
, nAttrRow2
);
2088 bool ScTable::HasBlockMatrixFragment( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
2092 sal_uInt16 nEdges
= 0;
2094 if ( nCol1
== nCol2
)
2095 { // left and right column
2096 const sal_uInt16 n
= MatrixEdgeLeft
| MatrixEdgeRight
;
2097 nEdges
= aCol
[nCol1
].GetBlockMatrixEdges( nRow1
, nRow2
, n
);
2098 // not (4 and 16) or 1 or 32
2099 if (nEdges
&& (((nEdges
& n
) != n
) || (nEdges
& (MatrixEdgeInside
|MatrixEdgeOpen
))))
2100 return true; // left or right edge is missing or open
2104 nEdges
= aCol
[nCol1
].GetBlockMatrixEdges(nRow1
, nRow2
, MatrixEdgeLeft
);
2106 if (nEdges
&& (((nEdges
& MatrixEdgeLeft
) != MatrixEdgeLeft
) || (nEdges
& (MatrixEdgeInside
|MatrixEdgeOpen
))))
2107 return true; // left edge missing or open
2109 nEdges
= aCol
[nCol2
].GetBlockMatrixEdges(nRow1
, nRow2
, MatrixEdgeRight
);
2110 // not 16 or 1 or 32
2111 if (nEdges
&& (((nEdges
& MatrixEdgeRight
) != MatrixEdgeRight
) || (nEdges
& (MatrixEdgeInside
|MatrixEdgeOpen
))))
2112 return true; // right edge is missing or open
2115 if ( nRow1
== nRow2
)
2116 { // Row on top and on bottom
2118 const sal_uInt16 n
= MatrixEdgeBottom
| MatrixEdgeTop
;
2119 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2121 nEdges
= aCol
[i
].GetBlockMatrixEdges( nRow1
, nRow1
, n
);
2124 if ( (nEdges
& n
) != n
)
2125 return true; // Top or bottom edge missing
2126 if (nEdges
& MatrixEdgeLeft
)
2127 bOpen
= true; // left edge open, continue
2129 return true; // Something exist that has not been opened
2130 if (nEdges
& MatrixEdgeRight
)
2131 bOpen
= false; // Close right edge
2135 return true; // continue
2141 // first rop row, then bottom row
2142 for ( j
=0, nR
=nRow1
, n
=8; j
<2; j
++, nR
=nRow2
, n
=2 )
2145 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2147 nEdges
= aCol
[i
].GetBlockMatrixEdges( nR
, nR
, n
);
2150 // in top row no top edge respectively
2151 // in bottom row no bottom edge
2152 if ( (nEdges
& n
) != n
)
2154 if (nEdges
& MatrixEdgeLeft
)
2155 bOpen
= true; // open left edge, continue
2157 return true; // Something exist that has not been opened
2158 if (nEdges
& MatrixEdgeRight
)
2159 bOpen
= false; // Close right edge
2163 return true; // continue
2169 bool ScTable::HasSelectionMatrixFragment( const ScMarkData
& rMark
) const
2171 std::vector
<sc::ColRowSpan
> aSpans
= rMark
.GetMarkedColSpans();
2173 for ( size_t i
=0; i
<aSpans
.size(); i
++ )
2175 for ( SCCOLROW j
=aSpans
[i
].mnStart
; j
<aSpans
[i
].mnEnd
; j
++ )
2177 if ( aCol
[j
].HasSelectionMatrixFragment(rMark
) )
2184 bool ScTable::IsBlockEditable( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
,
2185 SCROW nRow2
, bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
2187 if ( !ValidColRow( nCol2
, nRow2
) )
2189 OSL_FAIL("IsBlockEditable: invalid column or row");
2190 if (pOnlyNotBecauseOfMatrix
)
2191 *pOnlyNotBecauseOfMatrix
= false;
2195 bool bIsEditable
= true;
2197 bIsEditable
= false;
2198 else if ( IsProtected() && !pDocument
->IsScenario(nTab
) )
2200 bIsEditable
= !HasAttrib( nCol1
, nRow1
, nCol2
, nRow2
, HASATTR_PROTECTED
);
2203 // An enhanced protection permission may override the attribute.
2205 bIsEditable
= pTabProtection
->isBlockEditable( ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
));
2209 // If Sheet is protected and cells are not protected then
2210 // check the active scenario protect flag if this range is
2211 // on the active scenario range. Note the 'copy back' must also
2212 // be set to apply protection.
2213 sal_uInt16 nScenTab
= nTab
+1;
2214 while(pDocument
->IsScenario(nScenTab
))
2216 ScRange
aEditRange(nCol1
, nRow1
, nScenTab
, nCol2
, nRow2
, nScenTab
);
2217 if(pDocument
->IsActiveScenario(nScenTab
) && pDocument
->HasScenarioRange(nScenTab
, aEditRange
))
2220 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
2221 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
2228 else if (pDocument
->IsScenario(nTab
))
2230 // Determine if the preceding sheet is protected
2231 SCTAB nActualTab
= nTab
;
2236 while(pDocument
->IsScenario(nActualTab
));
2238 if(pDocument
->IsTabProtected(nActualTab
))
2240 ScRange
aEditRange(nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
2241 if(pDocument
->HasScenarioRange(nTab
, aEditRange
))
2244 pDocument
->GetScenarioFlags(nTab
,nFlags
);
2245 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
2251 if ( HasBlockMatrixFragment( nCol1
, nRow1
, nCol2
, nRow2
) )
2253 bIsEditable
= false;
2254 if ( pOnlyNotBecauseOfMatrix
)
2255 *pOnlyNotBecauseOfMatrix
= true;
2257 else if ( pOnlyNotBecauseOfMatrix
)
2258 *pOnlyNotBecauseOfMatrix
= false;
2260 else if ( pOnlyNotBecauseOfMatrix
)
2261 *pOnlyNotBecauseOfMatrix
= false;
2265 bool ScTable::IsSelectionEditable( const ScMarkData
& rMark
,
2266 bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
2268 bool bIsEditable
= true;
2270 bIsEditable
= false;
2271 else if ( IsProtected() && !pDocument
->IsScenario(nTab
) )
2273 ScRangeList aRanges
;
2274 rMark
.FillRangeListWithMarks( &aRanges
, false );
2275 bIsEditable
= !HasAttribSelection( rMark
, HASATTR_PROTECTED
);
2278 // An enhanced protection permission may override the attribute.
2280 bIsEditable
= pTabProtection
->isSelectionEditable( aRanges
);
2284 // If Sheet is protected and cells are not protected then
2285 // check the active scenario protect flag if this area is
2286 // in the active scenario range.
2287 SCTAB nScenTab
= nTab
+1;
2288 while(pDocument
->IsScenario(nScenTab
) && bIsEditable
)
2290 if(pDocument
->IsActiveScenario(nScenTab
))
2292 for (size_t i
=0, nRange
= aRanges
.size(); (i
< nRange
) && bIsEditable
; i
++ )
2294 ScRange aRange
= *aRanges
[ i
];
2295 if(pDocument
->HasScenarioRange(nScenTab
, aRange
))
2298 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
2299 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
2307 else if (pDocument
->IsScenario(nTab
))
2309 // Determine if the preceding sheet is protected
2310 SCTAB nActualTab
= nTab
;
2315 while(pDocument
->IsScenario(nActualTab
));
2317 if(pDocument
->IsTabProtected(nActualTab
))
2319 ScRangeList aRanges
;
2320 rMark
.FillRangeListWithMarks( &aRanges
, false );
2321 for (size_t i
= 0, nRange
= aRanges
.size(); (i
< nRange
) && bIsEditable
; i
++)
2323 ScRange aRange
= *aRanges
[ i
];
2324 if(pDocument
->HasScenarioRange(nTab
, aRange
))
2327 pDocument
->GetScenarioFlags(nTab
,nFlags
);
2328 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
2335 if ( HasSelectionMatrixFragment( rMark
) )
2337 bIsEditable
= false;
2338 if ( pOnlyNotBecauseOfMatrix
)
2339 *pOnlyNotBecauseOfMatrix
= true;
2341 else if ( pOnlyNotBecauseOfMatrix
)
2342 *pOnlyNotBecauseOfMatrix
= false;
2344 else if ( pOnlyNotBecauseOfMatrix
)
2345 *pOnlyNotBecauseOfMatrix
= false;
2349 void ScTable::LockTable()
2354 void ScTable::UnlockTable()
2360 OSL_FAIL("UnlockTable without LockTable");
2364 void ScTable::MergeSelectionPattern( ScMergePatternState
& rState
, const ScMarkData
& rMark
, bool bDeep
) const
2366 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2367 aCol
[i
].MergeSelectionPattern( rState
, rMark
, bDeep
);
2370 void ScTable::MergePatternArea( ScMergePatternState
& rState
, SCCOL nCol1
, SCROW nRow1
,
2371 SCCOL nCol2
, SCROW nRow2
, bool bDeep
) const
2373 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2374 aCol
[i
].MergePatternArea( rState
, nRow1
, nRow2
, bDeep
);
2377 void ScTable::MergeBlockFrame( SvxBoxItem
* pLineOuter
, SvxBoxInfoItem
* pLineInner
, ScLineFlags
& rFlags
,
2378 SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
) const
2380 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2382 PutInOrder(nStartCol
, nEndCol
);
2383 PutInOrder(nStartRow
, nEndRow
);
2384 for (SCCOL i
=nStartCol
; i
<=nEndCol
; i
++)
2385 aCol
[i
].MergeBlockFrame( pLineOuter
, pLineInner
, rFlags
,
2386 nStartRow
, nEndRow
, (i
==nStartCol
), nEndCol
-i
);
2390 void ScTable::ApplyBlockFrame( const SvxBoxItem
* pLineOuter
, const SvxBoxInfoItem
* pLineInner
,
2391 SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
)
2393 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2395 PutInOrder(nStartCol
, nEndCol
);
2396 PutInOrder(nStartRow
, nEndRow
);
2397 for (SCCOL i
=nStartCol
; i
<=nEndCol
; i
++)
2398 aCol
[i
].ApplyBlockFrame( pLineOuter
, pLineInner
,
2399 nStartRow
, nEndRow
, (i
==nStartCol
), nEndCol
-i
);
2403 void ScTable::ApplyPattern( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
)
2405 if (ValidColRow(nCol
,nRow
))
2406 aCol
[nCol
].ApplyPattern( nRow
, rAttr
);
2409 void ScTable::ApplyPatternArea( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2410 const ScPatternAttr
& rAttr
, ScEditDataArray
* pDataArray
)
2412 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2414 PutInOrder(nStartCol
, nEndCol
);
2415 PutInOrder(nStartRow
, nEndRow
);
2416 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2417 aCol
[i
].ApplyPatternArea(nStartRow
, nEndRow
, rAttr
, pDataArray
);
2421 void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange
& rRange
,
2422 const ScPatternAttr
& rPattern
, short nNewType
)
2424 SCCOL nEndCol
= rRange
.aEnd
.Col();
2425 for ( SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= nEndCol
; nCol
++ )
2427 aCol
[nCol
].ApplyPatternIfNumberformatIncompatible( rRange
, rPattern
, nNewType
);
2431 void ScTable::AddCondFormatData( const ScRangeList
& rRange
, sal_uInt32 nIndex
)
2433 size_t n
= rRange
.size();
2434 for(size_t i
= 0; i
< n
; ++i
)
2436 const ScRange
* pRange
= rRange
[i
];
2437 SCCOL nColStart
= pRange
->aStart
.Col();
2438 SCCOL nColEnd
= pRange
->aEnd
.Col();
2439 SCROW nRowStart
= pRange
->aStart
.Row();
2440 SCROW nRowEnd
= pRange
->aEnd
.Row();
2441 for(SCCOL nCol
= nColStart
; nCol
<= nColEnd
; ++nCol
)
2443 aCol
[nCol
].AddCondFormat(nRowStart
, nRowEnd
, nIndex
);
2448 void ScTable::RemoveCondFormatData( const ScRangeList
& rRange
, sal_uInt32 nIndex
)
2450 size_t n
= rRange
.size();
2451 for(size_t i
= 0; i
< n
; ++i
)
2453 const ScRange
* pRange
= rRange
[i
];
2454 SCCOL nColStart
= pRange
->aStart
.Col();
2455 SCCOL nColEnd
= pRange
->aEnd
.Col();
2456 SCROW nRowStart
= pRange
->aStart
.Row();
2457 SCROW nRowEnd
= pRange
->aEnd
.Row();
2458 for(SCCOL nCol
= nColStart
; nCol
<= nColEnd
; ++nCol
)
2460 aCol
[nCol
].RemoveCondFormat(nRowStart
, nRowEnd
, nIndex
);
2465 void ScTable::ApplyStyle( SCCOL nCol
, SCROW nRow
, const ScStyleSheet
& rStyle
)
2467 if (ValidColRow(nCol
,nRow
))
2468 aCol
[nCol
].ApplyStyle( nRow
, rStyle
);
2471 void ScTable::ApplyStyleArea( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
, const ScStyleSheet
& rStyle
)
2473 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2475 PutInOrder(nStartCol
, nEndCol
);
2476 PutInOrder(nStartRow
, nEndRow
);
2477 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2478 aCol
[i
].ApplyStyleArea(nStartRow
, nEndRow
, rStyle
);
2482 void ScTable::ApplySelectionStyle(const ScStyleSheet
& rStyle
, const ScMarkData
& rMark
)
2484 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2485 aCol
[i
].ApplySelectionStyle( rStyle
, rMark
);
2488 void ScTable::ApplySelectionLineStyle( const ScMarkData
& rMark
,
2489 const ::editeng::SvxBorderLine
* pLine
, bool bColorOnly
)
2491 if ( bColorOnly
&& !pLine
)
2494 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2495 aCol
[i
].ApplySelectionLineStyle( rMark
, pLine
, bColorOnly
);
2498 const ScStyleSheet
* ScTable::GetStyle( SCCOL nCol
, SCROW nRow
) const
2500 if (ValidColRow(nCol
, nRow
))
2501 return aCol
[nCol
].GetStyle(nRow
);
2506 const ScStyleSheet
* ScTable::GetSelectionStyle( const ScMarkData
& rMark
, bool& rFound
) const
2513 const ScStyleSheet
* pStyle
= NULL
;
2514 const ScStyleSheet
* pNewStyle
;
2516 for (SCCOL i
=0; i
<=MAXCOL
&& bEqual
; i
++)
2517 if (rMark
.HasMultiMarks(i
))
2519 pNewStyle
= aCol
[i
].GetSelectionStyle( rMark
, bColFound
);
2523 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
2529 return bEqual
? pStyle
: NULL
;
2532 const ScStyleSheet
* ScTable::GetAreaStyle( bool& rFound
, SCCOL nCol1
, SCROW nRow1
,
2533 SCCOL nCol2
, SCROW nRow2
) const
2540 const ScStyleSheet
* pStyle
= NULL
;
2541 const ScStyleSheet
* pNewStyle
;
2543 for (SCCOL i
=nCol1
; i
<=nCol2
&& bEqual
; i
++)
2545 pNewStyle
= aCol
[i
].GetAreaStyle(bColFound
, nRow1
, nRow2
);
2549 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
2555 return bEqual
? pStyle
: NULL
;
2558 bool ScTable::IsStyleSheetUsed( const ScStyleSheet
& rStyle
, bool bGatherAllStyles
) const
2560 bool bIsUsed
= false;
2562 for ( SCCOL i
=0; i
<=MAXCOL
; i
++ )
2564 if ( aCol
[i
].IsStyleSheetUsed( rStyle
, bGatherAllStyles
) )
2566 if ( !bGatherAllStyles
)
2575 void ScTable::StyleSheetChanged( const SfxStyleSheetBase
* pStyleSheet
, bool bRemoved
,
2577 double nPPTX
, double nPPTY
,
2578 const Fraction
& rZoomX
, const Fraction
& rZoomY
)
2580 ScFlatBoolRowSegments aUsedRows
;
2581 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
2582 aCol
[i
].FindStyleSheet(pStyleSheet
, aUsedRows
, bRemoved
);
2584 sc::RowHeightContext
aCxt(nPPTX
, nPPTY
, rZoomX
, rZoomY
, pDev
);
2586 while (nRow
<= MAXROW
)
2588 ScFlatBoolRowSegments::RangeData aData
;
2589 if (!aUsedRows
.getRangeData(nRow
, aData
))
2593 SCROW nEndRow
= aData
.mnRow2
;
2595 SetOptimalHeight(aCxt
, nRow
, nEndRow
);
2601 bool ScTable::ApplyFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2604 bool bChanged
= false;
2605 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2606 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2607 bChanged
|= aCol
[i
].ApplyFlags(nStartRow
, nEndRow
, nFlags
);
2611 bool ScTable::RemoveFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2614 bool bChanged
= false;
2615 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2616 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2617 bChanged
|= aCol
[i
].RemoveFlags(nStartRow
, nEndRow
, nFlags
);
2621 void ScTable::SetPattern( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
, bool bPutToPool
)
2623 if (ValidColRow(nCol
,nRow
))
2624 aCol
[nCol
].SetPattern( nRow
, rAttr
, bPutToPool
);
2627 void ScTable::ApplyAttr( SCCOL nCol
, SCROW nRow
, const SfxPoolItem
& rAttr
)
2629 if (ValidColRow(nCol
,nRow
))
2630 aCol
[nCol
].ApplyAttr( nRow
, rAttr
);
2633 void ScTable::ApplySelectionCache( SfxItemPoolCache
* pCache
, const ScMarkData
& rMark
,
2634 ScEditDataArray
* pDataArray
)
2636 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2637 aCol
[i
].ApplySelectionCache( pCache
, rMark
, pDataArray
);
2640 void ScTable::ChangeSelectionIndent( bool bIncrement
, const ScMarkData
& rMark
)
2642 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2643 aCol
[i
].ChangeSelectionIndent( bIncrement
, rMark
);
2646 void ScTable::ClearSelectionItems( const sal_uInt16
* pWhich
, const ScMarkData
& rMark
)
2648 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2649 aCol
[i
].ClearSelectionItems( pWhich
, rMark
);
2652 // Column widths / Row heights
2654 void ScTable::SetColWidth( SCCOL nCol
, sal_uInt16 nNewWidth
)
2656 if (ValidCol(nCol
) && pColWidth
)
2660 nNewWidth
= STD_COL_WIDTH
;
2663 if ( nNewWidth
!= pColWidth
[nCol
] )
2665 pColWidth
[nCol
] = nNewWidth
;
2666 InvalidatePageBreaks();
2671 OSL_FAIL("Invalid column number or no widths");
2675 void ScTable::SetColWidthOnly( SCCOL nCol
, sal_uInt16 nNewWidth
)
2677 if (!ValidCol(nCol
) || !pColWidth
)
2681 nNewWidth
= STD_COL_WIDTH
;
2683 if (nNewWidth
!= pColWidth
[nCol
])
2684 pColWidth
[nCol
] = nNewWidth
;
2687 void ScTable::SetRowHeight( SCROW nRow
, sal_uInt16 nNewHeight
)
2689 if (ValidRow(nRow
) && mpRowHeights
)
2693 OSL_FAIL("SetRowHeight: Row height zero");
2694 nNewHeight
= ScGlobal::nStdRowHeight
;
2697 sal_uInt16 nOldHeight
= mpRowHeights
->getValue(nRow
);
2698 if ( nNewHeight
!= nOldHeight
)
2700 mpRowHeights
->setValue(nRow
, nRow
, nNewHeight
);
2701 InvalidatePageBreaks();
2706 OSL_FAIL("Invalid row number or no heights");
2713 * Check if the new pixel size is different from the old size between
2716 bool lcl_pixelSizeChanged(
2717 ScFlatUInt16RowSegments
& rRowHeights
, SCROW nStartRow
, SCROW nEndRow
,
2718 sal_uInt16 nNewHeight
, double nPPTY
)
2720 long nNewPix
= static_cast<long>(nNewHeight
* nPPTY
);
2722 ScFlatUInt16RowSegments::ForwardIterator
aFwdIter(rRowHeights
);
2723 for (SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
2726 if (!aFwdIter
.getValue(nRow
, nHeight
))
2729 if (nHeight
!= nNewHeight
)
2731 bool bChanged
= (nNewPix
!= static_cast<long>(nHeight
* nPPTY
));
2736 // Skip ahead to the last position of the current range.
2737 nRow
= aFwdIter
.getLastPos();
2744 bool ScTable::SetRowHeightRange( SCROW nStartRow
, SCROW nEndRow
, sal_uInt16 nNewHeight
,
2745 double /* nPPTX */, double nPPTY
)
2747 bool bChanged
= false;
2748 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2752 OSL_FAIL("SetRowHeight: Row height zero");
2753 nNewHeight
= ScGlobal::nStdRowHeight
;
2756 bool bSingle
= false; // true = process every row for its own
2757 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2759 if (pDrawLayer
->HasObjectsInRows( nTab
, nStartRow
, nEndRow
))
2764 ScFlatUInt16RowSegments::RangeData aData
;
2765 if (mpRowHeights
->getRangeData(nStartRow
, aData
) &&
2766 nNewHeight
== aData
.mnValue
&& nEndRow
<= aData
.mnRow2
)
2768 bSingle
= false; // no difference in this range
2773 if (nEndRow
-nStartRow
< 20)
2776 bChanged
= lcl_pixelSizeChanged(*mpRowHeights
, nStartRow
, nEndRow
, nNewHeight
, nPPTY
);
2778 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2782 SCROW nMid
= (nStartRow
+nEndRow
) / 2;
2783 if (SetRowHeightRange( nStartRow
, nMid
, nNewHeight
, 1.0, 1.0 ))
2785 if (SetRowHeightRange( nMid
+1, nEndRow
, nNewHeight
, 1.0, 1.0 ))
2792 bChanged
= lcl_pixelSizeChanged(*mpRowHeights
, nStartRow
, nEndRow
, nNewHeight
, nPPTY
);
2794 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2798 InvalidatePageBreaks();
2802 OSL_FAIL("Invalid row number or no heights");
2808 void ScTable::SetRowHeightOnly( SCROW nStartRow
, SCROW nEndRow
, sal_uInt16 nNewHeight
)
2810 if (!ValidRow(nStartRow
) || !ValidRow(nEndRow
) || !mpRowHeights
)
2814 nNewHeight
= ScGlobal::nStdRowHeight
;
2816 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2819 void ScTable::SetManualHeight( SCROW nStartRow
, SCROW nEndRow
, bool bManual
)
2821 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && pRowFlags
)
2824 pRowFlags
->OrValue( nStartRow
, nEndRow
, CR_MANUALSIZE
);
2826 pRowFlags
->AndValue( nStartRow
, nEndRow
, sal::static_int_cast
<sal_uInt8
>(~CR_MANUALSIZE
));
2830 OSL_FAIL("Invalid row number or no column flags");
2834 sal_uInt16
ScTable::GetColWidth( SCCOL nCol
, bool bHiddenAsZero
) const
2836 OSL_ENSURE(ValidCol(nCol
),"wrong column number");
2838 if (ValidCol(nCol
) && pColFlags
&& pColWidth
)
2840 if (bHiddenAsZero
&& ColHidden(nCol
))
2843 return pColWidth
[nCol
];
2846 return (sal_uInt16
) STD_COL_WIDTH
;
2849 sal_uLong
ScTable::GetColWidth( SCCOL nStartCol
, SCCOL nEndCol
, bool bHiddenAsZero
) const
2851 if (!ValidCol(nStartCol
) || !ValidCol(nEndCol
) || nStartCol
> nEndCol
)
2855 bool bHidden
= false;
2856 SCCOL nLastHiddenCol
= -1;
2857 for (SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
2859 if (bHiddenAsZero
&& nCol
> nLastHiddenCol
)
2860 bHidden
= ColHidden(nCol
, NULL
, &nLastHiddenCol
);
2865 nW
+= pColWidth
[nCol
];
2870 sal_uInt16
ScTable::GetOriginalWidth( SCCOL nCol
) const // always the set value
2872 OSL_ENSURE(ValidCol(nCol
),"wrong column number");
2874 if (ValidCol(nCol
) && pColWidth
)
2875 return pColWidth
[nCol
];
2877 return (sal_uInt16
) STD_COL_WIDTH
;
2880 sal_uInt16
ScTable::GetCommonWidth( SCCOL nEndCol
) const
2882 // get the width that is used in the largest continuous column range (up to nEndCol)
2884 if ( !ValidCol(nEndCol
) )
2886 OSL_FAIL("wrong column");
2890 sal_uInt16 nMaxWidth
= 0;
2891 sal_uInt16 nMaxCount
= 0;
2892 SCCOL nRangeStart
= 0;
2893 while ( nRangeStart
<= nEndCol
)
2895 // skip hidden columns
2896 while ( nRangeStart
<= nEndCol
&& ColHidden(nRangeStart
) )
2898 if ( nRangeStart
<= nEndCol
)
2900 sal_uInt16 nThisCount
= 0;
2901 sal_uInt16 nThisWidth
= pColWidth
[nRangeStart
];
2902 SCCOL nRangeEnd
= nRangeStart
;
2903 while ( nRangeEnd
<= nEndCol
&& pColWidth
[nRangeEnd
] == nThisWidth
)
2908 // skip hidden columns
2909 while ( nRangeEnd
<= nEndCol
&& ColHidden(nRangeEnd
) )
2913 if ( nThisCount
> nMaxCount
)
2915 nMaxCount
= nThisCount
;
2916 nMaxWidth
= nThisWidth
;
2919 nRangeStart
= nRangeEnd
; // next range
2926 sal_uInt16
ScTable::GetRowHeight( SCROW nRow
, SCROW
* pStartRow
, SCROW
* pEndRow
, bool bHiddenAsZero
) const
2928 OSL_ENSURE(ValidRow(nRow
),"Invalid row number");
2930 if (ValidRow(nRow
) && mpRowHeights
)
2932 if (bHiddenAsZero
&& RowHidden( nRow
, pStartRow
, pEndRow
))
2936 ScFlatUInt16RowSegments::RangeData aData
;
2937 if (!mpRowHeights
->getRangeData(nRow
, aData
))
2943 // TODO: What should we return in case the search fails?
2947 // If bHiddenAsZero, pStartRow and pEndRow were initialized to
2948 // boundaries of a non-hidden segment. Assume that the previous and
2949 // next segment are hidden then and limit the current height
2952 *pStartRow
= (bHiddenAsZero
? std::max( *pStartRow
, aData
.mnRow1
) : aData
.mnRow1
);
2954 *pEndRow
= (bHiddenAsZero
? std::min( *pEndRow
, aData
.mnRow2
) : aData
.mnRow2
);
2955 return aData
.mnValue
;
2964 return (sal_uInt16
) ScGlobal::nStdRowHeight
;
2968 sal_uLong
ScTable::GetRowHeight( SCROW nStartRow
, SCROW nEndRow
, bool bHiddenAsZero
) const
2970 OSL_ENSURE(ValidRow(nStartRow
) && ValidRow(nEndRow
),"wrong row number");
2972 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2974 sal_uLong nHeight
= 0;
2975 SCROW nRow
= nStartRow
;
2976 while (nRow
<= nEndRow
)
2978 SCROW nLastRow
= -1;
2979 if (!( ( RowHidden(nRow
, NULL
, &nLastRow
) ) && bHiddenAsZero
) )
2981 if (nLastRow
> nEndRow
)
2983 nHeight
+= mpRowHeights
->getSumValue(nRow
, nLastRow
);
2985 nRow
= nLastRow
+ 1;
2990 return (nEndRow
- nStartRow
+ 1) * (sal_uLong
)ScGlobal::nStdRowHeight
;
2993 sal_uLong
ScTable::GetScaledRowHeight( SCROW nStartRow
, SCROW nEndRow
, double fScale
) const
2995 OSL_ENSURE(ValidRow(nStartRow
) && ValidRow(nEndRow
),"wrong row number");
2997 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2999 sal_uLong nHeight
= 0;
3000 SCROW nRow
= nStartRow
;
3001 while (nRow
<= nEndRow
)
3003 SCROW nLastRow
= -1;
3004 if (!RowHidden(nRow
, NULL
, &nLastRow
))
3006 if (nLastRow
> nEndRow
)
3009 // #i117315# can't use getSumValue, because individual values must be rounded
3010 while (nRow
<= nLastRow
)
3012 ScFlatUInt16RowSegments::RangeData aData
;
3013 if (!mpRowHeights
->getRangeData(nRow
, aData
))
3014 return nHeight
; // shouldn't happen
3016 SCROW nSegmentEnd
= std::min( nLastRow
, aData
.mnRow2
);
3018 // round-down a single height value, multiply resulting (pixel) values
3019 sal_uLong nOneHeight
= static_cast<sal_uLong
>( aData
.mnValue
* fScale
);
3020 nHeight
+= nOneHeight
* ( nSegmentEnd
+ 1 - nRow
);
3022 nRow
= nSegmentEnd
+ 1;
3025 nRow
= nLastRow
+ 1;
3030 return (sal_uLong
) ((nEndRow
- nStartRow
+ 1) * ScGlobal::nStdRowHeight
* fScale
);
3033 sal_uInt16
ScTable::GetOriginalHeight( SCROW nRow
) const // non-0 even if hidden
3035 OSL_ENSURE(ValidRow(nRow
),"wrong row number");
3037 if (ValidRow(nRow
) && mpRowHeights
)
3038 return mpRowHeights
->getValue(nRow
);
3040 return (sal_uInt16
) ScGlobal::nStdRowHeight
;
3043 // Column/Row -Flags
3045 SCROW
ScTable::GetHiddenRowCount( SCROW nRow
) const
3047 if (!ValidRow(nRow
))
3050 SCROW nLastRow
= -1;
3051 if (!RowHidden(nRow
, NULL
, &nLastRow
) || !ValidRow(nLastRow
))
3054 return nLastRow
- nRow
+ 1;
3057 //TODO: combine ShowRows / DBShowRows
3059 void ScTable::ShowCol(SCCOL nCol
, bool bShow
)
3063 bool bWasVis
= !ColHidden(nCol
);
3064 if (bWasVis
!= bShow
)
3066 SetColHidden(nCol
, nCol
, !bShow
);
3068 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3070 pCharts
->SetRangeDirty(ScRange( nCol
, 0, nTab
, nCol
, MAXROW
, nTab
));
3075 OSL_FAIL("Invalid column number or no flags");
3079 void ScTable::ShowRow(SCROW nRow
, bool bShow
)
3081 if (ValidRow(nRow
) && pRowFlags
)
3083 bool bWasVis
= !RowHidden(nRow
);
3084 if (bWasVis
!= bShow
)
3086 SetRowHidden(nRow
, nRow
, !bShow
);
3088 SetRowFiltered(nRow
, nRow
, false);
3089 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3091 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
3093 InvalidatePageBreaks();
3098 OSL_FAIL("Invalid row number or no flags");
3102 void ScTable::DBShowRow(SCROW nRow
, bool bShow
)
3104 if (ValidRow(nRow
) && pRowFlags
)
3106 // Always set Filter-Flag, also unchanged when Hidden
3107 bool bChanged
= SetRowHidden(nRow
, nRow
, !bShow
);
3108 SetRowFiltered(nRow
, nRow
, !bShow
);
3112 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3114 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
3117 UpdateOutlineRow( nRow
, nRow
, bShow
);
3119 InvalidatePageBreaks();
3124 OSL_FAIL("Invalid row number or no flags");
3128 void ScTable::DBShowRows(SCROW nRow1
, SCROW nRow2
, bool bShow
)
3130 SCROW nStartRow
= nRow1
;
3131 while (nStartRow
<= nRow2
)
3134 bool bWasVis
= !RowHiddenLeaf(nStartRow
, NULL
, &nEndRow
);
3135 if (nEndRow
> nRow2
)
3138 bool bChanged
= ( bWasVis
!= bShow
);
3140 SetRowHidden(nStartRow
, nEndRow
, !bShow
);
3141 SetRowFiltered(nStartRow
, nEndRow
, !bShow
);
3145 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3147 pCharts
->SetRangeDirty(ScRange( 0, nStartRow
, nTab
, MAXCOL
, nEndRow
, nTab
));
3150 nStartRow
= nEndRow
+ 1;
3153 // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
3154 // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
3157 UpdateOutlineRow( nRow1
, nRow2
, bShow
);
3160 void ScTable::ShowRows(SCROW nRow1
, SCROW nRow2
, bool bShow
)
3162 SCROW nStartRow
= nRow1
;
3164 // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
3165 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
3166 bool bHasObjects
= pDrawLayer
&& pDrawLayer
->HasObjectsInRows( nTab
, nRow1
, nRow2
);
3168 while (nStartRow
<= nRow2
)
3171 bool bWasVis
= !RowHiddenLeaf(nStartRow
, NULL
, &nEndRow
);
3172 if (nEndRow
> nRow2
)
3175 bool bChanged
= ( bWasVis
!= bShow
);
3177 SetRowHidden(nStartRow
, nEndRow
, !bShow
);
3179 SetRowFiltered(nStartRow
, nEndRow
, false);
3183 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3185 pCharts
->SetRangeDirty(ScRange( 0, nStartRow
, nTab
, MAXCOL
, nEndRow
, nTab
));
3187 InvalidatePageBreaks();
3190 nStartRow
= nEndRow
+ 1;
3195 // #i116164# set the flags for the whole range at once
3196 SetRowHidden(nRow1
, nRow2
, !bShow
);
3198 SetRowFiltered(nRow1
, nRow2
, false);
3202 bool ScTable::IsDataFiltered(SCCOL nColStart
, SCROW nRowStart
, SCCOL nColEnd
, SCROW nRowEnd
) const
3204 for (SCROW i
= nRowStart
; i
<= nRowEnd
; ++i
)
3209 for (SCCOL i
= nColStart
; i
<= nColEnd
; ++i
)
3217 bool ScTable::IsDataFiltered(const ScRange
& rRange
) const
3219 return IsDataFiltered(rRange
.aStart
.Col(), rRange
.aStart
.Row(),
3220 rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
3223 void ScTable::SetRowFlags( SCROW nRow
, sal_uInt8 nNewFlags
)
3225 if (ValidRow(nRow
) && pRowFlags
)
3226 pRowFlags
->SetValue( nRow
, nNewFlags
);
3229 OSL_FAIL("Invalid row number or no flags");
3233 void ScTable::SetRowFlags( SCROW nStartRow
, SCROW nEndRow
, sal_uInt8 nNewFlags
)
3235 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && pRowFlags
)
3236 pRowFlags
->SetValue( nStartRow
, nEndRow
, nNewFlags
);
3239 OSL_FAIL("Invalid row number(s) or no flags");
3243 sal_uInt8
ScTable::GetColFlags( SCCOL nCol
) const
3245 if (ValidCol(nCol
) && pColFlags
)
3246 return pColFlags
[nCol
];
3251 sal_uInt8
ScTable::GetRowFlags( SCROW nRow
) const
3253 if (ValidRow(nRow
) && pRowFlags
)
3254 return pRowFlags
->GetValue(nRow
);
3259 SCROW
ScTable::GetLastFlaggedRow() const
3261 SCROW nLastFound
= 0;
3264 SCROW nRow
= pRowFlags
->GetLastAnyBitAccess( 0, sal::static_int_cast
<sal_uInt8
>(CR_ALL
) );
3269 if (!maRowManualBreaks
.empty())
3270 nLastFound
= ::std::max(nLastFound
, *maRowManualBreaks
.rbegin());
3274 SCROW nRow
= mpHiddenRows
->findLastNotOf(false);
3276 nLastFound
= ::std::max(nLastFound
, nRow
);
3281 SCROW nRow
= mpFilteredRows
->findLastNotOf(false);
3283 nLastFound
= ::std::max(nLastFound
, nRow
);
3289 SCCOL
ScTable::GetLastChangedCol() const
3294 SCCOL nLastFound
= 0;
3295 for (SCCOL nCol
= 1; nCol
<= MAXCOL
; nCol
++)
3296 if ((pColFlags
[nCol
] & CR_ALL
) || (pColWidth
[nCol
] != STD_COL_WIDTH
))
3302 SCROW
ScTable::GetLastChangedRow() const
3307 SCROW nLastFlags
= GetLastFlaggedRow();
3309 // Find the last row position where the height is NOT the standard row
3311 // KOHEI: Test this to make sure it does what it's supposed to.
3312 SCROW nLastHeight
= mpRowHeights
->findLastNotOf(ScGlobal::nStdRowHeight
);
3313 if (!ValidRow(nLastHeight
))
3316 return std::max( nLastFlags
, nLastHeight
);
3319 bool ScTable::UpdateOutlineCol( SCCOL nStartCol
, SCCOL nEndCol
, bool bShow
)
3321 if (pOutlineTable
&& pColFlags
)
3323 ScBitMaskCompressedArray
< SCCOLROW
, sal_uInt8
> aArray( MAXCOL
, pColFlags
, MAXCOLCOUNT
);
3324 return pOutlineTable
->GetColArray().ManualAction( nStartCol
, nEndCol
, bShow
, *this, true );
3330 bool ScTable::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, bool bShow
)
3332 if (pOutlineTable
&& pRowFlags
)
3333 return pOutlineTable
->GetRowArray().ManualAction( nStartRow
, nEndRow
, bShow
, *this, false );
3338 void ScTable::ExtendHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
3340 // Column-wise expansion
3342 while (rX1
> 0 && ColHidden(rX1
-1))
3345 while (rX2
< MAXCOL
&& ColHidden(rX2
+1))
3348 // Row-wise expansion
3352 ScFlatBoolRowSegments::RangeData aData
;
3353 if (mpHiddenRows
->getRangeData(rY1
-1, aData
) && aData
.mbValue
)
3355 SCROW nStartRow
= aData
.mnRow1
;
3356 if (ValidRow(nStartRow
))
3363 if (RowHidden(rY2
+1, NULL
, &nEndRow
) && ValidRow(nEndRow
))
3368 void ScTable::StripHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
3370 while ( rX2
>rX1
&& ColHidden(rX2
) )
3372 while ( rX2
>rX1
&& ColHidden(rX1
) )
3377 ScFlatBoolRowSegments::RangeData aData
;
3378 if (mpHiddenRows
->getRangeData(rY2
, aData
) && aData
.mbValue
)
3380 SCROW nStartRow
= aData
.mnRow1
;
3381 if (ValidRow(nStartRow
) && nStartRow
>= rY1
)
3389 if (RowHidden(rY1
, NULL
, &nEndRow
) && ValidRow(nEndRow
) && nEndRow
<= rY2
)
3396 template< typename T
>
3397 short DiffSign( T a
, T b
)
3405 class OutlineArrayFinder
3410 ScOutlineArray
* mpArray
;
3414 OutlineArrayFinder(const ScRange
& rRef
, SCCOL nCol
, SCTAB nTab
, ScOutlineArray
* pArray
, bool bSizeChanged
) :
3415 maRef(rRef
), mnCol(nCol
), mnTab(nTab
), mpArray(pArray
),
3416 mbSizeChanged(bSizeChanged
) {}
3418 bool operator() (size_t nRow
, const ScFormulaCell
* pCell
)
3420 SCROW nRow2
= static_cast<SCROW
>(nRow
);
3422 if (!pCell
->HasRefListExpressibleAsOneReference(maRef
))
3425 if (maRef
.aStart
.Row() != nRow2
|| maRef
.aEnd
.Row() != nRow2
||
3426 maRef
.aStart
.Tab() != mnTab
|| maRef
.aEnd
.Tab() != mnTab
)
3429 if (DiffSign(maRef
.aStart
.Col(), mnCol
) != DiffSign(maRef
.aEnd
.Col(), mnCol
))
3432 return mpArray
->Insert(maRef
.aStart
.Col(), maRef
.aEnd
.Col(), mbSizeChanged
);
3438 void ScTable::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
)
3440 typedef mdds::flat_segment_tree
<SCROW
, bool> UsedRowsType
;
3442 bool bSizeChanged
= false;
3449 StartOutlineTable();
3453 UsedRowsType
aUsed(0, MAXROW
+1, false);
3454 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3455 aCol
[nCol
].FindUsed(nStartRow
, nEndRow
, aUsed
);
3458 ScOutlineArray
& rRowArray
= pOutlineTable
->GetRowArray();
3459 for (nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
3462 SCROW nLastRow
= nRow
;
3463 aUsed
.search_tree(nRow
, bUsed
, NULL
, &nLastRow
);
3471 for (nCol
=nStartCol
; nCol
<=nEndCol
&& !bFound
; nCol
++)
3473 ScRefCellValue aCell
= aCol
[nCol
].GetCellValue(nRow
);
3475 if (aCell
.meType
!= CELLTYPE_FORMULA
)
3478 if (!aCell
.mpFormula
->HasRefListExpressibleAsOneReference(aRef
))
3481 if ( aRef
.aStart
.Col() == nCol
&& aRef
.aEnd
.Col() == nCol
&&
3482 aRef
.aStart
.Tab() == nTab
&& aRef
.aEnd
.Tab() == nTab
&&
3483 DiffSign( aRef
.aStart
.Row(), nRow
) ==
3484 DiffSign( aRef
.aEnd
.Row(), nRow
) )
3486 if (rRowArray
.Insert( aRef
.aStart
.Row(), aRef
.aEnd
.Row(), bSizeChanged
))
3495 ScOutlineArray
& rColArray
= pOutlineTable
->GetColArray();
3496 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3498 if (aCol
[nCol
].IsEmptyData())
3501 OutlineArrayFinder
aFunc(aRef
, nCol
, nTab
, &rColArray
, bSizeChanged
);
3502 sc::FindFormula(aCol
[nCol
].maCells
, nStartRow
, nEndRow
, aFunc
);
3506 // CopyData - for Query in other range
3508 void ScTable::CopyData( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
3509 SCCOL nDestCol
, SCROW nDestRow
, SCTAB nDestTab
)
3511 //TODO: if used for multipe rows, optimize after columns!
3513 ScAddress
aSrc( nStartCol
, nStartRow
, nTab
);
3514 ScAddress
aDest( nDestCol
, nDestRow
, nDestTab
);
3515 ScRange
aRange( aSrc
, aDest
);
3516 bool bThisTab
= ( nDestTab
== nTab
);
3517 SCROW nDestY
= nDestRow
;
3518 for (SCROW nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
3520 aSrc
.SetRow( nRow
);
3521 aDest
.SetRow( nDestY
);
3522 SCCOL nDestX
= nDestCol
;
3523 for (SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3525 aSrc
.SetCol( nCol
);
3526 aDest
.SetCol( nDestX
);
3528 aCell
.assign(*pDocument
, ScAddress(nCol
, nRow
, nTab
));
3530 if (aCell
.meType
== CELLTYPE_FORMULA
)
3532 sc::RefUpdateContext
aCxt(*pDocument
);
3533 aCxt
.meMode
= URM_COPY
;
3534 aCxt
.maRange
= aRange
;
3535 aCxt
.mnColDelta
= nDestCol
- nStartCol
;
3536 aCxt
.mnRowDelta
= nDestRow
- nStartRow
;
3537 aCxt
.mnTabDelta
= nDestTab
- nTab
;
3538 aCell
.mpFormula
->UpdateReference(aCxt
);
3539 aCell
.mpFormula
->aPos
= aDest
;
3544 aCell
.release(aCol
[nDestX
], nDestY
);
3545 SetPattern( nDestX
, nDestY
, *GetPattern( nCol
, nRow
), true );
3549 aCell
.release(*pDocument
, aDest
);
3550 pDocument
->SetPattern( aDest
, *GetPattern( nCol
, nRow
), true );
3559 bool ScTable::RefVisible(ScFormulaCell
* pCell
)
3563 if (pCell
->HasOneReference(aRef
))
3565 if (aRef
.aStart
.Col()==aRef
.aEnd
.Col() && aRef
.aStart
.Tab()==aRef
.aEnd
.Tab())
3568 if (!RowFiltered(aRef
.aStart
.Row(), NULL
, &nEndRow
))
3569 // row not filtered.
3570 nEndRow
= ::std::numeric_limits
<SCROW
>::max();
3572 if (!ValidRow(nEndRow
) || nEndRow
< aRef
.aEnd
.Row())
3573 return true; // at least partly visible
3574 return false; // completely invisible
3578 return true; // somehow different
3581 void ScTable::GetUpperCellString(SCCOL nCol
, SCROW nRow
, OUString
& rStr
)
3583 GetInputString(nCol
, nRow
, rStr
);
3584 rStr
= ScGlobal::pCharClass
->uppercase(rStr
.trim());
3587 // Calculate the size of the sheet and set the size on DrawPage
3589 void ScTable::SetDrawPageSize(bool bResetStreamValid
, bool bUpdateNoteCaptionPos
)
3591 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
3594 double fValX
= GetColOffset( MAXCOL
+ 1 ) * HMM_PER_TWIPS
;
3595 double fValY
= GetRowOffset( MAXROW
+ 1 ) * HMM_PER_TWIPS
;
3596 const long nMax
= ::std::numeric_limits
<long>::max();
3597 // #i113884# Avoid int32 overflow with possible negative results than can cause bad effects.
3598 // If the draw page size is smaller than all rows, only the bottom of the sheet is affected.
3599 long x
= ( fValX
> (double)nMax
) ? nMax
: (long) fValX
;
3600 long y
= ( fValY
> (double)nMax
) ? nMax
: (long) fValY
;
3602 if ( IsLayoutRTL() ) // IsNegativePage
3605 pDrawLayer
->SetPageSize( static_cast<sal_uInt16
>(nTab
), Size( x
, y
), bUpdateNoteCaptionPos
);
3608 // #i102616# actions that modify the draw page size count as sheet modification
3609 // (exception: InitDrawLayer)
3610 if (bResetStreamValid
&& IsStreamValid())
3611 SetStreamValid(false);
3614 void ScTable::SetRangeName(ScRangeName
* pNew
)
3619 //fdo#39792: mark stream as invalid, otherwise new ScRangeName will not be written to file
3620 if (IsStreamValid())
3621 SetStreamValid(false);
3624 ScRangeName
* ScTable::GetRangeName() const
3627 mpRangeName
= new ScRangeName
;
3631 sal_uLong
ScTable::GetRowOffset( SCROW nRow
, bool bHiddenAsZero
) const
3634 if ( mpHiddenRows
&& mpRowHeights
)
3639 return GetRowHeight(0, NULL
, NULL
, bHiddenAsZero
);
3641 n
= GetTotalRowHeight(0, nRow
-1, bHiddenAsZero
);
3642 #if OSL_DEBUG_LEVEL > 0
3643 if (n
== ::std::numeric_limits
<unsigned long>::max())
3644 OSL_FAIL("ScTable::GetRowOffset: row heights overflow");
3649 OSL_FAIL("GetRowOffset: Data missing");
3654 SCROW
ScTable::GetRowForHeight(sal_uLong nHeight
) const
3656 sal_uInt32 nSum
= 0;
3658 ScFlatBoolRowSegments::RangeData aData
;
3659 for (SCROW nRow
= 0; nRow
<= MAXROW
; ++nRow
)
3661 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
3666 nRow
= aData
.mnRow2
;
3670 sal_uInt32 nNew
= mpRowHeights
->getValue(nRow
);
3674 return nRow
< MAXROW
? nRow
+ 1 : MAXROW
;
3680 sal_uLong
ScTable::GetColOffset( SCCOL nCol
, bool bHiddenAsZero
) const
3686 for( i
= 0; i
< nCol
; i
++ )
3687 if (!( bHiddenAsZero
&& ColHidden(i
) ))
3692 OSL_FAIL("GetColumnOffset: Data missing");
3697 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */