Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "table.hxx"
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"
37 : #include "postit.hxx"
38 : #include "sheetevents.hxx"
39 : #include "globstr.hrc"
40 : #include "segmenttree.hxx"
41 : #include "queryparam.hxx"
42 : #include "queryentry.hxx"
43 : #include "dbdata.hxx"
44 : #include "colorscale.hxx"
45 : #include "tokenarray.hxx"
46 : #include "clipcontext.hxx"
47 : #include "types.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>
56 :
57 : #include "scitems.hxx"
58 : #include <editeng/boxitem.hxx>
59 : #include <editeng/editobj.hxx>
60 : #include <svl/poolcach.hxx>
61 : #include <unotools/charclass.hxx>
62 : #include <math.h>
63 : #include <svl/PasswordHelper.hxx>
64 : #include <unotools/transliterationwrapper.hxx>
65 :
66 : namespace {
67 :
68 : class ColumnRegroupFormulaCells
69 : {
70 : ScColumn* mpCols;
71 : public:
72 216 : ColumnRegroupFormulaCells(ScColumn* pCols) : mpCols(pCols) {}
73 :
74 146 : void operator() (SCCOL nCol)
75 : {
76 146 : mpCols[nCol].RegroupFormulaCells();
77 146 : }
78 : };
79 :
80 : }
81 :
82 2 : sal_uInt16 ScTable::GetTextWidth(SCCOL nCol, SCROW nRow) const
83 : {
84 2 : return aCol[nCol].GetTextWidth(nRow);
85 : }
86 :
87 686 : bool ScTable::SetOutlineTable( const ScOutlineTable* pNewOutline )
88 : {
89 686 : sal_uInt16 nOldSizeX = 0;
90 686 : sal_uInt16 nOldSizeY = 0;
91 686 : sal_uInt16 nNewSizeX = 0;
92 686 : sal_uInt16 nNewSizeY = 0;
93 :
94 686 : if (pOutlineTable)
95 : {
96 8 : nOldSizeX = pOutlineTable->GetColArray().GetDepth();
97 8 : nOldSizeY = pOutlineTable->GetRowArray().GetDepth();
98 8 : delete pOutlineTable;
99 : }
100 :
101 686 : if (pNewOutline)
102 : {
103 66 : pOutlineTable = new ScOutlineTable( *pNewOutline );
104 66 : nNewSizeX = pOutlineTable->GetColArray().GetDepth();
105 66 : nNewSizeY = pOutlineTable->GetRowArray().GetDepth();
106 : }
107 : else
108 620 : pOutlineTable = NULL;
109 :
110 686 : return ( nNewSizeX != nOldSizeX || nNewSizeY != nOldSizeY ); // Groesse geaendert ?
111 : }
112 :
113 424 : void ScTable::StartOutlineTable()
114 : {
115 424 : if (!pOutlineTable)
116 424 : pOutlineTable = new ScOutlineTable;
117 424 : }
118 :
119 44 : void ScTable::SetSheetEvents( const ScSheetEvents* pNew )
120 : {
121 44 : delete pSheetEvents;
122 44 : if (pNew)
123 0 : pSheetEvents = new ScSheetEvents(*pNew);
124 : else
125 44 : pSheetEvents = NULL;
126 :
127 44 : SetCalcNotification( false ); // discard notifications before the events were set
128 :
129 44 : if (IsStreamValid())
130 0 : SetStreamValid(false);
131 44 : }
132 :
133 44 : void ScTable::SetCalcNotification( bool bSet )
134 : {
135 44 : bCalcNotification = bSet;
136 44 : }
137 :
138 98 : bool ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize ) const
139 : {
140 98 : bool bTest = true;
141 :
142 98 : if ( nStartCol==0 && nEndCol==MAXCOL && pOutlineTable )
143 0 : bTest = pOutlineTable->TestInsertRow(nSize);
144 :
145 82036 : for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
146 81938 : bTest = aCol[i].TestInsertRow(nStartRow, nSize);
147 :
148 98 : return bTest;
149 : }
150 :
151 98 : void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize )
152 : {
153 98 : if (nStartCol==0 && nEndCol==MAXCOL)
154 : {
155 80 : if (mpRowHeights && pRowFlags)
156 : {
157 80 : mpRowHeights->insertSegment(nStartRow, nSize, false);
158 80 : sal_uInt8 nNewFlags = pRowFlags->Insert( nStartRow, nSize);
159 : // only copy manual size flag, clear all others
160 80 : if (nNewFlags && (nNewFlags != CR_MANUALSIZE))
161 : pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1,
162 0 : nNewFlags & CR_MANUALSIZE);
163 : }
164 :
165 80 : if (pOutlineTable)
166 0 : pOutlineTable->InsertRow( nStartRow, nSize );
167 :
168 80 : mpFilteredRows->insertSegment(nStartRow, nSize, true);
169 80 : mpHiddenRows->insertSegment(nStartRow, nSize, true);
170 :
171 80 : if (!maRowManualBreaks.empty())
172 : {
173 : // Copy all breaks up to nStartRow (non-inclusive).
174 0 : ::std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
175 0 : ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
176 :
177 : // Copy all breaks from nStartRow (inclusive) to the last element,
178 : // but add nSize to each value.
179 0 : ::std::set<SCROW>::iterator itr2 = maRowManualBreaks.end();
180 0 : for (; itr1 != itr2; ++itr1)
181 0 : aNewBreaks.insert(static_cast<SCROW>(*itr1 + nSize));
182 :
183 0 : maRowManualBreaks.swap(aNewBreaks);
184 : }
185 : }
186 :
187 82036 : for (SCCOL j=nStartCol; j<=nEndCol; j++)
188 81938 : aCol[j].InsertRow( nStartRow, nSize );
189 :
190 98 : mpCondFormatList->InsertRow(nTab, nStartCol, nEndCol, nStartRow, nSize);
191 :
192 98 : InvalidatePageBreaks();
193 :
194 98 : if (IsStreamValid())
195 : // TODO: In the future we may want to check if the table has been
196 : // really modified before setting the stream invalid.
197 2 : SetStreamValid(false);
198 98 : }
199 :
200 92 : void ScTable::DeleteRow(
201 : const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
202 : bool* pUndoOutline )
203 : {
204 92 : if (nStartCol==0 && nEndCol==MAXCOL)
205 : {
206 72 : if (pRowFlags)
207 72 : pRowFlags->Remove( nStartRow, nSize);
208 :
209 72 : if (mpRowHeights)
210 72 : mpRowHeights->removeSegment(nStartRow, nStartRow+nSize);
211 :
212 72 : if (pOutlineTable)
213 4 : if (pOutlineTable->DeleteRow( nStartRow, nSize ))
214 0 : if (pUndoOutline)
215 0 : *pUndoOutline = true;
216 :
217 72 : mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
218 72 : mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
219 :
220 72 : if (!maRowManualBreaks.empty())
221 : {
222 : // Erase all manual breaks between nStartRow and nStartRow + nSize - 1 (inclusive).
223 0 : std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
224 0 : std::set<SCROW>::iterator itr2 = maRowManualBreaks.upper_bound(static_cast<SCROW>(nStartRow + nSize - 1));
225 0 : maRowManualBreaks.erase(itr1, itr2);
226 :
227 : // Copy all breaks from the 1st element up to nStartRow to the new container.
228 0 : itr1 = maRowManualBreaks.lower_bound(nStartRow);
229 0 : ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
230 :
231 : // Copy all breaks from nStartRow to the last element, but subtract each value by nSize.
232 0 : itr2 = maRowManualBreaks.end();
233 0 : for (; itr1 != itr2; ++itr1)
234 0 : aNewBreaks.insert(static_cast<SCROW>(*itr1 - nSize));
235 :
236 0 : maRowManualBreaks.swap(aNewBreaks);
237 : }
238 : }
239 :
240 : { // scope for bulk broadcast
241 92 : ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
242 73842 : for (SCCOL j=nStartCol; j<=nEndCol; j++)
243 73842 : aCol[j].DeleteRow( nStartRow, nSize );
244 : }
245 :
246 92 : std::vector<SCCOL> aRegroupCols;
247 92 : rRegroupCols.getColumns(nTab, aRegroupCols);
248 92 : std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol));
249 :
250 92 : InvalidatePageBreaks();
251 :
252 92 : if (IsStreamValid())
253 : // TODO: In the future we may want to check if the table has been
254 : // really modified before setting the stream invalid.
255 0 : SetStreamValid(false);
256 92 : }
257 :
258 72 : bool ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize ) const
259 : {
260 72 : bool bTest = true;
261 :
262 72 : if ( nStartRow==0 && nEndRow==MAXROW && pOutlineTable )
263 0 : bTest = pOutlineTable->TestInsertCol(nSize);
264 :
265 72 : if ( nSize > static_cast<SCSIZE>(MAXCOL) )
266 0 : bTest = false;
267 :
268 190 : for (SCCOL i=MAXCOL; (i+static_cast<SCCOL>(nSize)>MAXCOL) && bTest; i--)
269 118 : bTest = aCol[i].TestInsertCol(nStartRow, nEndRow);
270 :
271 72 : return bTest;
272 : }
273 :
274 72 : void ScTable::InsertCol(
275 : const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
276 : {
277 72 : if (nStartRow==0 && nEndRow==MAXROW)
278 : {
279 54 : if (pColWidth && pColFlags)
280 : {
281 108 : memmove( &pColWidth[nStartCol+nSize], &pColWidth[nStartCol],
282 162 : (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
283 54 : memmove( &pColFlags[nStartCol+nSize], &pColFlags[nStartCol],
284 108 : (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
285 : }
286 54 : if (pOutlineTable)
287 0 : pOutlineTable->InsertCol( nStartCol, nSize );
288 :
289 54 : mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
290 54 : mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
291 :
292 54 : if (!maColManualBreaks.empty())
293 : {
294 0 : std::set<SCCOL>::reverse_iterator rit = maColManualBreaks.rbegin();
295 0 : while (rit != maColManualBreaks.rend())
296 : {
297 0 : SCCOL nCol = *rit;
298 0 : if (nCol < nStartCol)
299 0 : break; // while
300 : else
301 : {
302 0 : maColManualBreaks.erase( (++rit).base());
303 0 : maColManualBreaks.insert( static_cast<SCCOL>( nCol + nSize));
304 : }
305 : }
306 : }
307 : }
308 :
309 72 : if ((nStartRow == 0) && (nEndRow == MAXROW))
310 : {
311 140 : for (SCSIZE i=0; i < nSize; i++)
312 87880 : for (SCCOL nCol = MAXCOL; nCol > nStartCol; nCol--)
313 87848 : aCol[nCol].SwapCol(aCol[nCol-1]);
314 : }
315 : else
316 : {
317 18382 : for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
318 18364 : aCol[MAXCOL - nSize - i].MoveTo(nStartRow, nEndRow, aCol[MAXCOL - i]);
319 : }
320 :
321 72 : std::vector<SCCOL> aRegroupCols;
322 72 : rRegroupCols.getColumns(nTab, aRegroupCols);
323 72 : std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol));
324 :
325 72 : if (nStartCol>0) // copy old attributes
326 : {
327 : sal_uInt16 nWhichArray[2];
328 50 : nWhichArray[0] = ATTR_MERGE;
329 50 : nWhichArray[1] = 0;
330 :
331 50 : sc::CopyToDocContext aCxt(*pDocument);
332 132 : for (SCSIZE i=0; i<nSize; i++)
333 : {
334 82 : aCol[nStartCol-1].CopyToColumn(aCxt, nStartRow, nEndRow, IDF_ATTRIB,
335 164 : false, aCol[nStartCol+i] );
336 82 : aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
337 82 : SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
338 82 : aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray );
339 50 : }
340 : }
341 :
342 72 : mpCondFormatList->InsertCol(nTab, nStartRow, nEndRow, nStartCol, nSize);
343 :
344 72 : InvalidatePageBreaks();
345 :
346 72 : if (IsStreamValid())
347 : // TODO: In the future we may want to check if the table has been
348 : // really modified before setting the stream invalid.
349 0 : SetStreamValid(false);
350 72 : }
351 :
352 52 : void ScTable::DeleteCol(
353 : const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, bool* pUndoOutline )
354 : {
355 52 : if (nStartRow==0 && nEndRow==MAXROW)
356 : {
357 44 : if (pColWidth && pColFlags)
358 : {
359 88 : memmove( &pColWidth[nStartCol], &pColWidth[nStartCol+nSize],
360 132 : (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
361 88 : memmove( &pColFlags[nStartCol], &pColFlags[nStartCol+nSize],
362 132 : (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
363 : }
364 44 : if (pOutlineTable)
365 0 : if (pOutlineTable->DeleteCol( nStartCol, nSize ))
366 0 : if (pUndoOutline)
367 0 : *pUndoOutline = true;
368 :
369 44 : SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize);
370 44 : mpHiddenCols->removeSegment(nStartCol, nRmSize);
371 44 : mpFilteredCols->removeSegment(nStartCol, nRmSize);
372 :
373 44 : if (!maColManualBreaks.empty())
374 : {
375 0 : std::set<SCCOL>::iterator it = maColManualBreaks.upper_bound( static_cast<SCCOL>( nStartCol + nSize - 1));
376 0 : maColManualBreaks.erase( maColManualBreaks.lower_bound( nStartCol), it);
377 0 : while (it != maColManualBreaks.end())
378 : {
379 0 : SCCOL nCol = *it;
380 0 : maColManualBreaks.erase( it++);
381 0 : maColManualBreaks.insert( static_cast<SCCOL>( nCol - nSize));
382 : }
383 : }
384 : }
385 :
386 136 : for (SCSIZE i = 0; i < nSize; i++)
387 84 : aCol[nStartCol + i].DeleteArea(nStartRow, nEndRow, IDF_ALL, false);
388 :
389 52 : if ((nStartRow == 0) && (nEndRow == MAXROW))
390 : {
391 114 : for (SCSIZE i=0; i < nSize; i++)
392 71530 : for (SCCOL nCol = nStartCol; nCol < MAXCOL; nCol++)
393 71504 : aCol[nCol].SwapCol(aCol[nCol+1]);
394 : }
395 : else
396 : {
397 8132 : for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
398 8124 : aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
399 : }
400 :
401 52 : std::vector<SCCOL> aRegroupCols;
402 52 : rRegroupCols.getColumns(nTab, aRegroupCols);
403 52 : std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol));
404 :
405 52 : InvalidatePageBreaks();
406 :
407 52 : if (IsStreamValid())
408 : // TODO: In the future we may want to check if the table has been
409 : // really modified before setting the stream invalid.
410 0 : SetStreamValid(false);
411 52 : }
412 :
413 2478 : void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag)
414 : {
415 2478 : if (nCol2 > MAXCOL) nCol2 = MAXCOL;
416 2478 : if (nRow2 > MAXROW) nRow2 = MAXROW;
417 2478 : if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
418 : {
419 : { // scope for bulk broadcast
420 2478 : ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
421 97530 : for (SCCOL i = nCol1; i <= nCol2; i++)
422 97530 : aCol[i].DeleteArea(nRow1, nRow2, nDelFlag);
423 : }
424 :
425 : // Zellschutz auf geschuetzter Tabelle nicht setzen
426 :
427 2478 : if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
428 : {
429 0 : ScPatternAttr aPattern(pDocument->GetPool());
430 0 : aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
431 0 : ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
432 : }
433 :
434 2478 : if( nDelFlag & IDF_ATTRIB )
435 598 : mpCondFormatList->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
436 : }
437 :
438 2478 : if (IsStreamValid())
439 : // TODO: In the future we may want to check if the table has been
440 : // really modified before setting the stream invalid.
441 0 : SetStreamValid(false);
442 2478 : }
443 :
444 186 : void ScTable::DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast )
445 : {
446 : { // scope for bulk broadcast
447 186 : ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
448 190650 : for (SCCOL i=0; i<=MAXCOL; i++)
449 190650 : aCol[i].DeleteSelection(nDelFlag, rMark, bBroadcast);
450 : }
451 :
452 186 : ScRangeList aRangeList;
453 186 : rMark.FillRangeListWithMarks(&aRangeList, false);
454 :
455 376 : for (size_t i = 0; i < aRangeList.size(); ++i)
456 : {
457 190 : ScRange* pRange = aRangeList[i];
458 :
459 190 : if((nDelFlag & IDF_ATTRIB) && pRange && pRange->aStart.Tab() == nTab)
460 142 : mpCondFormatList->DeleteArea( pRange->aStart.Col(), pRange->aStart.Row(), pRange->aEnd.Col(), pRange->aEnd.Row() );
461 : }
462 :
463 : // Zellschutz auf geschuetzter Tabelle nicht setzen
464 :
465 186 : if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
466 : {
467 0 : ScDocumentPool* pPool = pDocument->GetPool();
468 0 : SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
469 0 : aSet.Put( ScProtectionAttr( false ) );
470 0 : SfxItemPoolCache aCache( pPool, &aSet );
471 0 : ApplySelectionCache( &aCache, rMark );
472 : }
473 :
474 186 : if (IsStreamValid())
475 : // TODO: In the future we may want to check if the table has been
476 : // really modified before setting the stream invalid.
477 0 : SetStreamValid(false);
478 186 : }
479 :
480 : // pTable = Clipboard
481 104 : void ScTable::CopyToClip(
482 : sc::CopyToClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
483 : ScTable* pTable )
484 : {
485 104 : if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
486 104 : return;
487 :
488 : // copy content
489 : //local range names need to be copied first for formula cells
490 104 : if (!pTable->mpRangeName && mpRangeName)
491 38 : pTable->mpRangeName = new ScRangeName(*mpRangeName);
492 :
493 : SCCOL i;
494 :
495 254 : for ( i = nCol1; i <= nCol2; i++)
496 150 : aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->aCol[i]); // notes are handled at column level
497 :
498 : // copy widths/heights, and only "hidden", "filtered" and "manual" flags
499 : // also for all preceding columns/rows, to have valid positions for drawing objects
500 :
501 104 : if (pColWidth && pTable->pColWidth)
502 358 : for (i=0; i<=nCol2; i++)
503 254 : pTable->pColWidth[i] = pColWidth[i];
504 :
505 104 : pTable->CopyColHidden(*this, 0, nCol2);
506 104 : pTable->CopyColFiltered(*this, 0, nCol2);
507 104 : if (pDBDataNoName)
508 8 : pTable->SetAnonymousDBData(new ScDBData(*pDBDataNoName));
509 :
510 104 : if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights)
511 : {
512 104 : pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
513 104 : pTable->CopyRowHeight(*this, 0, nRow2, 0);
514 : }
515 :
516 104 : pTable->CopyRowHidden(*this, 0, nRow2);
517 104 : pTable->CopyRowFiltered(*this, 0, nRow2);
518 :
519 : // ggf. Formeln durch Werte ersetzen
520 :
521 104 : if ( IsProtected() )
522 0 : for (i = nCol1; i <= nCol2; i++)
523 0 : pTable->aCol[i].RemoveProtected(nRow1, nRow2);
524 :
525 104 : pTable->mpCondFormatList.reset(new ScConditionalFormatList(pTable->pDocument, *mpCondFormatList));
526 : }
527 :
528 100 : void ScTable::CopyToClip(
529 : sc::CopyToClipContext& rCxt, const ScRangeList& rRanges, ScTable* pTable )
530 : {
531 100 : ScRangeList aRanges(rRanges);
532 204 : for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
533 : {
534 104 : ScRange* p = aRanges[ i ];
535 : CopyToClip(
536 104 : rCxt, p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), pTable);
537 100 : }
538 100 : }
539 :
540 8 : void ScTable::CopyStaticToDocument(
541 : SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const SvNumberFormatterMergeMap& rMap, ScTable* pDestTab )
542 : {
543 8 : if (nCol1 > nCol2)
544 8 : return;
545 :
546 20 : for (SCCOL i = nCol1; i <= nCol2; ++i)
547 : {
548 12 : ScColumn& rSrcCol = aCol[i];
549 12 : ScColumn& rDestCol = pDestTab->aCol[i];
550 12 : rSrcCol.CopyStaticToDocument(nRow1, nRow2, rMap, rDestCol);
551 : }
552 : }
553 :
554 2 : void ScTable::CopyCellToDocument(SCCOL nSrcCol, SCROW nSrcRow, SCCOL nDestCol, SCROW nDestRow, ScTable& rDestTab )
555 : {
556 2 : if (!ValidColRow(nSrcCol, nSrcRow) || !ValidColRow(nDestCol, nDestRow))
557 2 : return;
558 :
559 2 : ScColumn& rSrcCol = aCol[nSrcCol];
560 2 : ScColumn& rDestCol = rDestTab.aCol[nDestCol];
561 2 : rSrcCol.CopyCellToDocument(nSrcRow, nDestRow, rDestCol);
562 : }
563 :
564 1816 : void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
565 : SCsCOL nDx, SCsROW nDy, ScTable* pTable)
566 : {
567 1816 : ScRange aOldRange( nCol1 - nDx, nRow1 - nDy, pTable->nTab, nCol2 - nDx, nRow2 - nDy, pTable->nTab);
568 1816 : ScRange aNewRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
569 1816 : bool bSameDoc = pDocument == pTable->pDocument;
570 :
571 4840 : for(ScConditionalFormatList::const_iterator itr = pTable->mpCondFormatList->begin(),
572 1816 : itrEnd = pTable->mpCondFormatList->end(); itr != itrEnd; ++itr)
573 : {
574 1208 : const ScRangeList& rCondFormatRange = itr->GetRange();
575 1208 : if(!rCondFormatRange.Intersects( aOldRange ))
576 44 : continue;
577 :
578 1164 : ScRangeList aIntersectedRange = rCondFormatRange.GetIntersectedRange(aOldRange);
579 1164 : ScConditionalFormat* pNewFormat = itr->Clone(pDocument);
580 :
581 1164 : pNewFormat->AddRange(aIntersectedRange);
582 2328 : sc::RefUpdateContext aRefCxt(*pDocument);
583 1164 : aRefCxt.meMode = URM_COPY;
584 1164 : aRefCxt.maRange = aNewRange;
585 1164 : aRefCxt.mnColDelta = nDx;
586 1164 : aRefCxt.mnRowDelta = nDy;
587 1164 : aRefCxt.mnTabDelta = nTab - pTable->nTab;
588 1164 : pNewFormat->UpdateReference(aRefCxt, true);
589 :
590 1164 : sal_uLong nMax = 0;
591 6912 : for(ScConditionalFormatList::const_iterator itrCond = mpCondFormatList->begin();
592 4608 : itrCond != mpCondFormatList->end(); ++itrCond)
593 : {
594 1140 : if(itrCond->GetKey() > nMax)
595 1140 : nMax = itrCond->GetKey();
596 : }
597 1164 : pNewFormat->SetKey(nMax + 1);
598 1164 : mpCondFormatList->InsertNew(pNewFormat);
599 :
600 1164 : if(!bSameDoc)
601 : {
602 1172 : for(size_t i = 0, n = pNewFormat->size();
603 : i < n; ++i)
604 : {
605 10 : OUString aStyleName;
606 10 : const ScFormatEntry* pEntry = pNewFormat->GetEntry(i);
607 10 : if(pEntry->GetType() == condformat::CONDITION)
608 10 : aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle();
609 0 : else if(pEntry->GetType() == condformat::DATE)
610 0 : aStyleName = static_cast<const ScCondDateFormatEntry*>(pEntry)->GetStyleName();
611 :
612 10 : if(!aStyleName.isEmpty())
613 : {
614 10 : if(pDocument->GetStyleSheetPool()->Find(aStyleName, SFX_STYLE_FAMILY_PARA))
615 4 : continue;
616 :
617 : pDocument->GetStyleSheetPool()->CopyStyleFrom(
618 6 : pTable->pDocument->GetStyleSheetPool(), aStyleName, SFX_STYLE_FAMILY_PARA );
619 : }
620 6 : }
621 : }
622 :
623 1164 : pDocument->AddCondFormatData( pNewFormat->GetRange(), nTab, pNewFormat->GetKey() );
624 1164 : }
625 1816 : }
626 :
627 368568 : bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol )
628 : {
629 368568 : if (!ValidCol(nCol))
630 0 : return false;
631 :
632 368568 : return aCol[nCol].InitBlockPosition(rBlockPos);
633 : }
634 :
635 136 : void ScTable::CopyFromClip(
636 : sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
637 : SCsCOL nDx, SCsROW nDy, ScTable* pTable )
638 : {
639 :
640 136 : if (nCol2 > MAXCOL)
641 0 : nCol2 = MAXCOL;
642 136 : if (nRow2 > MAXROW)
643 0 : nRow2 = MAXROW;
644 :
645 136 : if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
646 : {
647 562 : for ( SCCOL i = nCol1; i <= nCol2; i++)
648 426 : aCol[i].CopyFromClip(rCxt, nRow1, nRow2, nDy, pTable->aCol[i - nDx]); // notes are handles at column level
649 :
650 136 : if (rCxt.getInsertFlag() & IDF_ATTRIB)
651 : {
652 : // make sure that there are no old references to the cond formats
653 : sal_uInt16 nWhichArray[2];
654 92 : nWhichArray[0] = ATTR_CONDITIONAL;
655 92 : nWhichArray[1] = 0;
656 340 : for ( SCCOL i = nCol1; i <= nCol2; ++i)
657 248 : aCol[i].ClearItems(nRow1, nRow2, nWhichArray);
658 : }
659 :
660 136 : if ((rCxt.getInsertFlag() & IDF_ATTRIB) != IDF_NONE)
661 : {
662 92 : if (nRow1==0 && nRow2==MAXROW && pColWidth && pTable->pColWidth)
663 0 : for (SCCOL i=nCol1; i<=nCol2; i++)
664 0 : pColWidth[i] = pTable->pColWidth[i-nDx];
665 :
666 132 : if (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pTable->mpRowHeights &&
667 92 : pRowFlags && pTable->pRowFlags)
668 : {
669 0 : CopyRowHeight(*pTable, nRow1, nRow2, -nDy);
670 : // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
671 0 : for (SCROW j=nRow1; j<=nRow2; j++)
672 : {
673 0 : if ( pTable->pRowFlags->GetValue(j-nDy) & CR_MANUALSIZE )
674 0 : pRowFlags->OrValue( j, CR_MANUALSIZE);
675 : else
676 0 : pRowFlags->AndValue( j, sal::static_int_cast<sal_uInt8>(~CR_MANUALSIZE));
677 : }
678 : }
679 :
680 : // Zellschutz auf geschuetzter Tabelle nicht setzen
681 92 : if (IsProtected() && (rCxt.getInsertFlag() & IDF_ATTRIB))
682 : {
683 0 : ScPatternAttr aPattern(pDocument->GetPool());
684 0 : aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
685 0 : ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
686 : }
687 :
688 : // create deep copies for conditional formatting
689 92 : CopyConditionalFormat( nCol1, nRow1, nCol2, nRow2, nDx, nDy, pTable);
690 : }
691 : }
692 136 : }
693 :
694 4 : void ScTable::MixData(
695 : sc::MixDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
696 : sal_uInt16 nFunction, bool bSkipEmpty, const ScTable* pSrcTab )
697 : {
698 10 : for (SCCOL i=nCol1; i<=nCol2; i++)
699 6 : aCol[i].MixData(rCxt, nRow1, nRow2, nFunction, bSkipEmpty, pSrcTab->aCol[i]);
700 4 : }
701 :
702 : // Markierung von diesem Dokument
703 0 : void ScTable::MixMarked(
704 : sc::MixDocContext& rCxt, const ScMarkData& rMark, sal_uInt16 nFunction,
705 : bool bSkipEmpty, const ScTable* pSrcTab )
706 : {
707 0 : for (SCCOL i=0; i<=MAXCOL; i++)
708 0 : aCol[i].MixMarked(rCxt, rMark, nFunction, bSkipEmpty, pSrcTab->aCol[i]);
709 0 : }
710 :
711 : namespace {
712 :
713 : class TransClipHandler
714 : {
715 : ScTable& mrClipTab;
716 : SCTAB mnSrcTab;
717 : SCCOL mnSrcCol;
718 : size_t mnTopRow;
719 : SCROW mnTransRow;
720 : bool mbAsLink;
721 : bool mbWasCut;
722 :
723 2 : ScAddress getDestPos(size_t nRow) const
724 : {
725 2 : return ScAddress(static_cast<SCCOL>(nRow-mnTopRow), mnTransRow, mrClipTab.GetTab());
726 : }
727 :
728 0 : ScFormulaCell* createRefCell(size_t nSrcRow, const ScAddress& rDestPos) const
729 : {
730 0 : ScAddress aSrcPos(mnSrcCol, nSrcRow, mnSrcTab);
731 : ScSingleRefData aRef;
732 0 : aRef.InitAddress(aSrcPos); // Absolute reference.
733 0 : aRef.SetFlag3D(true);
734 :
735 0 : ScTokenArray aArr;
736 0 : aArr.AddSingleReference(aRef);
737 0 : return new ScFormulaCell(&mrClipTab.GetDoc(), rDestPos, aArr);
738 : }
739 :
740 0 : void setLink(size_t nRow)
741 : {
742 0 : SCCOL nTransCol = nRow - mnTopRow;
743 : mrClipTab.SetFormulaCell(
744 0 : nTransCol, mnTransRow, createRefCell(nRow, getDestPos(nRow)));
745 0 : }
746 :
747 : public:
748 6 : TransClipHandler(ScTable& rClipTab, SCTAB nSrcTab, SCCOL nSrcCol, size_t nTopRow, SCROW nTransRow, bool bAsLink, bool bWasCut) :
749 : mrClipTab(rClipTab), mnSrcTab(nSrcTab), mnSrcCol(nSrcCol),
750 6 : mnTopRow(nTopRow), mnTransRow(nTransRow), mbAsLink(bAsLink), mbWasCut(bWasCut) {}
751 :
752 2 : void operator() (size_t nRow, double fVal)
753 : {
754 2 : if (mbAsLink)
755 : {
756 0 : setLink(nRow);
757 2 : return;
758 : }
759 :
760 2 : SCCOL nTransCol = nRow - mnTopRow;
761 2 : mrClipTab.SetValue(nTransCol, mnTransRow, fVal);
762 : }
763 :
764 2 : void operator() (size_t nRow, const svl::SharedString& rStr)
765 : {
766 2 : if (mbAsLink)
767 : {
768 0 : setLink(nRow);
769 2 : return;
770 : }
771 :
772 2 : SCCOL nTransCol = nRow - mnTopRow;
773 2 : mrClipTab.SetRawString(nTransCol, mnTransRow, rStr);
774 : }
775 :
776 0 : void operator() (size_t nRow, const EditTextObject* p)
777 : {
778 0 : if (mbAsLink)
779 : {
780 0 : setLink(nRow);
781 0 : return;
782 : }
783 :
784 0 : SCCOL nTransCol = nRow - mnTopRow;
785 0 : mrClipTab.SetEditText(nTransCol, mnTransRow, ScEditUtil::Clone(*p, mrClipTab.GetDoc()));
786 : }
787 :
788 2 : void operator() (size_t nRow, const ScFormulaCell* p)
789 : {
790 2 : if (mbAsLink)
791 : {
792 0 : setLink(nRow);
793 2 : return;
794 : }
795 :
796 : ScFormulaCell* pNew = new ScFormulaCell(
797 2 : *p, mrClipTab.GetDoc(), getDestPos(nRow), SC_CLONECELL_STARTLISTENING);
798 :
799 : // Referenzen drehen
800 : // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
801 :
802 2 : if (!mbWasCut)
803 2 : pNew->TransposeReference();
804 :
805 2 : SCCOL nTransCol = nRow - mnTopRow;
806 2 : mrClipTab.SetFormulaCell(nTransCol, mnTransRow, pNew);
807 : }
808 : };
809 :
810 : }
811 :
812 2 : void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
813 : ScTable* pTransClip, InsertDeleteFlags nFlags, bool bAsLink )
814 : {
815 2 : bool bWasCut = pDocument->IsCutMode();
816 :
817 2 : ScDocument* pDestDoc = pTransClip->pDocument;
818 :
819 8 : for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
820 : {
821 : SCROW nRow;
822 6 : if ( bAsLink && nFlags == IDF_ALL )
823 : {
824 : // with IDF_ALL, also create links (formulas) for empty cells
825 :
826 0 : for ( nRow=nRow1; nRow<=nRow2; nRow++ )
827 : {
828 : // create simple formula, as in ScColumn::CreateRefCell
829 :
830 0 : ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
831 : ScSingleRefData aRef;
832 0 : aRef.InitAddress(ScAddress(nCol,nRow,nTab));
833 0 : aRef.SetFlag3D(true);
834 0 : ScTokenArray aArr;
835 0 : aArr.AddSingleReference( aRef );
836 :
837 : pTransClip->SetFormulaCell(
838 : static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1),
839 0 : new ScFormulaCell(pDestDoc, aDestPos, aArr));
840 0 : }
841 : }
842 : else
843 : {
844 6 : TransClipHandler aFunc(*pTransClip, nTab, nCol, nRow1, static_cast<SCROW>(nCol-nCol1), bAsLink, bWasCut);
845 6 : const sc::CellStoreType& rCells = aCol[nCol].maCells;
846 6 : sc::ParseAllNonEmpty(rCells.begin(), rCells, nRow1, nRow2, aFunc);
847 : }
848 :
849 : // Attribute
850 :
851 : SCROW nAttrRow1;
852 : SCROW nAttrRow2;
853 : const ScPatternAttr* pPattern;
854 6 : boost::scoped_ptr<ScAttrIterator> pAttrIter(aCol[nCol].CreateAttrIterator( nRow1, nRow2 ));
855 18 : while ( (pPattern = pAttrIter->Next( nAttrRow1, nAttrRow2 )) != 0 )
856 : {
857 6 : if ( !IsDefaultItem( pPattern ) )
858 : {
859 0 : const SfxItemSet& rSet = pPattern->GetItemSet();
860 0 : if ( rSet.GetItemState( ATTR_MERGE, false ) == SfxItemState::DEFAULT &&
861 0 : rSet.GetItemState( ATTR_MERGE_FLAG, false ) == SfxItemState::DEFAULT &&
862 0 : rSet.GetItemState( ATTR_BORDER, false ) == SfxItemState::DEFAULT )
863 : {
864 : // no borders or merge items involved - use pattern as-is
865 0 : for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
866 0 : pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern, true );
867 : }
868 : else
869 : {
870 : // transpose borders and merge values, remove merge flags (refreshed after pasting)
871 0 : ScPatternAttr aNewPattern( *pPattern );
872 0 : SfxItemSet& rNewSet = aNewPattern.GetItemSet();
873 :
874 0 : const SvxBoxItem& rOldBox = static_cast<const SvxBoxItem&>(rSet.Get(ATTR_BORDER));
875 0 : if ( rOldBox.GetTop() || rOldBox.GetBottom() || rOldBox.GetLeft() || rOldBox.GetRight() )
876 : {
877 0 : SvxBoxItem aNew( ATTR_BORDER );
878 0 : aNew.SetLine( rOldBox.GetLine( BOX_LINE_TOP ), BOX_LINE_LEFT );
879 0 : aNew.SetLine( rOldBox.GetLine( BOX_LINE_LEFT ), BOX_LINE_TOP );
880 0 : aNew.SetLine( rOldBox.GetLine( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
881 0 : aNew.SetLine( rOldBox.GetLine( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
882 0 : aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_TOP ), BOX_LINE_LEFT );
883 0 : aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_LEFT ), BOX_LINE_TOP );
884 0 : aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
885 0 : aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
886 0 : rNewSet.Put( aNew );
887 : }
888 :
889 0 : const ScMergeAttr& rOldMerge = static_cast<const ScMergeAttr&>(rSet.Get(ATTR_MERGE));
890 0 : if (rOldMerge.IsMerged())
891 : rNewSet.Put( ScMergeAttr( std::min(
892 0 : static_cast<SCsCOL>(rOldMerge.GetRowMerge()),
893 0 : static_cast<SCsCOL>(MAXCOL+1 - (nAttrRow2-nRow1))),
894 : std::min(
895 0 : static_cast<SCsROW>(rOldMerge.GetColMerge()),
896 0 : static_cast<SCsROW>(MAXROW+1 - (nCol-nCol1)))));
897 0 : const ScMergeFlagAttr& rOldFlag = static_cast<const ScMergeFlagAttr&>(rSet.Get(ATTR_MERGE_FLAG));
898 0 : if (rOldFlag.IsOverlapped())
899 : {
900 0 : sal_Int16 nNewFlags = rOldFlag.GetValue() & ~( SC_MF_HOR | SC_MF_VER );
901 0 : if ( nNewFlags )
902 0 : rNewSet.Put( ScMergeFlagAttr( nNewFlags ) );
903 : else
904 0 : rNewSet.ClearItem( ATTR_MERGE_FLAG );
905 : }
906 :
907 0 : for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
908 : pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
909 0 : static_cast<SCROW>(nCol-nCol1), aNewPattern, true);
910 : }
911 : }
912 : }
913 :
914 : // Cell Notes - fdo#68381 paste cell notes on Transpose
915 6 : if ( pDocument->HasColNotes(nCol, nTab) )
916 6 : TransposeColNotes(pTransClip, nCol1, nCol, nRow1, nRow2);
917 6 : }
918 2 : }
919 :
920 6 : void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2)
921 : {
922 6 : bool bCloneCaption = true;
923 :
924 6 : sc::CellNoteStoreType::const_iterator itBlk = aCol[nCol].maCellNotes.begin(), itBlkEnd = aCol[nCol].maCellNotes.end();
925 :
926 : // Locate the top row position.
927 6 : size_t nOffsetInBlock = 0;
928 6 : size_t nBlockStart = 0, nBlockEnd = 0, nRowPos = static_cast<size_t>(nRow1);
929 6 : for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd)
930 : {
931 6 : nBlockEnd = nBlockStart + itBlk->size;
932 6 : if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
933 : {
934 : // Found.
935 6 : nOffsetInBlock = nRowPos - nBlockStart;
936 6 : break;
937 : }
938 : }
939 :
940 6 : if (itBlk != itBlkEnd)
941 : // Specified range found
942 : {
943 6 : nRowPos = static_cast<size_t>(nRow2); // End row position.
944 :
945 : // Keep processing until we hit the end row position.
946 6 : sc::cellnote_block::const_iterator itData, itDataEnd;
947 6 : for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd, nOffsetInBlock = 0)
948 : {
949 6 : nBlockEnd = nBlockStart + itBlk->size;
950 :
951 6 : if (itBlk->data)
952 : {
953 6 : itData = sc::cellnote_block::begin(*itBlk->data);
954 6 : std::advance(itData, nOffsetInBlock);
955 :
956 6 : if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
957 : {
958 : // This block contains the end row. Only process partially.
959 6 : size_t nOffsetEnd = nRowPos - nBlockStart + 1;
960 6 : itDataEnd = sc::cellnote_block::begin(*itBlk->data);
961 6 : std::advance(itDataEnd, nOffsetEnd);
962 6 : size_t curRow = nBlockStart + nOffsetInBlock;
963 12 : for (; itData != itDataEnd; ++itData, ++curRow)
964 : {
965 6 : ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
966 6 : pTransClip->pDocument->ReleaseNote(aDestPos);
967 6 : ScPostIt* pNote = *itData;
968 6 : if (pNote)
969 : {
970 6 : ScPostIt* pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), *pTransClip->pDocument, aDestPos, bCloneCaption );
971 6 : pTransClip->pDocument->SetNote(aDestPos, pClonedNote);
972 : }
973 : }
974 6 : break; // we reached the last valid block
975 : }
976 : else
977 : {
978 0 : itDataEnd = sc::cellnote_block::end(*itBlk->data);
979 0 : size_t curRow = nBlockStart + nOffsetInBlock;
980 0 : for (; itData != itDataEnd; ++itData, ++curRow)
981 : {
982 0 : ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
983 0 : pTransClip->pDocument->ReleaseNote(aDestPos);
984 0 : ScPostIt* pNote = *itData;
985 0 : if (pNote)
986 : {
987 0 : ScPostIt* pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), *pTransClip->pDocument, aDestPos, bCloneCaption );
988 0 : pTransClip->pDocument->SetNote(aDestPos, pClonedNote);
989 : }
990 : }
991 : }
992 : }
993 : else
994 : {
995 : size_t curRow;
996 0 : for ( curRow = nBlockStart + nOffsetInBlock; curRow <= nBlockEnd && curRow <= nRowPos; ++curRow)
997 : {
998 0 : ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
999 0 : pTransClip->pDocument->ReleaseNote(aDestPos);
1000 : }
1001 0 : if (curRow == nRowPos)
1002 0 : break;
1003 : }
1004 : }
1005 : }
1006 6 : }
1007 :
1008 63350 : ScColumn* ScTable::FetchColumn( SCCOL nCol )
1009 : {
1010 63350 : if (!ValidCol(nCol))
1011 0 : return NULL;
1012 :
1013 63350 : return &aCol[nCol];
1014 : }
1015 :
1016 0 : const ScColumn* ScTable::FetchColumn( SCCOL nCol ) const
1017 : {
1018 0 : if (!ValidCol(nCol))
1019 0 : return NULL;
1020 :
1021 0 : return &aCol[nCol];
1022 : }
1023 :
1024 760 : void ScTable::StartAllListeners()
1025 : {
1026 779000 : for (SCCOL i=0; i<=MAXCOL; i++)
1027 778240 : aCol[i].StartAllListeners();
1028 760 : }
1029 :
1030 8 : void ScTable::AttachFormulaCells(
1031 : sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1032 : {
1033 28 : for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
1034 20 : aCol[nCol].AttachFormulaCells(rCxt, nRow1, nRow2);
1035 8 : }
1036 :
1037 8 : void ScTable::DetachFormulaCells(
1038 : sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1039 : {
1040 28 : for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
1041 20 : aCol[nCol].DetachFormulaCells(rCxt, nRow1, nRow2);
1042 8 : }
1043 :
1044 344 : void ScTable::StartNeededListeners()
1045 : {
1046 352600 : for (SCCOL i=0; i<=MAXCOL; i++)
1047 352256 : aCol[i].StartNeededListeners();
1048 344 : }
1049 :
1050 102 : void ScTable::BroadcastInArea( SCCOL nCol1, SCROW nRow1,
1051 : SCCOL nCol2, SCROW nRow2 )
1052 : {
1053 102 : if (nCol2 > MAXCOL) nCol2 = MAXCOL;
1054 102 : if (nRow2 > MAXROW) nRow2 = MAXROW;
1055 102 : if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
1056 360 : for (SCCOL i = nCol1; i <= nCol2; i++)
1057 258 : aCol[i].SetDirty(nRow1, nRow2);
1058 102 : }
1059 :
1060 102 : void ScTable::StartListeningInArea(
1061 : sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1062 : {
1063 102 : if (nCol2 > MAXCOL) nCol2 = MAXCOL;
1064 102 : if (nRow2 > MAXROW) nRow2 = MAXROW;
1065 102 : if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
1066 360 : for (SCCOL i = nCol1; i <= nCol2; i++)
1067 258 : aCol[i].StartListeningInArea(rCxt, nRow1, nRow2);
1068 102 : }
1069 :
1070 2168 : void ScTable::CopyToTable(
1071 : sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1072 : InsertDeleteFlags nFlags, bool bMarked, ScTable* pDestTab, const ScMarkData* pMarkData,
1073 : bool bAsLink, bool bColRowFlags )
1074 : {
1075 2168 : if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
1076 0 : return;
1077 :
1078 2168 : if (nFlags)
1079 353496 : for (SCCOL i = nCol1; i <= nCol2; i++)
1080 351542 : aCol[i].CopyToColumn(rCxt, nRow1, nRow2, nFlags, bMarked,
1081 703084 : pDestTab->aCol[i], pMarkData, bAsLink);
1082 :
1083 2168 : if (!bColRowFlags) // Spaltenbreiten/Zeilenhoehen/Flags
1084 140 : return;
1085 :
1086 2028 : if(pDestTab->pDocument->IsUndo() && (nFlags & IDF_ATTRIB))
1087 : {
1088 1534 : pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->pDocument, *mpCondFormatList));
1089 : }
1090 :
1091 2028 : if (pDBDataNoName)
1092 : {
1093 558 : ScDBData* pNewDBData = new ScDBData(*pDBDataNoName);
1094 : SCCOL aCol1, aCol2;
1095 : SCROW aRow1, aRow2;
1096 : SCTAB aTab;
1097 558 : pNewDBData->GetArea(aTab, aCol1, aRow1, aCol2, aRow2);
1098 558 : pNewDBData->MoveTo(pDestTab->nTab, aCol1, aRow1, aCol2, aRow2);
1099 558 : pDestTab->SetAnonymousDBData(pNewDBData);
1100 : }
1101 : // Charts muessen beim Ein-/Ausblenden angepasst werden
1102 2028 : ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection();
1103 :
1104 2028 : bool bFlagChange = false;
1105 :
1106 2028 : bool bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
1107 2028 : bool bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
1108 :
1109 2028 : if (bWidth || bHeight)
1110 : {
1111 356 : if (bWidth)
1112 : {
1113 109572 : for (SCCOL i = nCol1; i <= nCol2; ++i)
1114 : {
1115 109356 : bool bThisHidden = ColHidden(i);
1116 109356 : bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden);
1117 109356 : bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]);
1118 109356 : pDestTab->pColWidth[i] = pColWidth[i];
1119 109356 : pDestTab->pColFlags[i] = pColFlags[i];
1120 109356 : pDestTab->SetColHidden(i, i, bThisHidden);
1121 : //! Aenderungen zusammenfassen?
1122 109356 : if (bHiddenChange && pCharts)
1123 0 : pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
1124 :
1125 109356 : if (bChange)
1126 19076 : bFlagChange = true;
1127 : }
1128 216 : pDestTab->SetColManualBreaks( maColManualBreaks);
1129 : }
1130 :
1131 356 : if (bHeight)
1132 : {
1133 246 : bool bChange = pDestTab->GetRowHeight(nRow1, nRow2) != GetRowHeight(nRow1, nRow2);
1134 :
1135 246 : if (bChange)
1136 160 : bFlagChange = true;
1137 :
1138 246 : pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
1139 246 : pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
1140 :
1141 : // Hidden flags.
1142 610 : for (SCROW i = nRow1; i <= nRow2; ++i)
1143 : {
1144 : SCROW nLastRow;
1145 364 : bool bHidden = RowHidden(i, NULL, &nLastRow);
1146 364 : if (nLastRow >= nRow2)
1147 : // the last row shouldn't exceed the upper bound the caller specified.
1148 246 : nLastRow = nRow2;
1149 :
1150 364 : bool bHiddenChanged = pDestTab->SetRowHidden(i, nLastRow, bHidden);
1151 364 : if (bHiddenChanged && pCharts)
1152 : // Hidden flags differ.
1153 2 : pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab));
1154 :
1155 364 : if (bHiddenChanged)
1156 56 : bFlagChange = true;
1157 :
1158 : // Jump to the last row of the identical flag segment.
1159 364 : i = nLastRow;
1160 : }
1161 :
1162 : // Filtered flags.
1163 596 : for (SCROW i = nRow1; i <= nRow2; ++i)
1164 : {
1165 : SCROW nLastRow;
1166 350 : bool bFiltered = RowFiltered(i, NULL, &nLastRow);
1167 350 : if (nLastRow >= nRow2)
1168 : // the last row shouldn't exceed the upper bound the caller specified.
1169 246 : nLastRow = nRow2;
1170 350 : pDestTab->SetRowFiltered(i, nLastRow, bFiltered);
1171 350 : i = nLastRow;
1172 : }
1173 246 : pDestTab->SetRowManualBreaks( maRowManualBreaks);
1174 : }
1175 : }
1176 :
1177 2028 : if (bFlagChange)
1178 244 : pDestTab->InvalidatePageBreaks();
1179 :
1180 2028 : if(nFlags & IDF_ATTRIB)
1181 : {
1182 1718 : pDestTab->mpCondFormatList->DeleteArea(nCol1, nRow1, nCol2, nRow2);
1183 1718 : pDestTab->CopyConditionalFormat(nCol1, nRow1, nCol2, nRow2, 0, 0, this);
1184 : }
1185 :
1186 2028 : if(nFlags & IDF_OUTLINE) // also only when bColRowFlags
1187 678 : pDestTab->SetOutlineTable( pOutlineTable );
1188 : }
1189 :
1190 16 : void ScTable::UndoToTable(
1191 : sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1192 : InsertDeleteFlags nFlags, bool bMarked, ScTable* pDestTab, const ScMarkData* pMarkData )
1193 : {
1194 16 : if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
1195 : {
1196 16 : bool bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
1197 16 : bool bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
1198 :
1199 16400 : for ( SCCOL i = 0; i <= MAXCOL; i++)
1200 : {
1201 16384 : if ( i >= nCol1 && i <= nCol2 )
1202 32 : aCol[i].UndoToColumn(rCxt, nRow1, nRow2, nFlags, bMarked, pDestTab->aCol[i], pMarkData);
1203 : else
1204 16352 : aCol[i].CopyToColumn(rCxt, 0, MAXROW, IDF_FORMULA, false, pDestTab->aCol[i]);
1205 : }
1206 :
1207 16 : if (nFlags & IDF_ATTRIB)
1208 14 : pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->pDocument, *mpCondFormatList));
1209 :
1210 16 : if (bWidth||bHeight)
1211 : {
1212 0 : if (bWidth)
1213 : {
1214 0 : for (SCCOL i=nCol1; i<=nCol2; i++)
1215 0 : pDestTab->pColWidth[i] = pColWidth[i];
1216 0 : pDestTab->SetColManualBreaks( maColManualBreaks);
1217 : }
1218 0 : if (bHeight)
1219 : {
1220 0 : pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
1221 0 : pDestTab->SetRowManualBreaks( maRowManualBreaks);
1222 : }
1223 : }
1224 : }
1225 16 : }
1226 :
1227 0 : void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
1228 : {
1229 0 : for (SCCOL i=0; i<=MAXCOL; i++)
1230 0 : aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
1231 0 : }
1232 :
1233 65626 : void ScTable::InvalidateTableArea()
1234 : {
1235 65626 : bTableAreaValid = false;
1236 65626 : }
1237 :
1238 23332 : void ScTable::InvalidatePageBreaks()
1239 : {
1240 23332 : mbPageBreaksValid = false;
1241 23332 : }
1242 :
1243 0 : void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
1244 : {
1245 : OSL_ENSURE( bScenario, "bScenario == FALSE" );
1246 :
1247 0 : for (SCCOL i=0; i<=MAXCOL; i++)
1248 0 : aCol[i].CopyScenarioTo( pDestTab->aCol[i] );
1249 0 : }
1250 :
1251 0 : void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
1252 : {
1253 : OSL_ENSURE( bScenario, "bScenario == FALSE" );
1254 :
1255 0 : for (SCCOL i=0; i<=MAXCOL; i++)
1256 0 : aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
1257 0 : }
1258 :
1259 2 : void ScTable::MarkScenarioIn( ScMarkData& rDestMark, sal_uInt16 nNeededBits ) const
1260 : {
1261 : OSL_ENSURE( bScenario, "bScenario == FALSE" );
1262 :
1263 2 : if ( ( nScenarioFlags & nNeededBits ) != nNeededBits ) // alle Bits gesetzt?
1264 2 : return;
1265 :
1266 2050 : for (SCCOL i=0; i<=MAXCOL; i++)
1267 2048 : aCol[i].MarkScenarioIn( rDestMark );
1268 : }
1269 :
1270 0 : bool ScTable::HasScenarioRange( const ScRange& rRange ) const
1271 : {
1272 : OSL_ENSURE( bScenario, "bScenario == FALSE" );
1273 :
1274 0 : ScRange aTabRange = rRange;
1275 0 : aTabRange.aStart.SetTab( nTab );
1276 0 : aTabRange.aEnd.SetTab( nTab );
1277 :
1278 0 : const ScRangeList* pList = GetScenarioRanges();
1279 :
1280 0 : if (pList)
1281 : {
1282 0 : for ( size_t j = 0, n = pList->size(); j < n; j++ )
1283 : {
1284 0 : const ScRange* pR = (*pList)[j];
1285 0 : if ( pR->Intersects( aTabRange ) )
1286 0 : return true;
1287 : }
1288 : }
1289 :
1290 0 : return false;
1291 : }
1292 :
1293 2 : void ScTable::InvalidateScenarioRanges()
1294 : {
1295 2 : delete pScenarioRanges;
1296 2 : pScenarioRanges = NULL;
1297 2 : }
1298 :
1299 2 : const ScRangeList* ScTable::GetScenarioRanges() const
1300 : {
1301 : OSL_ENSURE( bScenario, "bScenario == FALSE" );
1302 :
1303 2 : if (!pScenarioRanges)
1304 : {
1305 2 : ((ScTable*)this)->pScenarioRanges = new ScRangeList;
1306 2 : ScMarkData aMark;
1307 2 : MarkScenarioIn( aMark, 0 ); // immer
1308 2 : aMark.FillRangeListWithMarks( pScenarioRanges, false );
1309 : }
1310 2 : return pScenarioRanges;
1311 : }
1312 :
1313 0 : bool ScTable::TestCopyScenarioTo( const ScTable* pDestTab ) const
1314 : {
1315 : OSL_ENSURE( bScenario, "bScenario == FALSE" );
1316 :
1317 0 : if (!pDestTab->IsProtected())
1318 0 : return true;
1319 :
1320 0 : bool bOk = true;
1321 0 : for (SCCOL i=0; i<=MAXCOL && bOk; i++)
1322 0 : bOk = aCol[i].TestCopyScenarioTo( pDestTab->aCol[i] );
1323 0 : return bOk;
1324 : }
1325 :
1326 13624 : bool ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const OUString& rString,
1327 : ScSetStringParam* pParam )
1328 : {
1329 13624 : if (ValidColRow(nCol,nRow))
1330 13624 : return aCol[nCol].SetString(
1331 27248 : nRow, nTabP, rString, pDocument->GetAddressConvention(), pParam );
1332 : else
1333 0 : return false;
1334 : }
1335 :
1336 384 : void ScTable::SetEditText( SCCOL nCol, SCROW nRow, EditTextObject* pEditText )
1337 : {
1338 384 : if (!ValidColRow(nCol, nRow))
1339 : {
1340 0 : delete pEditText;
1341 384 : return;
1342 : }
1343 :
1344 384 : aCol[nCol].SetEditText(nRow, pEditText);
1345 : }
1346 :
1347 0 : void ScTable::SetEditText( SCCOL nCol, SCROW nRow, const EditTextObject& rEditText, const SfxItemPool* pEditPool )
1348 : {
1349 0 : if (!ValidColRow(nCol, nRow))
1350 0 : return;
1351 :
1352 0 : aCol[nCol].SetEditText(nRow, rEditText, pEditPool);
1353 : }
1354 :
1355 22 : SCROW ScTable::GetFirstEditTextRow( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
1356 : {
1357 22 : if (!ValidCol(nCol1) || !ValidCol(nCol2) || nCol2 < nCol1)
1358 0 : return -1;
1359 :
1360 22 : if (!ValidRow(nRow1) || !ValidRow(nRow2) || nRow2 < nRow1)
1361 0 : return -1;
1362 :
1363 22 : SCROW nFirst = MAXROW+1;
1364 36 : for (SCCOL i = nCol1; i <= nCol2; ++i)
1365 : {
1366 22 : const ScColumn& rCol = aCol[i];
1367 22 : SCROW nThisFirst = -1;
1368 22 : if (const_cast<ScColumn&>(rCol).HasEditCells(nRow1, nRow2, nThisFirst))
1369 : {
1370 8 : if (nThisFirst == nRow1)
1371 8 : return nRow1;
1372 :
1373 0 : if (nThisFirst < nFirst)
1374 0 : nFirst = nThisFirst;
1375 : }
1376 : }
1377 :
1378 14 : return nFirst == (MAXROW+1) ? -1 : nFirst;
1379 : }
1380 :
1381 980 : void ScTable::SetEmptyCell( SCCOL nCol, SCROW nRow )
1382 : {
1383 980 : if (!ValidColRow(nCol, nRow))
1384 980 : return;
1385 :
1386 980 : aCol[nCol].Delete(nRow);
1387 : }
1388 :
1389 0 : void ScTable::SetFormula(
1390 : SCCOL nCol, SCROW nRow, const ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram )
1391 : {
1392 0 : if (!ValidColRow(nCol, nRow))
1393 0 : return;
1394 :
1395 0 : aCol[nCol].SetFormula(nRow, rArray, eGram);
1396 : }
1397 :
1398 0 : void ScTable::SetFormula(
1399 : SCCOL nCol, SCROW nRow, const OUString& rFormula, formula::FormulaGrammar::Grammar eGram )
1400 : {
1401 0 : if (!ValidColRow(nCol, nRow))
1402 0 : return;
1403 :
1404 0 : aCol[nCol].SetFormula(nRow, rFormula, eGram);
1405 : }
1406 :
1407 770 : ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell )
1408 : {
1409 770 : if (!ValidColRow(nCol, nRow))
1410 : {
1411 0 : delete pCell;
1412 0 : return NULL;
1413 : }
1414 :
1415 770 : return aCol[nCol].SetFormulaCell(nRow, pCell);
1416 : }
1417 :
1418 6 : bool ScTable::SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells )
1419 : {
1420 6 : if (!ValidCol(nCol))
1421 0 : return false;
1422 :
1423 6 : return aCol[nCol].SetFormulaCells(nRow, rCells);
1424 : }
1425 :
1426 68 : svl::SharedString ScTable::GetSharedString( SCCOL nCol, SCROW nRow ) const
1427 : {
1428 68 : if (!ValidColRow(nCol, nRow))
1429 0 : return svl::SharedString();
1430 :
1431 68 : return aCol[nCol].GetSharedString(nRow);
1432 : }
1433 :
1434 52688 : void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
1435 : {
1436 52688 : if (ValidColRow(nCol, nRow))
1437 52688 : aCol[nCol].SetValue( nRow, rVal );
1438 52688 : }
1439 :
1440 2 : void ScTable::SetRawString( SCCOL nCol, SCROW nRow, const svl::SharedString& rStr )
1441 : {
1442 2 : if (ValidColRow(nCol, nRow))
1443 2 : aCol[nCol].SetRawString(nRow, rStr);
1444 2 : }
1445 :
1446 31413 : void ScTable::GetString( SCCOL nCol, SCROW nRow, OUString& rString ) const
1447 : {
1448 31413 : if (ValidColRow(nCol,nRow))
1449 31413 : aCol[nCol].GetString( nRow, rString );
1450 : else
1451 0 : rString = OUString();
1452 31413 : }
1453 :
1454 10 : double* ScTable::GetValueCell( SCCOL nCol, SCROW nRow )
1455 : {
1456 10 : if (!ValidColRow(nCol,nRow))
1457 0 : return NULL;
1458 :
1459 10 : return aCol[nCol].GetValueCell(nRow);
1460 : }
1461 :
1462 4433 : void ScTable::GetInputString( SCCOL nCol, SCROW nRow, OUString& rString ) const
1463 : {
1464 4433 : if (ValidColRow(nCol,nRow))
1465 4433 : aCol[nCol].GetInputString( nRow, rString );
1466 : else
1467 0 : rString = OUString();
1468 4433 : }
1469 :
1470 23937 : double ScTable::GetValue( SCCOL nCol, SCROW nRow ) const
1471 : {
1472 23937 : if (ValidColRow( nCol, nRow ))
1473 23937 : return aCol[nCol].GetValue( nRow );
1474 0 : return 0.0;
1475 : }
1476 :
1477 150 : const EditTextObject* ScTable::GetEditText( SCCOL nCol, SCROW nRow ) const
1478 : {
1479 150 : if (!ValidColRow(nCol, nRow))
1480 0 : return NULL;
1481 :
1482 150 : return aCol[nCol].GetEditText(nRow);
1483 : }
1484 :
1485 0 : void ScTable::RemoveEditTextCharAttribs( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
1486 : {
1487 0 : if (!ValidColRow(nCol, nRow))
1488 0 : return;
1489 :
1490 0 : return aCol[nCol].RemoveEditTextCharAttribs(nRow, rAttr);
1491 : }
1492 :
1493 104 : void ScTable::GetFormula( SCCOL nCol, SCROW nRow, OUString& rFormula ) const
1494 : {
1495 104 : if (ValidColRow(nCol,nRow))
1496 104 : aCol[nCol].GetFormula( nRow, rFormula );
1497 : else
1498 0 : rFormula = OUString();
1499 104 : }
1500 :
1501 0 : const ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow ) const
1502 : {
1503 0 : if (!ValidColRow(nCol, nRow))
1504 0 : return NULL;
1505 :
1506 0 : return aCol[nCol].GetFormulaCell(nRow);
1507 : }
1508 :
1509 7878 : ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow )
1510 : {
1511 7878 : if (!ValidColRow(nCol, nRow))
1512 172 : return NULL;
1513 :
1514 7706 : return aCol[nCol].GetFormulaCell(nRow);
1515 : }
1516 :
1517 38 : ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
1518 : {
1519 38 : if (!ValidCol(nCol))
1520 0 : return NULL;
1521 :
1522 38 : return aCol[nCol].ReleaseNote(nRow);
1523 : }
1524 :
1525 2112 : size_t ScTable::GetNoteCount( SCCOL nCol ) const
1526 : {
1527 2112 : if (!ValidCol(nCol))
1528 0 : return 0;
1529 :
1530 2112 : return aCol[nCol].GetNoteCount();
1531 : }
1532 :
1533 12 : SCROW ScTable::GetNotePosition( SCCOL nCol, size_t nIndex ) const
1534 : {
1535 12 : if (!ValidCol(nCol))
1536 0 : return -1;
1537 :
1538 12 : return aCol[nCol].GetNotePosition(nIndex);
1539 : }
1540 :
1541 58 : void ScTable::CreateAllNoteCaptions()
1542 : {
1543 59450 : for (SCCOL i = 0; i <= MAXCOL; ++i)
1544 59392 : aCol[i].CreateAllNoteCaptions();
1545 58 : }
1546 :
1547 16 : void ScTable::ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1548 : {
1549 16 : if (!ValidCol(nCol1) || !ValidCol(nCol2))
1550 16 : return;
1551 :
1552 48 : for (SCCOL i = nCol1; i <= nCol2; ++i)
1553 32 : aCol[i].ForgetNoteCaptions(nRow1, nRow2);
1554 : }
1555 :
1556 296 : void ScTable::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
1557 : {
1558 303400 : for (SCCOL nCol = 0; nCol < MAXCOLCOUNT; ++nCol)
1559 303104 : aCol[nCol].GetAllNoteEntries(rNotes);
1560 296 : }
1561 :
1562 24 : void ScTable::GetNotesInRange( const ScRange& rRange, std::vector<sc::NoteEntry>& rNotes ) const
1563 : {
1564 24 : SCROW nStartRow = rRange.aStart.Row();
1565 24 : SCROW nEndRow = rRange.aEnd.Row();
1566 24600 : for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
1567 : {
1568 24576 : aCol[nCol].GetNotesInRange(nStartRow, nEndRow, rNotes);
1569 : }
1570 24 : }
1571 :
1572 0 : bool ScTable::ContainsNotesInRange( const ScRange& rRange ) const
1573 : {
1574 0 : SCROW nStartRow = rRange.aStart.Row();
1575 0 : SCROW nEndRow = rRange.aEnd.Row();
1576 0 : for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
1577 : {
1578 0 : bool bContainsNote = !aCol[nCol].IsNotesEmptyBlock(nStartRow, nEndRow);
1579 0 : if(bContainsNote)
1580 0 : return true;
1581 : }
1582 :
1583 0 : return false;
1584 : }
1585 :
1586 72 : CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
1587 : {
1588 72 : if (ValidColRow( nCol, nRow ))
1589 72 : return aCol[nCol].GetCellType( nRow );
1590 0 : return CELLTYPE_NONE;
1591 : }
1592 :
1593 630 : ScRefCellValue ScTable::GetCellValue( SCCOL nCol, SCROW nRow ) const
1594 : {
1595 630 : if (!ValidColRow(nCol, nRow))
1596 0 : return ScRefCellValue();
1597 :
1598 630 : return aCol[nCol].GetCellValue(nRow);
1599 : }
1600 :
1601 114 : void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
1602 : {
1603 114 : rCol = 0;
1604 114 : rRow = MAXROW+1;
1605 2312 : while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
1606 2084 : ++rCol;
1607 114 : SCCOL nCol = rCol;
1608 37170 : while (nCol <= MAXCOL && rRow > 0)
1609 : {
1610 36942 : if (!aCol[nCol].IsEmptyData())
1611 194 : rRow = ::std::min( rRow, aCol[nCol].GetFirstDataPos());
1612 36942 : ++nCol;
1613 : }
1614 114 : }
1615 :
1616 1388 : void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
1617 : {
1618 1388 : rCol = MAXCOL;
1619 1388 : rRow = 0;
1620 1378902 : while (aCol[rCol].IsEmptyData() && (rCol > 0))
1621 1376126 : rCol--;
1622 1388 : SCCOL nCol = rCol;
1623 47962 : while (nCol >= 0 && rRow < MAXROW)
1624 45186 : rRow = ::std::max( rRow, aCol[nCol--].GetLastDataPos());
1625 1388 : }
1626 :
1627 5902 : bool ScTable::HasData( SCCOL nCol, SCROW nRow ) const
1628 : {
1629 5902 : if (ValidColRow(nCol,nRow))
1630 5902 : return aCol[nCol].HasDataAt( nRow );
1631 : else
1632 0 : return false;
1633 : }
1634 :
1635 12 : bool ScTable::HasStringData( SCCOL nCol, SCROW nRow ) const
1636 : {
1637 12 : if (ValidColRow(nCol,nRow))
1638 12 : return aCol[nCol].HasStringData( nRow );
1639 : else
1640 0 : return false;
1641 : }
1642 :
1643 5678 : bool ScTable::HasValueData( SCCOL nCol, SCROW nRow ) const
1644 : {
1645 5678 : if (ValidColRow(nCol,nRow))
1646 5678 : return aCol[nCol].HasValueData( nRow );
1647 : else
1648 0 : return false;
1649 : }
1650 :
1651 0 : bool ScTable::HasStringCells( SCCOL nStartCol, SCROW nStartRow,
1652 : SCCOL nEndCol, SCROW nEndRow ) const
1653 : {
1654 0 : if ( ValidCol(nEndCol) )
1655 0 : for ( SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++ )
1656 0 : if (aCol[nCol].HasStringCells(nStartRow, nEndRow))
1657 0 : return true;
1658 :
1659 0 : return false;
1660 : }
1661 :
1662 888 : void ScTable::SetDirtyVar()
1663 : {
1664 910200 : for (SCCOL i=0; i<=MAXCOL; i++)
1665 909312 : aCol[i].SetDirtyVar();
1666 888 : }
1667 :
1668 1818 : void ScTable::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
1669 : {
1670 1818 : sc::AutoCalcSwitch aACSwitch(*pDocument, false);
1671 :
1672 1863450 : for (SCCOL i=0; i<=MAXCOL; i++)
1673 1863450 : aCol[i].SetAllFormulasDirty(rCxt);
1674 1818 : }
1675 :
1676 378 : void ScTable::SetDirty( const ScRange& rRange )
1677 : {
1678 378 : bool bOldAutoCalc = pDocument->GetAutoCalc();
1679 378 : pDocument->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1680 378 : SCCOL nCol2 = rRange.aEnd.Col();
1681 29592 : for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1682 29214 : aCol[i].SetDirty(rRange.aStart.Row(), rRange.aEnd.Row());
1683 378 : pDocument->SetAutoCalc( bOldAutoCalc );
1684 378 : }
1685 :
1686 88 : void ScTable::SetTableOpDirty( const ScRange& rRange )
1687 : {
1688 88 : bool bOldAutoCalc = pDocument->GetAutoCalc();
1689 88 : pDocument->SetAutoCalc( false ); // no multiple recalculation
1690 88 : SCCOL nCol2 = rRange.aEnd.Col();
1691 176 : for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1692 88 : aCol[i].SetTableOpDirty( rRange );
1693 88 : pDocument->SetAutoCalc( bOldAutoCalc );
1694 88 : }
1695 :
1696 434 : void ScTable::SetDirtyAfterLoad()
1697 : {
1698 434 : bool bOldAutoCalc = pDocument->GetAutoCalc();
1699 434 : pDocument->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1700 444850 : for (SCCOL i=0; i<=MAXCOL; i++)
1701 444416 : aCol[i].SetDirtyAfterLoad();
1702 434 : pDocument->SetAutoCalc( bOldAutoCalc );
1703 434 : }
1704 :
1705 344 : void ScTable::SetDirtyIfPostponed()
1706 : {
1707 344 : bool bOldAutoCalc = pDocument->GetAutoCalc();
1708 344 : pDocument->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1709 352600 : for (SCCOL i=0; i<=MAXCOL; i++)
1710 352256 : aCol[i].SetDirtyIfPostponed();
1711 344 : pDocument->SetAutoCalc( bOldAutoCalc );
1712 344 : }
1713 :
1714 344 : void ScTable::BroadcastRecalcOnRefMove()
1715 : {
1716 344 : sc::AutoCalcSwitch aSwitch(*pDocument, false);
1717 352600 : for (SCCOL i = 0; i <= MAXCOL; ++i)
1718 352600 : aCol[i].BroadcastRecalcOnRefMove();
1719 344 : }
1720 :
1721 12 : void ScTable::TransferListeners(
1722 : ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1723 : SCCOL nColDelta, SCROW nRowDelta )
1724 : {
1725 26 : for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
1726 : {
1727 14 : ScColumn& rSrcCol = aCol[nCol];
1728 14 : ScColumn& rDestCol = rDestTab.aCol[nCol+nColDelta];
1729 14 : rSrcCol.TransferListeners(rDestCol, nRow1, nRow2, nRowDelta);
1730 : }
1731 12 : }
1732 :
1733 4078 : void ScTable::SetLoadingMedium(bool bLoading)
1734 : {
1735 4078 : mpRowHeights->enableTreeSearch(!bLoading);
1736 4078 : }
1737 :
1738 888 : void ScTable::CalcAll()
1739 : {
1740 888 : for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll();
1741 888 : }
1742 :
1743 62 : void ScTable::CompileAll( sc::CompileFormulaContext& rCxt )
1744 : {
1745 63550 : for (SCCOL i = 0; i <= MAXCOL; ++i)
1746 63488 : aCol[i].CompileAll(rCxt);
1747 :
1748 62 : if(mpCondFormatList)
1749 62 : mpCondFormatList->CompileAll();
1750 62 : }
1751 :
1752 578 : void ScTable::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress )
1753 : {
1754 578 : if (mpRangeName)
1755 64 : mpRangeName->CompileUnresolvedXML(rCxt);
1756 :
1757 592450 : for (SCCOL i=0; i <= MAXCOL; i++)
1758 : {
1759 591872 : aCol[i].CompileXML(rCxt, rProgress);
1760 : }
1761 :
1762 578 : if(mpCondFormatList)
1763 578 : mpCondFormatList->CompileXML();
1764 578 : }
1765 :
1766 0 : bool ScTable::CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode )
1767 : {
1768 0 : bool bCompiled = false;
1769 0 : for (SCCOL i = 0; i <= MAXCOL; ++i)
1770 : {
1771 0 : if (aCol[i].CompileErrorCells(rCxt, nErrCode))
1772 0 : bCompiled = true;
1773 : }
1774 :
1775 0 : return bCompiled;
1776 : }
1777 :
1778 434 : void ScTable::CalcAfterLoad( sc::CompileFormulaContext& rCxt )
1779 : {
1780 444850 : for (SCCOL i = 0; i <= MAXCOL; ++i)
1781 444416 : aCol[i].CalcAfterLoad(rCxt);
1782 434 : }
1783 :
1784 2477 : void ScTable::ResetChanged( const ScRange& rRange )
1785 : {
1786 2477 : SCCOL nStartCol = rRange.aStart.Col();
1787 2477 : SCROW nStartRow = rRange.aStart.Row();
1788 2477 : SCCOL nEndCol = rRange.aEnd.Col();
1789 2477 : SCROW nEndRow = rRange.aEnd.Row();
1790 :
1791 27681 : for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
1792 25204 : aCol[nCol].ResetChanged(nStartRow, nEndRow);
1793 2477 : }
1794 :
1795 : // Attribute
1796 :
1797 22306 : const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, sal_uInt16 nWhich ) const
1798 : {
1799 22306 : if (ValidColRow(nCol,nRow))
1800 22306 : return aCol[nCol].GetAttr( nRow, nWhich );
1801 : else
1802 0 : return NULL;
1803 : }
1804 :
1805 43211 : sal_uInt32 ScTable::GetNumberFormat( const ScAddress& rPos ) const
1806 : {
1807 43211 : return ValidColRow(rPos.Col(),rPos.Row()) ?
1808 43211 : aCol[rPos.Col()].GetNumberFormat( rPos.Row() ) :
1809 86422 : 0;
1810 : }
1811 :
1812 1480 : sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
1813 : {
1814 1480 : if (ValidColRow(nCol,nRow))
1815 1480 : return aCol[nCol].GetNumberFormat( nRow );
1816 : else
1817 0 : return 0;
1818 : }
1819 :
1820 48 : sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1821 : {
1822 48 : if (!ValidCol(nCol) || !ValidRow(nStartRow) || !ValidRow(nEndRow))
1823 0 : return 0;
1824 :
1825 48 : return aCol[nCol].GetNumberFormat(nStartRow, nEndRow);
1826 : }
1827 :
1828 130 : void ScTable::SetNumberFormat( SCCOL nCol, SCROW nRow, sal_uInt32 nNumberFormat )
1829 : {
1830 130 : if (!ValidColRow(nCol, nRow))
1831 130 : return;
1832 :
1833 130 : aCol[nCol].SetNumberFormat(nRow, nNumberFormat);
1834 : }
1835 :
1836 31392 : const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
1837 : {
1838 31392 : if (ValidColRow(nCol,nRow))
1839 31392 : return aCol[nCol].GetPattern( nRow );
1840 : else
1841 : {
1842 : OSL_FAIL("wrong column or row");
1843 0 : return pDocument->GetDefPattern(); // for safety
1844 : }
1845 : }
1846 :
1847 88576 : const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
1848 : {
1849 88576 : if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) )
1850 88576 : return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
1851 : else
1852 0 : return NULL;
1853 : }
1854 :
1855 48849 : bool ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uInt16 nMask ) const
1856 : {
1857 48849 : bool bFound = false;
1858 28240801 : for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++)
1859 28191952 : bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask );
1860 48849 : return bFound;
1861 : }
1862 :
1863 0 : bool ScTable::HasAttribSelection( const ScMarkData& rMark, sal_uInt16 nMask ) const
1864 : {
1865 0 : std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans();
1866 :
1867 0 : for (size_t i = 0; i < aSpans.size(); ++i)
1868 : {
1869 0 : for (SCCOLROW j = aSpans[i].mnStart; j < aSpans[i].mnEnd; ++j)
1870 : {
1871 0 : if (aCol[j].HasAttribSelection(rMark, nMask))
1872 0 : return true;
1873 : }
1874 : }
1875 0 : return false;
1876 : }
1877 :
1878 16636 : bool ScTable::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
1879 : SCCOL& rEndCol, SCROW& rEndRow,
1880 : bool bRefresh )
1881 : {
1882 16636 : if (!(ValidCol(nStartCol) && ValidCol(rEndCol)))
1883 : {
1884 : OSL_FAIL("ScTable::ExtendMerge: invalid column number");
1885 0 : return false;
1886 : }
1887 16636 : bool bFound = false;
1888 16636 : SCCOL nOldEndX = rEndCol;
1889 16636 : SCROW nOldEndY = rEndRow;
1890 37172 : for (SCCOL i=nStartCol; i<=nOldEndX; i++)
1891 20536 : bFound |= aCol[i].ExtendMerge( i, nStartRow, nOldEndY, rEndCol, rEndRow, bRefresh );
1892 16636 : return bFound;
1893 : }
1894 :
1895 312 : bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const
1896 : {
1897 312 : if (!(ValidCol(nCol1) && ValidCol(nCol2)))
1898 : {
1899 : OSL_FAIL("ScTable::IsBlockEmpty: invalid column number");
1900 0 : return false;
1901 : }
1902 312 : bool bEmpty = true;
1903 1626 : for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
1904 : {
1905 1314 : bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2 );
1906 1314 : if (!bIgnoreNotes && bEmpty)
1907 : {
1908 830 : bEmpty = aCol[i].IsNotesEmptyBlock(nRow1, nRow2);
1909 : }
1910 : }
1911 312 : return bEmpty;
1912 : }
1913 :
1914 608050 : SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
1915 : SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
1916 : const ScPatternAttr* pPattern, const SfxItemSet* pCondSet )
1917 : {
1918 : // Rueckgabe = neues nArrY
1919 :
1920 608050 : sal_uInt8 nRotDir = pPattern->GetRotateDir( pCondSet );
1921 608050 : if ( nRotDir != SC_ROTDIR_NONE )
1922 : {
1923 530 : bool bHit = true;
1924 530 : if ( nCol+1 < nX1 ) // column to the left
1925 0 : bHit = ( nRotDir != SC_ROTDIR_LEFT );
1926 530 : else if ( nCol > nX2+1 ) // column to the right
1927 0 : bHit = ( nRotDir != SC_ROTDIR_RIGHT ); // SC_ROTDIR_STANDARD may now also be extended to the left
1928 :
1929 530 : if ( bHit )
1930 : {
1931 530 : double nFactor = 0.0;
1932 530 : if ( nCol > nX2+1 )
1933 : {
1934 : long nRotVal = static_cast<const SfxInt32Item&>( pPattern->
1935 0 : GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue();
1936 0 : double nRealOrient = nRotVal * F_PI18000; // 1/100 Grad
1937 0 : double nCos = cos( nRealOrient );
1938 0 : double nSin = sin( nRealOrient );
1939 : //! begrenzen !!!
1940 : //! zusaetzlich Faktor fuer unterschiedliche PPT X/Y !!!
1941 :
1942 : // bei SC_ROTDIR_LEFT kommt immer ein negativer Wert heraus,
1943 : // wenn der Modus beruecksichtigt wird
1944 0 : nFactor = -fabs( nCos / nSin );
1945 : }
1946 :
1947 3132 : for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
1948 : {
1949 2602 : if (!RowHidden(nRow))
1950 : {
1951 2602 : bool bHitOne = true;
1952 2602 : if ( nCol > nX2+1 )
1953 : {
1954 : // reicht die gedrehte Zelle bis in den sichtbaren Bereich?
1955 :
1956 0 : SCCOL nTouchedCol = nCol;
1957 0 : long nWidth = static_cast<long>(mpRowHeights->getValue(nRow) * nFactor);
1958 : OSL_ENSURE(nWidth <= 0, "Wrong direction");
1959 0 : while ( nWidth < 0 && nTouchedCol > 0 )
1960 : {
1961 0 : --nTouchedCol;
1962 0 : nWidth += GetColWidth( nTouchedCol );
1963 : }
1964 0 : if ( nTouchedCol > nX2 )
1965 0 : bHitOne = false;
1966 : }
1967 :
1968 2602 : if (bHitOne)
1969 : {
1970 7292 : while ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo < nRow )
1971 2088 : ++nArrY;
1972 2602 : if ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo == nRow )
1973 2602 : pRowInfo[nArrY].nRotMaxCol = nCol;
1974 : }
1975 : }
1976 : }
1977 : }
1978 : }
1979 :
1980 608050 : return nArrY;
1981 : }
1982 :
1983 583 : void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 )
1984 : {
1985 583 : if ( !pColWidth || !mpRowHeights || !pColFlags || !pRowFlags )
1986 : {
1987 : OSL_FAIL( "Row/column info missing" );
1988 583 : return;
1989 : }
1990 :
1991 : // nRotMaxCol ist auf SC_ROTMAX_NONE initialisiert, nRowNo ist schon gesetzt
1992 :
1993 583 : SCROW nY1 = pRowInfo[0].nRowNo;
1994 583 : SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
1995 :
1996 597575 : for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
1997 : {
1998 596992 : if (!ColHidden(nCol))
1999 : {
2000 596992 : SCSIZE nArrY = 0;
2001 596992 : ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
2002 : SCCOL nAttrCol;
2003 : SCROW nAttrRow1, nAttrRow2;
2004 596992 : const ScPatternAttr* pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
2005 1793388 : while ( pPattern )
2006 : {
2007 : const SfxPoolItem* pCondItem;
2008 599404 : if ( pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, true, &pCondItem )
2009 : == SfxItemState::SET )
2010 : {
2011 : // alle Formate durchgehen, damit die Zellen nicht einzeln
2012 : // angeschaut werden muessen
2013 :
2014 10504 : const std::vector<sal_uInt32>& rCondFormatData = static_cast<const ScCondFormatItem*>(pCondItem)->GetCondFormatData();
2015 10504 : ScStyleSheetPool* pStylePool = pDocument->GetStyleSheetPool();
2016 10504 : if (mpCondFormatList && pStylePool && !rCondFormatData.empty())
2017 : {
2018 24694 : for(std::vector<sal_uInt32>::const_iterator itr = rCondFormatData.begin(), itrEnd = rCondFormatData.end();
2019 : itr != itrEnd; ++itr)
2020 : {
2021 14190 : const ScConditionalFormat* pFormat = mpCondFormatList->GetFormat(*itr);
2022 14190 : if ( pFormat )
2023 : {
2024 14190 : size_t nEntryCount = pFormat->size();
2025 22836 : for (size_t nEntry=0; nEntry<nEntryCount; nEntry++)
2026 : {
2027 8646 : const ScFormatEntry* pEntry = pFormat->GetEntry(nEntry);
2028 8646 : if(pEntry->GetType() != condformat::CONDITION)
2029 0 : continue;
2030 :
2031 8646 : OUString aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle();
2032 8646 : if (!aStyleName.isEmpty())
2033 : {
2034 : SfxStyleSheetBase* pStyleSheet =
2035 8646 : pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
2036 8646 : if ( pStyleSheet )
2037 : {
2038 : FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
2039 : nCol, nAttrRow1, nAttrRow2,
2040 8646 : nArrY, pPattern, &pStyleSheet->GetItemSet() );
2041 : // nArrY nicht veraendern
2042 : }
2043 : }
2044 8646 : }
2045 : }
2046 : }
2047 : }
2048 : }
2049 :
2050 : nArrY = FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
2051 : nCol, nAttrRow1, nAttrRow2,
2052 599404 : nArrY, pPattern, NULL );
2053 :
2054 599404 : pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
2055 596992 : }
2056 : }
2057 : }
2058 : }
2059 :
2060 5905 : bool ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
2061 : {
2062 : using namespace sc;
2063 :
2064 5905 : sal_uInt16 nEdges = 0;
2065 :
2066 5905 : if ( nCol1 == nCol2 )
2067 : { // linke und rechte Spalte
2068 4995 : const sal_uInt16 n = MatrixEdgeLeft | MatrixEdgeRight;
2069 4995 : nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n );
2070 : // nicht (4 und 16) oder 1 oder 32
2071 4995 : if (nEdges && (((nEdges & n) != n) || (nEdges & (MatrixEdgeInside|MatrixEdgeOpen))))
2072 6 : return true; // linke oder rechte Kante fehlt oder offen
2073 : }
2074 : else
2075 : { // linke Spalte
2076 910 : nEdges = aCol[nCol1].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdgeLeft);
2077 : // nicht 4 oder 1 oder 32
2078 910 : if (nEdges && (((nEdges & MatrixEdgeLeft) != MatrixEdgeLeft) || (nEdges & (MatrixEdgeInside|MatrixEdgeOpen))))
2079 0 : return true; // linke Kante fehlt oder offen
2080 : // rechte Spalte
2081 910 : nEdges = aCol[nCol2].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdgeRight);
2082 : // nicht 16 oder 1 oder 32
2083 910 : if (nEdges && (((nEdges & MatrixEdgeRight) != MatrixEdgeRight) || (nEdges & (MatrixEdgeInside|MatrixEdgeOpen))))
2084 0 : return true; // rechte Kante fehlt oder offen
2085 : }
2086 :
2087 5899 : if ( nRow1 == nRow2 )
2088 : { // obere und untere Zeile
2089 4855 : bool bOpen = false;
2090 4855 : const sal_uInt16 n = MatrixEdgeBottom | MatrixEdgeTop;
2091 9774 : for ( SCCOL i=nCol1; i<=nCol2; i++)
2092 : {
2093 4919 : nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n );
2094 4919 : if ( nEdges )
2095 : {
2096 0 : if ( (nEdges & n) != n )
2097 0 : return true; // obere oder untere Kante fehlt
2098 0 : if (nEdges & MatrixEdgeLeft)
2099 0 : bOpen = true; // linke Kante oeffnet, weitersehen
2100 0 : else if ( !bOpen )
2101 0 : return true; // es gibt was, was nicht geoeffnet wurde
2102 0 : if (nEdges & MatrixEdgeRight)
2103 0 : bOpen = false; // rechte Kante schliesst
2104 : }
2105 : }
2106 4855 : if ( bOpen )
2107 0 : return true; // es geht noch weiter
2108 : }
2109 : else
2110 : {
2111 : sal_uInt16 j, n;
2112 : SCROW nR;
2113 : // erst obere Zeile, dann untere Zeile
2114 3132 : for ( j=0, nR=nRow1, n=8; j<2; j++, nR=nRow2, n=2 )
2115 : {
2116 2088 : bool bOpen = false;
2117 202820 : for ( SCCOL i=nCol1; i<=nCol2; i++)
2118 : {
2119 200732 : nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n );
2120 200732 : if ( nEdges )
2121 : {
2122 : // in oberere Zeile keine obere Kante bzw.
2123 : // in unterer Zeile keine untere Kante
2124 4 : if ( (nEdges & n) != n )
2125 0 : return true;
2126 4 : if (nEdges & MatrixEdgeLeft)
2127 4 : bOpen = true; // linke Kante oeffnet, weitersehen
2128 0 : else if ( !bOpen )
2129 0 : return true; // es gibt was, was nicht geoeffnet wurde
2130 4 : if (nEdges & MatrixEdgeRight)
2131 4 : bOpen = false; // rechte Kante schliesst
2132 : }
2133 : }
2134 2088 : if ( bOpen )
2135 0 : return true; // es geht noch weiter
2136 : }
2137 : }
2138 5899 : return false;
2139 : }
2140 :
2141 122 : bool ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
2142 : {
2143 122 : std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans();
2144 :
2145 244 : for ( size_t i=0; i<aSpans.size(); i++ )
2146 : {
2147 870 : for ( SCCOLROW j=aSpans[i].mnStart; j<aSpans[i].mnEnd; j++ )
2148 : {
2149 748 : if ( aCol[j].HasSelectionMatrixFragment(rMark) )
2150 0 : return true;
2151 : }
2152 : }
2153 122 : return false;
2154 : }
2155 :
2156 5879 : bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
2157 : SCROW nRow2, bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
2158 : {
2159 5879 : if ( !ValidColRow( nCol2, nRow2 ) )
2160 : {
2161 : OSL_FAIL("IsBlockEditable: invalid column or row");
2162 0 : if (pOnlyNotBecauseOfMatrix)
2163 0 : *pOnlyNotBecauseOfMatrix = false;
2164 0 : return false;
2165 : }
2166 :
2167 5879 : bool bIsEditable = true;
2168 5879 : if ( nLockCount )
2169 0 : bIsEditable = false;
2170 5879 : else if ( IsProtected() && !pDocument->IsScenario(nTab) )
2171 : {
2172 0 : bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED );
2173 0 : if (!bIsEditable)
2174 : {
2175 : // An enhanced protection permission may override the attribute.
2176 0 : if (pTabProtection)
2177 0 : bIsEditable = pTabProtection->isBlockEditable( ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab));
2178 : }
2179 0 : if (bIsEditable)
2180 : {
2181 : // If Sheet is protected and cells are not protected then
2182 : // check the active scenario protect flag if this range is
2183 : // on the active scenario range. Note the 'copy back' must also
2184 : // be set to apply protection.
2185 0 : sal_uInt16 nScenTab = nTab+1;
2186 0 : while(pDocument->IsScenario(nScenTab))
2187 : {
2188 0 : ScRange aEditRange(nCol1, nRow1, nScenTab, nCol2, nRow2, nScenTab);
2189 0 : if(pDocument->IsActiveScenario(nScenTab) && pDocument->HasScenarioRange(nScenTab, aEditRange))
2190 : {
2191 : sal_uInt16 nFlags;
2192 0 : pDocument->GetScenarioFlags(nScenTab,nFlags);
2193 0 : bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
2194 0 : break;
2195 : }
2196 0 : nScenTab++;
2197 : }
2198 : }
2199 : }
2200 5879 : else if (pDocument->IsScenario(nTab))
2201 : {
2202 : // Determine if the preceding sheet is protected
2203 0 : SCTAB nActualTab = nTab;
2204 0 : do
2205 : {
2206 0 : nActualTab--;
2207 : }
2208 0 : while(pDocument->IsScenario(nActualTab));
2209 :
2210 0 : if(pDocument->IsTabProtected(nActualTab))
2211 : {
2212 0 : ScRange aEditRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
2213 0 : if(pDocument->HasScenarioRange(nTab, aEditRange))
2214 : {
2215 : sal_uInt16 nFlags;
2216 0 : pDocument->GetScenarioFlags(nTab,nFlags);
2217 0 : bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
2218 : }
2219 : }
2220 : }
2221 5879 : if ( bIsEditable )
2222 : {
2223 5879 : if ( HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2 ) )
2224 : {
2225 6 : bIsEditable = false;
2226 6 : if ( pOnlyNotBecauseOfMatrix )
2227 6 : *pOnlyNotBecauseOfMatrix = true;
2228 : }
2229 5873 : else if ( pOnlyNotBecauseOfMatrix )
2230 5283 : *pOnlyNotBecauseOfMatrix = false;
2231 : }
2232 0 : else if ( pOnlyNotBecauseOfMatrix )
2233 0 : *pOnlyNotBecauseOfMatrix = false;
2234 5879 : return bIsEditable;
2235 : }
2236 :
2237 122 : bool ScTable::IsSelectionEditable( const ScMarkData& rMark,
2238 : bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
2239 : {
2240 122 : bool bIsEditable = true;
2241 122 : if ( nLockCount )
2242 0 : bIsEditable = false;
2243 122 : else if ( IsProtected() && !pDocument->IsScenario(nTab) )
2244 : {
2245 0 : ScRangeList aRanges;
2246 0 : rMark.FillRangeListWithMarks( &aRanges, false );
2247 0 : bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED );
2248 0 : if (!bIsEditable)
2249 : {
2250 : // An enhanced protection permission may override the attribute.
2251 0 : if (pTabProtection)
2252 0 : bIsEditable = pTabProtection->isSelectionEditable( aRanges);
2253 : }
2254 0 : if (bIsEditable)
2255 : {
2256 : // If Sheet is protected and cells are not protected then
2257 : // check the active scenario protect flag if this area is
2258 : // in the active scenario range.
2259 0 : SCTAB nScenTab = nTab+1;
2260 0 : while(pDocument->IsScenario(nScenTab) && bIsEditable)
2261 : {
2262 0 : if(pDocument->IsActiveScenario(nScenTab))
2263 : {
2264 0 : for (size_t i=0, nRange = aRanges.size(); (i < nRange) && bIsEditable; i++ )
2265 : {
2266 0 : ScRange aRange = *aRanges[ i ];
2267 0 : if(pDocument->HasScenarioRange(nScenTab, aRange))
2268 : {
2269 : sal_uInt16 nFlags;
2270 0 : pDocument->GetScenarioFlags(nScenTab,nFlags);
2271 0 : bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
2272 : }
2273 : }
2274 : }
2275 0 : nScenTab++;
2276 : }
2277 0 : }
2278 : }
2279 122 : else if (pDocument->IsScenario(nTab))
2280 : {
2281 : // Determine if the preceding sheet is protected
2282 0 : SCTAB nActualTab = nTab;
2283 0 : do
2284 : {
2285 0 : nActualTab--;
2286 : }
2287 0 : while(pDocument->IsScenario(nActualTab));
2288 :
2289 0 : if(pDocument->IsTabProtected(nActualTab))
2290 : {
2291 0 : ScRangeList aRanges;
2292 0 : rMark.FillRangeListWithMarks( &aRanges, false );
2293 0 : for (size_t i = 0, nRange = aRanges.size(); (i < nRange) && bIsEditable; i++)
2294 : {
2295 0 : ScRange aRange = *aRanges[ i ];
2296 0 : if(pDocument->HasScenarioRange(nTab, aRange))
2297 : {
2298 : sal_uInt16 nFlags;
2299 0 : pDocument->GetScenarioFlags(nTab,nFlags);
2300 0 : bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
2301 : }
2302 0 : }
2303 : }
2304 : }
2305 122 : if ( bIsEditable )
2306 : {
2307 122 : if ( HasSelectionMatrixFragment( rMark ) )
2308 : {
2309 0 : bIsEditable = false;
2310 0 : if ( pOnlyNotBecauseOfMatrix )
2311 0 : *pOnlyNotBecauseOfMatrix = true;
2312 : }
2313 122 : else if ( pOnlyNotBecauseOfMatrix )
2314 122 : *pOnlyNotBecauseOfMatrix = false;
2315 : }
2316 0 : else if ( pOnlyNotBecauseOfMatrix )
2317 0 : *pOnlyNotBecauseOfMatrix = false;
2318 122 : return bIsEditable;
2319 : }
2320 :
2321 0 : void ScTable::LockTable()
2322 : {
2323 0 : ++nLockCount;
2324 0 : }
2325 :
2326 0 : void ScTable::UnlockTable()
2327 : {
2328 0 : if (nLockCount)
2329 0 : --nLockCount;
2330 : else
2331 : {
2332 : OSL_FAIL("UnlockTable without LockTable");
2333 : }
2334 0 : }
2335 :
2336 500 : void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, bool bDeep ) const
2337 : {
2338 512500 : for (SCCOL i=0; i<=MAXCOL; i++)
2339 512000 : aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
2340 500 : }
2341 :
2342 22126 : void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1,
2343 : SCCOL nCol2, SCROW nRow2, bool bDeep ) const
2344 : {
2345 134780 : for (SCCOL i=nCol1; i<=nCol2; i++)
2346 112654 : aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
2347 22126 : }
2348 :
2349 88 : void ScTable::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
2350 : SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
2351 : {
2352 88 : if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2353 : {
2354 88 : PutInOrder(nStartCol, nEndCol);
2355 88 : PutInOrder(nStartRow, nEndRow);
2356 344 : for (SCCOL i=nStartCol; i<=nEndCol; i++)
2357 256 : aCol[i].MergeBlockFrame( pLineOuter, pLineInner, rFlags,
2358 512 : nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
2359 : }
2360 88 : }
2361 :
2362 1884 : void ScTable::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
2363 : SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
2364 : {
2365 1884 : if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2366 : {
2367 1884 : PutInOrder(nStartCol, nEndCol);
2368 1884 : PutInOrder(nStartRow, nEndRow);
2369 5576 : for (SCCOL i=nStartCol; i<=nEndCol; i++)
2370 3692 : aCol[i].ApplyBlockFrame( pLineOuter, pLineInner,
2371 7384 : nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
2372 : }
2373 1884 : }
2374 :
2375 24 : void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
2376 : {
2377 24 : if (ValidColRow(nCol,nRow))
2378 24 : aCol[nCol].ApplyPattern( nRow, rAttr );
2379 24 : }
2380 :
2381 3610 : void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2382 : const ScPatternAttr& rAttr, ScEditDataArray* pDataArray )
2383 : {
2384 3610 : if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2385 : {
2386 3610 : PutInOrder(nStartCol, nEndCol);
2387 3610 : PutInOrder(nStartRow, nEndRow);
2388 138008 : for (SCCOL i = nStartCol; i <= nEndCol; i++)
2389 134398 : aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray);
2390 : }
2391 3610 : }
2392 :
2393 0 : void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
2394 : const ScPatternAttr& rPattern, short nNewType )
2395 : {
2396 0 : SCCOL nEndCol = rRange.aEnd.Col();
2397 0 : for ( SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; nCol++ )
2398 : {
2399 0 : aCol[nCol].ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
2400 : }
2401 0 : }
2402 :
2403 1452 : void ScTable::AddCondFormatData( const ScRangeList& rRange, sal_uInt32 nIndex )
2404 : {
2405 1452 : size_t n = rRange.size();
2406 2912 : for(size_t i = 0; i < n; ++i)
2407 : {
2408 1460 : const ScRange* pRange = rRange[i];
2409 1460 : SCCOL nColStart = pRange->aStart.Col();
2410 1460 : SCCOL nColEnd = pRange->aEnd.Col();
2411 1460 : SCROW nRowStart = pRange->aStart.Row();
2412 1460 : SCROW nRowEnd = pRange->aEnd.Row();
2413 14496 : for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
2414 : {
2415 13036 : aCol[nCol].AddCondFormat(nRowStart, nRowEnd, nIndex);
2416 : }
2417 : }
2418 1452 : }
2419 :
2420 0 : void ScTable::RemoveCondFormatData( const ScRangeList& rRange, sal_uInt32 nIndex )
2421 : {
2422 0 : size_t n = rRange.size();
2423 0 : for(size_t i = 0; i < n; ++i)
2424 : {
2425 0 : const ScRange* pRange = rRange[i];
2426 0 : SCCOL nColStart = pRange->aStart.Col();
2427 0 : SCCOL nColEnd = pRange->aEnd.Col();
2428 0 : SCROW nRowStart = pRange->aStart.Row();
2429 0 : SCROW nRowEnd = pRange->aEnd.Row();
2430 0 : for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
2431 : {
2432 0 : aCol[nCol].RemoveCondFormat(nRowStart, nRowEnd, nIndex);
2433 : }
2434 : }
2435 0 : }
2436 :
2437 4 : void ScTable::ApplyStyle( SCCOL nCol, SCROW nRow, const ScStyleSheet& rStyle )
2438 : {
2439 4 : if (ValidColRow(nCol,nRow))
2440 4 : aCol[nCol].ApplyStyle( nRow, rStyle );
2441 4 : }
2442 :
2443 4014 : void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
2444 : {
2445 4014 : if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2446 : {
2447 4014 : PutInOrder(nStartCol, nEndCol);
2448 4014 : PutInOrder(nStartRow, nEndRow);
2449 410106 : for (SCCOL i = nStartCol; i <= nEndCol; i++)
2450 406092 : aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
2451 : }
2452 4014 : }
2453 :
2454 470 : void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
2455 : {
2456 481750 : for (SCCOL i=0; i<=MAXCOL; i++)
2457 481280 : aCol[i].ApplySelectionStyle( rStyle, rMark );
2458 470 : }
2459 :
2460 0 : void ScTable::ApplySelectionLineStyle( const ScMarkData& rMark,
2461 : const ::editeng::SvxBorderLine* pLine, bool bColorOnly )
2462 : {
2463 0 : if ( bColorOnly && !pLine )
2464 0 : return;
2465 :
2466 0 : for (SCCOL i=0; i<=MAXCOL; i++)
2467 0 : aCol[i].ApplySelectionLineStyle( rMark, pLine, bColorOnly );
2468 : }
2469 :
2470 16 : const ScStyleSheet* ScTable::GetStyle( SCCOL nCol, SCROW nRow ) const
2471 : {
2472 16 : if (ValidColRow(nCol, nRow))
2473 16 : return aCol[nCol].GetStyle(nRow);
2474 : else
2475 0 : return NULL;
2476 : }
2477 :
2478 44 : const ScStyleSheet* ScTable::GetSelectionStyle( const ScMarkData& rMark, bool& rFound ) const
2479 : {
2480 44 : rFound = false;
2481 :
2482 44 : bool bEqual = true;
2483 : bool bColFound;
2484 :
2485 44 : const ScStyleSheet* pStyle = NULL;
2486 : const ScStyleSheet* pNewStyle;
2487 :
2488 45100 : for (SCCOL i=0; i<=MAXCOL && bEqual; i++)
2489 45056 : if (rMark.HasMultiMarks(i))
2490 : {
2491 45056 : pNewStyle = aCol[i].GetSelectionStyle( rMark, bColFound );
2492 45056 : if (bColFound)
2493 : {
2494 45056 : rFound = true;
2495 45056 : if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
2496 0 : bEqual = false; // unterschiedliche
2497 45056 : pStyle = pNewStyle;
2498 : }
2499 : }
2500 :
2501 44 : return bEqual ? pStyle : NULL;
2502 : }
2503 :
2504 340 : const ScStyleSheet* ScTable::GetAreaStyle( bool& rFound, SCCOL nCol1, SCROW nRow1,
2505 : SCCOL nCol2, SCROW nRow2 ) const
2506 : {
2507 340 : rFound = false;
2508 :
2509 340 : bool bEqual = true;
2510 : bool bColFound;
2511 :
2512 340 : const ScStyleSheet* pStyle = NULL;
2513 : const ScStyleSheet* pNewStyle;
2514 :
2515 70400 : for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
2516 : {
2517 70060 : pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
2518 70060 : if (bColFound)
2519 : {
2520 70060 : rFound = true;
2521 70060 : if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
2522 0 : bEqual = false; // unterschiedliche
2523 70060 : pStyle = pNewStyle;
2524 : }
2525 : }
2526 :
2527 340 : return bEqual ? pStyle : NULL;
2528 : }
2529 :
2530 0 : bool ScTable::IsStyleSheetUsed( const ScStyleSheet& rStyle, bool bGatherAllStyles ) const
2531 : {
2532 0 : bool bIsUsed = false;
2533 :
2534 0 : for ( SCCOL i=0; i<=MAXCOL; i++ )
2535 : {
2536 0 : if ( aCol[i].IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
2537 : {
2538 0 : if ( !bGatherAllStyles )
2539 0 : return true;
2540 0 : bIsUsed = true;
2541 : }
2542 : }
2543 :
2544 0 : return bIsUsed;
2545 : }
2546 :
2547 10444 : void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, bool bRemoved,
2548 : OutputDevice* pDev,
2549 : double nPPTX, double nPPTY,
2550 : const Fraction& rZoomX, const Fraction& rZoomY )
2551 : {
2552 10444 : ScFlatBoolRowSegments aUsedRows;
2553 10705100 : for (SCCOL i = 0; i <= MAXCOL; ++i)
2554 10694656 : aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
2555 :
2556 20888 : sc::RowHeightContext aCxt(nPPTX, nPPTY, rZoomX, rZoomY, pDev);
2557 10444 : SCROW nRow = 0;
2558 31332 : while (nRow <= MAXROW)
2559 : {
2560 : ScFlatBoolRowSegments::RangeData aData;
2561 10444 : if (!aUsedRows.getRangeData(nRow, aData))
2562 : // search failed!
2563 10444 : return;
2564 :
2565 10444 : SCROW nEndRow = aData.mnRow2;
2566 10444 : if (aData.mbValue)
2567 3334 : SetOptimalHeight(aCxt, nRow, nEndRow);
2568 :
2569 10444 : nRow = nEndRow + 1;
2570 10444 : }
2571 : }
2572 :
2573 2386 : bool ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2574 : sal_Int16 nFlags )
2575 : {
2576 2386 : bool bChanged = false;
2577 2386 : if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2578 13258 : for (SCCOL i = nStartCol; i <= nEndCol; i++)
2579 10872 : bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags);
2580 2386 : return bChanged;
2581 : }
2582 :
2583 686 : bool ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2584 : sal_Int16 nFlags )
2585 : {
2586 686 : bool bChanged = false;
2587 686 : if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2588 32932 : for (SCCOL i = nStartCol; i <= nEndCol; i++)
2589 32246 : bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
2590 686 : return bChanged;
2591 : }
2592 :
2593 12 : void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr, bool bPutToPool )
2594 : {
2595 12 : if (ValidColRow(nCol,nRow))
2596 12 : aCol[nCol].SetPattern( nRow, rAttr, bPutToPool );
2597 12 : }
2598 :
2599 5660 : void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
2600 : {
2601 5660 : if (ValidColRow(nCol,nRow))
2602 5660 : aCol[nCol].ApplyAttr( nRow, rAttr );
2603 5660 : }
2604 :
2605 344 : void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark,
2606 : ScEditDataArray* pDataArray )
2607 : {
2608 352600 : for (SCCOL i=0; i<=MAXCOL; i++)
2609 352256 : aCol[i].ApplySelectionCache( pCache, rMark, pDataArray );
2610 344 : }
2611 :
2612 12 : void ScTable::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark )
2613 : {
2614 12300 : for (SCCOL i=0; i<=MAXCOL; i++)
2615 12288 : aCol[i].ChangeSelectionIndent( bIncrement, rMark );
2616 12 : }
2617 :
2618 0 : void ScTable::ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark )
2619 : {
2620 0 : for (SCCOL i=0; i<=MAXCOL; i++)
2621 0 : aCol[i].ClearSelectionItems( pWhich, rMark );
2622 0 : }
2623 :
2624 : // Spaltenbreiten / Zeilenhoehen
2625 :
2626 32608 : void ScTable::SetColWidth( SCCOL nCol, sal_uInt16 nNewWidth )
2627 : {
2628 32608 : if (ValidCol(nCol) && pColWidth)
2629 : {
2630 32608 : if (!nNewWidth)
2631 : {
2632 0 : nNewWidth = STD_COL_WIDTH;
2633 : }
2634 :
2635 32608 : if ( nNewWidth != pColWidth[nCol] )
2636 : {
2637 21478 : pColWidth[nCol] = nNewWidth;
2638 21478 : InvalidatePageBreaks();
2639 : }
2640 : }
2641 : else
2642 : {
2643 : OSL_FAIL("Invalid column number or no widths");
2644 : }
2645 32608 : }
2646 :
2647 692224 : void ScTable::SetColWidthOnly( SCCOL nCol, sal_uInt16 nNewWidth )
2648 : {
2649 692224 : if (!ValidCol(nCol) || !pColWidth)
2650 692224 : return;
2651 :
2652 692224 : if (!nNewWidth)
2653 0 : nNewWidth = STD_COL_WIDTH;
2654 :
2655 692224 : if (nNewWidth != pColWidth[nCol])
2656 638986 : pColWidth[nCol] = nNewWidth;
2657 : }
2658 :
2659 2 : void ScTable::SetRowHeight( SCROW nRow, sal_uInt16 nNewHeight )
2660 : {
2661 2 : if (ValidRow(nRow) && mpRowHeights)
2662 : {
2663 2 : if (!nNewHeight)
2664 : {
2665 : OSL_FAIL("SetRowHeight: Row height zero");
2666 0 : nNewHeight = ScGlobal::nStdRowHeight;
2667 : }
2668 :
2669 2 : sal_uInt16 nOldHeight = mpRowHeights->getValue(nRow);
2670 2 : if ( nNewHeight != nOldHeight )
2671 : {
2672 2 : mpRowHeights->setValue(nRow, nRow, nNewHeight);
2673 2 : InvalidatePageBreaks();
2674 : }
2675 : }
2676 : else
2677 : {
2678 : OSL_FAIL("Invalid row number or no heights");
2679 : }
2680 2 : }
2681 :
2682 : namespace {
2683 :
2684 : /**
2685 : * Check if the new pixel size is different from the old size between
2686 : * specified ranges.
2687 : */
2688 2766 : bool lcl_pixelSizeChanged(
2689 : ScFlatUInt16RowSegments& rRowHeights, SCROW nStartRow, SCROW nEndRow,
2690 : sal_uInt16 nNewHeight, double nPPTY)
2691 : {
2692 2766 : long nNewPix = static_cast<long>(nNewHeight * nPPTY);
2693 :
2694 2766 : ScFlatUInt16RowSegments::ForwardIterator aFwdIter(rRowHeights);
2695 5340 : for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
2696 : {
2697 : sal_uInt16 nHeight;
2698 2774 : if (!aFwdIter.getValue(nRow, nHeight))
2699 0 : break;
2700 :
2701 2774 : if (nHeight != nNewHeight)
2702 : {
2703 208 : bool bChanged = (nNewPix != static_cast<long>(nHeight * nPPTY));
2704 208 : if (bChanged)
2705 200 : return true;
2706 : }
2707 :
2708 : // Skip ahead to the last position of the current range.
2709 2574 : nRow = aFwdIter.getLastPos();
2710 : }
2711 2566 : return false;
2712 : }
2713 :
2714 : }
2715 :
2716 2766 : bool ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight,
2717 : double /* nPPTX */, double nPPTY )
2718 : {
2719 2766 : bool bChanged = false;
2720 2766 : if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
2721 : {
2722 2766 : if (!nNewHeight)
2723 : {
2724 : OSL_FAIL("SetRowHeight: Row height zero");
2725 0 : nNewHeight = ScGlobal::nStdRowHeight;
2726 : }
2727 :
2728 2766 : bool bSingle = false; // true = process every row for its own
2729 2766 : ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
2730 2766 : if (pDrawLayer)
2731 2528 : if (pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ))
2732 36 : bSingle = true;
2733 :
2734 2766 : if (bSingle)
2735 : {
2736 : ScFlatUInt16RowSegments::RangeData aData;
2737 36 : mpRowHeights->getRangeData(nStartRow, aData);
2738 36 : if (nNewHeight == aData.mnValue && nEndRow <= aData.mnRow2)
2739 26 : bSingle = false; // no difference in this range
2740 : }
2741 2766 : if (bSingle)
2742 : {
2743 10 : if (nEndRow-nStartRow < 20)
2744 : {
2745 10 : if (!bChanged)
2746 10 : bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
2747 :
2748 10 : mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
2749 : }
2750 : else
2751 : {
2752 0 : SCROW nMid = (nStartRow+nEndRow) / 2;
2753 0 : if (SetRowHeightRange( nStartRow, nMid, nNewHeight, 1.0, 1.0 ))
2754 0 : bChanged = true;
2755 0 : if (SetRowHeightRange( nMid+1, nEndRow, nNewHeight, 1.0, 1.0 ))
2756 0 : bChanged = true;
2757 : }
2758 : }
2759 : else
2760 : {
2761 2756 : if (!bChanged)
2762 2756 : bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
2763 :
2764 2756 : mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
2765 : }
2766 :
2767 2766 : if (bChanged)
2768 200 : InvalidatePageBreaks();
2769 : }
2770 : else
2771 : {
2772 : OSL_FAIL("Invalid row number or no heights");
2773 : }
2774 :
2775 2766 : return bChanged;
2776 : }
2777 :
2778 9860 : void ScTable::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight )
2779 : {
2780 9860 : if (!ValidRow(nStartRow) || !ValidRow(nEndRow) || !mpRowHeights)
2781 9860 : return;
2782 :
2783 9860 : if (!nNewHeight)
2784 0 : nNewHeight = ScGlobal::nStdRowHeight;
2785 :
2786 9860 : mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
2787 : }
2788 :
2789 764 : void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, bool bManual )
2790 : {
2791 764 : if (ValidRow(nStartRow) && ValidRow(nEndRow) && pRowFlags)
2792 : {
2793 764 : if (bManual)
2794 764 : pRowFlags->OrValue( nStartRow, nEndRow, CR_MANUALSIZE);
2795 : else
2796 0 : pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<sal_uInt8>(~CR_MANUALSIZE));
2797 : }
2798 : else
2799 : {
2800 : OSL_FAIL("Invalid row number or no column flags");
2801 : }
2802 764 : }
2803 :
2804 1312469 : sal_uInt16 ScTable::GetColWidth( SCCOL nCol, bool bHiddenAsZero ) const
2805 : {
2806 : OSL_ENSURE(ValidCol(nCol),"wrong column number");
2807 :
2808 1312469 : if (ValidCol(nCol) && pColFlags && pColWidth)
2809 : {
2810 1312469 : if (bHiddenAsZero && ColHidden(nCol))
2811 2900 : return 0;
2812 : else
2813 1309569 : return pColWidth[nCol];
2814 : }
2815 : else
2816 0 : return (sal_uInt16) STD_COL_WIDTH;
2817 : }
2818 :
2819 59274 : sal_uInt16 ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingestellte
2820 : {
2821 : OSL_ENSURE(ValidCol(nCol),"wrong column number");
2822 :
2823 59274 : if (ValidCol(nCol) && pColWidth)
2824 59274 : return pColWidth[nCol];
2825 : else
2826 0 : return (sal_uInt16) STD_COL_WIDTH;
2827 : }
2828 :
2829 0 : sal_uInt16 ScTable::GetCommonWidth( SCCOL nEndCol ) const
2830 : {
2831 : // get the width that is used in the largest continuous column range (up to nEndCol)
2832 :
2833 0 : if ( !ValidCol(nEndCol) )
2834 : {
2835 : OSL_FAIL("wrong column");
2836 0 : nEndCol = MAXCOL;
2837 : }
2838 :
2839 0 : sal_uInt16 nMaxWidth = 0;
2840 0 : sal_uInt16 nMaxCount = 0;
2841 0 : SCCOL nRangeStart = 0;
2842 0 : while ( nRangeStart <= nEndCol )
2843 : {
2844 : // skip hidden columns
2845 0 : while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) )
2846 0 : ++nRangeStart;
2847 0 : if ( nRangeStart <= nEndCol )
2848 : {
2849 0 : sal_uInt16 nThisCount = 0;
2850 0 : sal_uInt16 nThisWidth = pColWidth[nRangeStart];
2851 0 : SCCOL nRangeEnd = nRangeStart;
2852 0 : while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth )
2853 : {
2854 0 : ++nThisCount;
2855 0 : ++nRangeEnd;
2856 :
2857 : // skip hidden columns
2858 0 : while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) )
2859 0 : ++nRangeEnd;
2860 : }
2861 :
2862 0 : if ( nThisCount > nMaxCount )
2863 : {
2864 0 : nMaxCount = nThisCount;
2865 0 : nMaxWidth = nThisWidth;
2866 : }
2867 :
2868 0 : nRangeStart = nRangeEnd; // next range
2869 : }
2870 : }
2871 :
2872 0 : return nMaxWidth;
2873 : }
2874 :
2875 166413682 : sal_uInt16 ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
2876 : {
2877 : OSL_ENSURE(ValidRow(nRow),"Invalid row number");
2878 :
2879 166413682 : if (ValidRow(nRow) && mpRowHeights)
2880 : {
2881 166413682 : if (bHiddenAsZero && RowHidden( nRow, pStartRow, pEndRow))
2882 1726 : return 0;
2883 : else
2884 : {
2885 : ScFlatUInt16RowSegments::RangeData aData;
2886 166411956 : if (!mpRowHeights->getRangeData(nRow, aData))
2887 : {
2888 0 : if (pStartRow)
2889 0 : *pStartRow = nRow;
2890 0 : if (pEndRow)
2891 0 : *pEndRow = nRow;
2892 : // TODO: What should we return in case the search fails?
2893 0 : return 0;
2894 : }
2895 :
2896 : // If bHiddenAsZero, pStartRow and pEndRow were initialized to
2897 : // boundaries of a non-hidden segment. Assume that the previous and
2898 : // next segment are hidden then and limit the current height
2899 : // segment.
2900 166411956 : if (pStartRow)
2901 114 : *pStartRow = (bHiddenAsZero ? std::max( *pStartRow, aData.mnRow1) : aData.mnRow1);
2902 166411956 : if (pEndRow)
2903 123508 : *pEndRow = (bHiddenAsZero ? std::min( *pEndRow, aData.mnRow2) : aData.mnRow2);
2904 166411956 : return aData.mnValue;
2905 : }
2906 : }
2907 : else
2908 : {
2909 0 : if (pStartRow)
2910 0 : *pStartRow = nRow;
2911 0 : if (pEndRow)
2912 0 : *pEndRow = nRow;
2913 0 : return (sal_uInt16) ScGlobal::nStdRowHeight;
2914 : }
2915 : }
2916 :
2917 5564 : sal_uLong ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero ) const
2918 : {
2919 : OSL_ENSURE(ValidRow(nStartRow) && ValidRow(nEndRow),"wrong row number");
2920 :
2921 5564 : if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
2922 : {
2923 5564 : sal_uLong nHeight = 0;
2924 5564 : SCROW nRow = nStartRow;
2925 17438 : while (nRow <= nEndRow)
2926 : {
2927 6310 : SCROW nLastRow = -1;
2928 6310 : if (!( ( RowHidden(nRow, NULL, &nLastRow) ) && bHiddenAsZero ) )
2929 : {
2930 5904 : if (nLastRow > nEndRow)
2931 5002 : nLastRow = nEndRow;
2932 5904 : nHeight += mpRowHeights->getSumValue(nRow, nLastRow);
2933 : }
2934 6310 : nRow = nLastRow + 1;
2935 : }
2936 5564 : return nHeight;
2937 : }
2938 : else
2939 0 : return (nEndRow - nStartRow + 1) * (sal_uLong)ScGlobal::nStdRowHeight;
2940 : }
2941 :
2942 2 : sal_uLong ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const
2943 : {
2944 : OSL_ENSURE(ValidRow(nStartRow) && ValidRow(nEndRow),"wrong row number");
2945 :
2946 2 : if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
2947 : {
2948 2 : sal_uLong nHeight = 0;
2949 2 : SCROW nRow = nStartRow;
2950 6 : while (nRow <= nEndRow)
2951 : {
2952 2 : SCROW nLastRow = -1;
2953 2 : if (!RowHidden(nRow, NULL, &nLastRow))
2954 : {
2955 2 : if (nLastRow > nEndRow)
2956 2 : nLastRow = nEndRow;
2957 :
2958 : // #i117315# can't use getSumValue, because individual values must be rounded
2959 6 : while (nRow <= nLastRow)
2960 : {
2961 : ScFlatUInt16RowSegments::RangeData aData;
2962 2 : if (!mpRowHeights->getRangeData(nRow, aData))
2963 0 : return nHeight; // shouldn't happen
2964 :
2965 2 : SCROW nSegmentEnd = std::min( nLastRow, aData.mnRow2 );
2966 :
2967 : // round-down a single height value, multiply resulting (pixel) values
2968 2 : sal_uLong nOneHeight = static_cast<sal_uLong>( aData.mnValue * fScale );
2969 2 : nHeight += nOneHeight * ( nSegmentEnd + 1 - nRow );
2970 :
2971 2 : nRow = nSegmentEnd + 1;
2972 : }
2973 : }
2974 2 : nRow = nLastRow + 1;
2975 : }
2976 2 : return nHeight;
2977 : }
2978 : else
2979 0 : return (sal_uLong) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
2980 : }
2981 :
2982 83135 : sal_uInt16 ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hidden
2983 : {
2984 : OSL_ENSURE(ValidRow(nRow),"wrong row number");
2985 :
2986 83135 : if (ValidRow(nRow) && mpRowHeights)
2987 83135 : return mpRowHeights->getValue(nRow);
2988 : else
2989 0 : return (sal_uInt16) ScGlobal::nStdRowHeight;
2990 : }
2991 :
2992 : // Spalten-/Zeilen-Flags
2993 :
2994 104 : SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const
2995 : {
2996 104 : if (!ValidRow(nRow))
2997 0 : return 0;
2998 :
2999 104 : SCROW nLastRow = -1;
3000 104 : if (!RowHidden(nRow, NULL, &nLastRow) || !ValidRow(nLastRow))
3001 0 : return 0;
3002 :
3003 104 : return nLastRow - nRow + 1;
3004 : }
3005 :
3006 : //! ShowRows / DBShowRows zusammenfassen
3007 :
3008 29242 : void ScTable::ShowCol(SCCOL nCol, bool bShow)
3009 : {
3010 29242 : if (ValidCol(nCol))
3011 : {
3012 29242 : bool bWasVis = !ColHidden(nCol);
3013 29242 : if (bWasVis != bShow)
3014 : {
3015 408 : SetColHidden(nCol, nCol, !bShow);
3016 :
3017 408 : ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
3018 408 : if ( pCharts )
3019 408 : pCharts->SetRangeDirty(ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ));
3020 : }
3021 : }
3022 : else
3023 : {
3024 : OSL_FAIL("Invalid column number or no flags");
3025 : }
3026 29242 : }
3027 :
3028 0 : void ScTable::ShowRow(SCROW nRow, bool bShow)
3029 : {
3030 0 : if (ValidRow(nRow) && pRowFlags)
3031 : {
3032 0 : bool bWasVis = !RowHidden(nRow);
3033 0 : if (bWasVis != bShow)
3034 : {
3035 0 : SetRowHidden(nRow, nRow, !bShow);
3036 0 : if (bShow)
3037 0 : SetRowFiltered(nRow, nRow, false);
3038 0 : ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
3039 0 : if ( pCharts )
3040 0 : pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
3041 :
3042 0 : InvalidatePageBreaks();
3043 : }
3044 : }
3045 : else
3046 : {
3047 : OSL_FAIL("Invalid row number or no flags");
3048 : }
3049 0 : }
3050 :
3051 4 : void ScTable::DBShowRow(SCROW nRow, bool bShow)
3052 : {
3053 4 : if (ValidRow(nRow) && pRowFlags)
3054 : {
3055 : // Filter-Flag immer setzen, auch wenn Hidden unveraendert
3056 4 : bool bChanged = SetRowHidden(nRow, nRow, !bShow);
3057 4 : SetRowFiltered(nRow, nRow, !bShow);
3058 :
3059 4 : if (bChanged)
3060 : {
3061 0 : ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
3062 0 : if ( pCharts )
3063 0 : pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
3064 :
3065 0 : if (pOutlineTable)
3066 0 : UpdateOutlineRow( nRow, nRow, bShow );
3067 :
3068 0 : InvalidatePageBreaks();
3069 : }
3070 : }
3071 : else
3072 : {
3073 : OSL_FAIL("Invalid row number or no flags");
3074 : }
3075 4 : }
3076 :
3077 92 : void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
3078 : {
3079 92 : SCROW nStartRow = nRow1;
3080 302 : while (nStartRow <= nRow2)
3081 : {
3082 118 : SCROW nEndRow = -1;
3083 118 : bool bWasVis = !RowHiddenLeaf(nStartRow, NULL, &nEndRow);
3084 118 : if (nEndRow > nRow2)
3085 62 : nEndRow = nRow2;
3086 :
3087 118 : bool bChanged = ( bWasVis != bShow );
3088 :
3089 118 : SetRowHidden(nStartRow, nEndRow, !bShow);
3090 118 : SetRowFiltered(nStartRow, nEndRow, !bShow);
3091 :
3092 118 : if ( bChanged )
3093 : {
3094 62 : ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
3095 62 : if ( pCharts )
3096 62 : pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
3097 : }
3098 :
3099 118 : nStartRow = nEndRow + 1;
3100 : }
3101 :
3102 : // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
3103 : // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
3104 : // to be done here.
3105 92 : if (pOutlineTable)
3106 62 : UpdateOutlineRow( nRow1, nRow2, bShow );
3107 92 : }
3108 :
3109 102 : void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
3110 : {
3111 102 : SCROW nStartRow = nRow1;
3112 :
3113 : // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
3114 102 : ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
3115 102 : bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, nRow1, nRow2 );
3116 :
3117 312 : while (nStartRow <= nRow2)
3118 : {
3119 108 : SCROW nEndRow = -1;
3120 108 : bool bWasVis = !RowHiddenLeaf(nStartRow, NULL, &nEndRow);
3121 108 : if (nEndRow > nRow2)
3122 84 : nEndRow = nRow2;
3123 :
3124 108 : bool bChanged = ( bWasVis != bShow );
3125 :
3126 108 : SetRowHidden(nStartRow, nEndRow, !bShow);
3127 108 : if (bShow)
3128 52 : SetRowFiltered(nStartRow, nEndRow, false);
3129 :
3130 108 : if ( bChanged )
3131 : {
3132 78 : ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
3133 78 : if ( pCharts )
3134 78 : pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
3135 :
3136 78 : InvalidatePageBreaks();
3137 : }
3138 :
3139 108 : nStartRow = nEndRow + 1;
3140 : }
3141 :
3142 102 : if ( !bHasObjects )
3143 : {
3144 : // #i116164# set the flags for the whole range at once
3145 92 : SetRowHidden(nRow1, nRow2, !bShow);
3146 92 : if (bShow)
3147 42 : SetRowFiltered(nRow1, nRow2, false);
3148 : }
3149 102 : }
3150 :
3151 46 : bool ScTable::IsDataFiltered(SCCOL nColStart, SCROW nRowStart, SCCOL nColEnd, SCROW nRowEnd) const
3152 : {
3153 216 : for (SCROW i = nRowStart; i <= nRowEnd; ++i)
3154 : {
3155 174 : if (RowHidden(i))
3156 4 : return true;
3157 : }
3158 144 : for (SCCOL i = nColStart; i <= nColEnd; ++i)
3159 : {
3160 102 : if (ColHidden(i))
3161 0 : return true;
3162 : }
3163 42 : return false;
3164 : }
3165 :
3166 46 : bool ScTable::IsDataFiltered(const ScRange& rRange) const
3167 : {
3168 46 : return IsDataFiltered(rRange.aStart.Col(), rRange.aStart.Row(),
3169 92 : rRange.aEnd.Col(), rRange.aEnd.Row());
3170 : }
3171 :
3172 0 : void ScTable::SetRowFlags( SCROW nRow, sal_uInt8 nNewFlags )
3173 : {
3174 0 : if (ValidRow(nRow) && pRowFlags)
3175 0 : pRowFlags->SetValue( nRow, nNewFlags);
3176 : else
3177 : {
3178 : OSL_FAIL("Invalid row number or no flags");
3179 : }
3180 0 : }
3181 :
3182 22 : void ScTable::SetRowFlags( SCROW nStartRow, SCROW nEndRow, sal_uInt8 nNewFlags )
3183 : {
3184 22 : if (ValidRow(nStartRow) && ValidRow(nEndRow) && pRowFlags)
3185 22 : pRowFlags->SetValue( nStartRow, nEndRow, nNewFlags);
3186 : else
3187 : {
3188 : OSL_FAIL("Invalid row number(s) or no flags");
3189 : }
3190 22 : }
3191 :
3192 114632 : sal_uInt8 ScTable::GetColFlags( SCCOL nCol ) const
3193 : {
3194 114632 : if (ValidCol(nCol) && pColFlags)
3195 114632 : return pColFlags[nCol];
3196 : else
3197 0 : return 0;
3198 : }
3199 :
3200 4642 : sal_uInt8 ScTable::GetRowFlags( SCROW nRow ) const
3201 : {
3202 4642 : if (ValidRow(nRow) && pRowFlags)
3203 4642 : return pRowFlags->GetValue(nRow);
3204 : else
3205 0 : return 0;
3206 : }
3207 :
3208 180 : SCROW ScTable::GetLastFlaggedRow() const
3209 : {
3210 180 : SCROW nLastFound = 0;
3211 180 : if (pRowFlags)
3212 : {
3213 180 : SCROW nRow = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<sal_uInt8>(CR_ALL) );
3214 180 : if (ValidRow(nRow))
3215 16 : nLastFound = nRow;
3216 : }
3217 :
3218 180 : if (!maRowManualBreaks.empty())
3219 0 : nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin());
3220 :
3221 180 : if (mpHiddenRows)
3222 : {
3223 180 : SCROW nRow = mpHiddenRows->findLastNotOf(false);
3224 180 : if (ValidRow(nRow))
3225 4 : nLastFound = ::std::max(nLastFound, nRow);
3226 : }
3227 :
3228 180 : if (mpFilteredRows)
3229 : {
3230 180 : SCROW nRow = mpFilteredRows->findLastNotOf(false);
3231 180 : if (ValidRow(nRow))
3232 0 : nLastFound = ::std::max(nLastFound, nRow);
3233 : }
3234 :
3235 180 : return nLastFound;
3236 : }
3237 :
3238 56 : SCCOL ScTable::GetLastChangedCol() const
3239 : {
3240 56 : if ( !pColFlags )
3241 0 : return 0;
3242 :
3243 56 : SCCOL nLastFound = 0;
3244 57344 : for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
3245 57288 : if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH))
3246 8202 : nLastFound = nCol;
3247 :
3248 56 : return nLastFound;
3249 : }
3250 :
3251 56 : SCROW ScTable::GetLastChangedRow() const
3252 : {
3253 56 : if ( !pRowFlags )
3254 0 : return 0;
3255 :
3256 56 : SCROW nLastFlags = GetLastFlaggedRow();
3257 :
3258 : // Find the last row position where the height is NOT the standard row
3259 : // height.
3260 : // KOHEI: Test this to make sure it does what it's supposed to.
3261 56 : SCROW nLastHeight = mpRowHeights->findLastNotOf(ScGlobal::nStdRowHeight);
3262 56 : if (!ValidRow(nLastHeight))
3263 32 : nLastHeight = 0;
3264 :
3265 56 : return std::max( nLastFlags, nLastHeight);
3266 : }
3267 :
3268 2354 : bool ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, bool bShow )
3269 : {
3270 2354 : if (pOutlineTable && pColFlags)
3271 : {
3272 40 : ScBitMaskCompressedArray< SCCOLROW, sal_uInt8> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
3273 40 : return pOutlineTable->GetColArray().ManualAction( nStartCol, nEndCol, bShow, *this, true );
3274 : }
3275 : else
3276 2314 : return false;
3277 : }
3278 :
3279 120 : bool ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, bool bShow )
3280 : {
3281 120 : if (pOutlineTable && pRowFlags)
3282 82 : return pOutlineTable->GetRowArray().ManualAction( nStartRow, nEndRow, bShow, *this, false );
3283 : else
3284 38 : return false;
3285 : }
3286 :
3287 16398 : void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
3288 : {
3289 : // Column-wise expansion
3290 :
3291 32888 : while (rX1 > 0 && ColHidden(rX1-1))
3292 92 : --rX1;
3293 :
3294 32796 : while (rX2 < MAXCOL && ColHidden(rX2+1))
3295 0 : ++rX2;
3296 :
3297 : // Row-wise expansion
3298 :
3299 16398 : if (rY1 > 0)
3300 : {
3301 : ScFlatBoolRowSegments::RangeData aData;
3302 1302 : if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
3303 : {
3304 25 : SCROW nStartRow = aData.mnRow1;
3305 25 : if (ValidRow(nStartRow))
3306 25 : rY1 = nStartRow;
3307 : }
3308 : }
3309 16398 : if (rY2 < MAXROW)
3310 : {
3311 16398 : SCROW nEndRow = -1;
3312 16398 : if (RowHidden(rY2+1, NULL, &nEndRow) && ValidRow(nEndRow))
3313 6 : rY2 = nEndRow;
3314 : }
3315 16398 : }
3316 :
3317 16360 : void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
3318 : {
3319 32720 : while ( rX2>rX1 && ColHidden(rX2) )
3320 0 : --rX2;
3321 34000 : while ( rX2>rX1 && ColHidden(rX1) )
3322 1280 : ++rX1;
3323 :
3324 16360 : if (rY1 < rY2)
3325 : {
3326 : ScFlatBoolRowSegments::RangeData aData;
3327 16156 : if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
3328 : {
3329 6 : SCROW nStartRow = aData.mnRow1;
3330 6 : if (ValidRow(nStartRow) && nStartRow >= rY1)
3331 6 : rY2 = nStartRow;
3332 : }
3333 : }
3334 :
3335 16360 : if (rY1 < rY2)
3336 : {
3337 16156 : SCROW nEndRow = -1;
3338 16156 : if (RowHidden(rY1, NULL, &nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2)
3339 83 : rY1 = nEndRow;
3340 : }
3341 16360 : }
3342 :
3343 : // Auto-Outline
3344 :
3345 : template< typename T >
3346 16 : short DiffSign( T a, T b )
3347 : {
3348 : return (a<b) ? -1 :
3349 16 : (a>b) ? 1 : 0;
3350 : }
3351 :
3352 : namespace {
3353 :
3354 : class OutlineArrayFinder
3355 : {
3356 : ScRange maRef;
3357 : SCCOL mnCol;
3358 : SCTAB mnTab;
3359 : ScOutlineArray* mpArray;
3360 : bool mbSizeChanged;
3361 :
3362 : public:
3363 16 : OutlineArrayFinder(const ScRange& rRef, SCCOL nCol, SCTAB nTab, ScOutlineArray* pArray, bool bSizeChanged) :
3364 : maRef(rRef), mnCol(nCol), mnTab(nTab), mpArray(pArray),
3365 16 : mbSizeChanged(bSizeChanged) {}
3366 :
3367 8 : bool operator() (size_t nRow, const ScFormulaCell* pCell)
3368 : {
3369 8 : SCROW nRow2 = static_cast<SCROW>(nRow);
3370 :
3371 8 : if (!pCell->HasRefListExpressibleAsOneReference(maRef))
3372 0 : return false;
3373 :
3374 16 : if (maRef.aStart.Row() != nRow2 || maRef.aEnd.Row() != nRow2 ||
3375 8 : maRef.aStart.Tab() != mnTab || maRef.aEnd.Tab() != mnTab)
3376 8 : return false;
3377 :
3378 0 : if (DiffSign(maRef.aStart.Col(), mnCol) != DiffSign(maRef.aEnd.Col(), mnCol))
3379 0 : return false;
3380 :
3381 0 : return mpArray->Insert(maRef.aStart.Col(), maRef.aEnd.Col(), mbSizeChanged);
3382 : }
3383 : };
3384 :
3385 : }
3386 :
3387 4 : void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
3388 : {
3389 : typedef mdds::flat_segment_tree<SCROW, bool> UsedRowsType;
3390 :
3391 4 : bool bSizeChanged = false;
3392 :
3393 : SCCOL nCol;
3394 : SCROW nRow;
3395 : bool bFound;
3396 4 : ScRange aRef;
3397 :
3398 4 : StartOutlineTable();
3399 :
3400 : // Zeilen
3401 :
3402 4 : UsedRowsType aUsed(0, MAXROW+1, false);
3403 24 : for (nCol=nStartCol; nCol<=nEndCol; nCol++)
3404 20 : aCol[nCol].FindUsed(nStartRow, nEndRow, aUsed);
3405 4 : aUsed.build_tree();
3406 :
3407 4 : ScOutlineArray& rRowArray = pOutlineTable->GetRowArray();
3408 28 : for (nRow=nStartRow; nRow<=nEndRow; nRow++)
3409 : {
3410 24 : bool bUsed = false;
3411 24 : SCROW nLastRow = nRow;
3412 24 : aUsed.search_tree(nRow, bUsed, NULL, &nLastRow);
3413 24 : if (!bUsed)
3414 : {
3415 0 : nRow = nLastRow;
3416 0 : continue;
3417 : }
3418 :
3419 24 : bFound = false;
3420 140 : for (nCol=nStartCol; nCol<=nEndCol && !bFound; nCol++)
3421 : {
3422 116 : ScRefCellValue aCell = aCol[nCol].GetCellValue(nRow);
3423 :
3424 116 : if (aCell.meType != CELLTYPE_FORMULA)
3425 108 : continue;
3426 :
3427 8 : if (!aCell.mpFormula->HasRefListExpressibleAsOneReference(aRef))
3428 0 : continue;
3429 :
3430 32 : if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
3431 32 : aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
3432 8 : DiffSign( aRef.aStart.Row(), nRow ) ==
3433 8 : DiffSign( aRef.aEnd.Row(), nRow ) )
3434 : {
3435 8 : if (rRowArray.Insert( aRef.aStart.Row(), aRef.aEnd.Row(), bSizeChanged ))
3436 : {
3437 8 : bFound = true;
3438 : }
3439 : }
3440 8 : }
3441 : }
3442 :
3443 : // Column
3444 4 : ScOutlineArray& rColArray = pOutlineTable->GetColArray();
3445 24 : for (nCol=nStartCol; nCol<=nEndCol; nCol++)
3446 : {
3447 20 : if (aCol[nCol].IsEmptyData())
3448 4 : continue;
3449 :
3450 16 : OutlineArrayFinder aFunc(aRef, nCol, nTab, &rColArray, bSizeChanged);
3451 16 : sc::FindFormula(aCol[nCol].maCells, nStartRow, nEndRow, aFunc);
3452 4 : }
3453 4 : }
3454 :
3455 : // CopyData - fuer Query in anderen Bereich
3456 :
3457 0 : void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
3458 : SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab )
3459 : {
3460 : //! wenn fuer mehrere Zeilen benutzt, nach Spalten optimieren!
3461 :
3462 0 : ScAddress aSrc( nStartCol, nStartRow, nTab );
3463 0 : ScAddress aDest( nDestCol, nDestRow, nDestTab );
3464 0 : ScRange aRange( aSrc, aDest );
3465 0 : bool bThisTab = ( nDestTab == nTab );
3466 0 : SCROW nDestY = nDestRow;
3467 0 : for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
3468 : {
3469 0 : aSrc.SetRow( nRow );
3470 0 : aDest.SetRow( nDestY );
3471 0 : SCCOL nDestX = nDestCol;
3472 0 : for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
3473 : {
3474 0 : aSrc.SetCol( nCol );
3475 0 : aDest.SetCol( nDestX );
3476 0 : ScCellValue aCell;
3477 0 : aCell.assign(*pDocument, ScAddress(nCol, nRow, nTab));
3478 :
3479 0 : if (aCell.meType == CELLTYPE_FORMULA)
3480 : {
3481 0 : sc::RefUpdateContext aCxt(*pDocument);
3482 0 : aCxt.meMode = URM_COPY;
3483 0 : aCxt.maRange = aRange;
3484 0 : aCxt.mnColDelta = nDestCol - nStartCol;
3485 0 : aCxt.mnRowDelta = nDestRow - nStartRow;
3486 0 : aCxt.mnTabDelta = nDestTab - nTab;
3487 0 : aCell.mpFormula->UpdateReference(aCxt);
3488 0 : aCell.mpFormula->aPos = aDest;
3489 : }
3490 :
3491 0 : if (bThisTab)
3492 : {
3493 0 : aCell.release(aCol[nDestX], nDestY);
3494 0 : SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ), true );
3495 : }
3496 : else
3497 : {
3498 0 : aCell.release(*pDocument, aDest);
3499 0 : pDocument->SetPattern( aDest, *GetPattern( nCol, nRow ), true );
3500 : }
3501 :
3502 0 : ++nDestX;
3503 0 : }
3504 0 : ++nDestY;
3505 : }
3506 0 : }
3507 :
3508 0 : bool ScTable::RefVisible(ScFormulaCell* pCell)
3509 : {
3510 0 : ScRange aRef;
3511 :
3512 0 : if (pCell->HasOneReference(aRef))
3513 : {
3514 0 : if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
3515 : {
3516 : SCROW nEndRow;
3517 0 : if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow))
3518 : // row not filtered.
3519 0 : nEndRow = ::std::numeric_limits<SCROW>::max();
3520 :
3521 0 : if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
3522 0 : return true; // at least partly visible
3523 0 : return false; // completely invisible
3524 : }
3525 : }
3526 :
3527 0 : return true; // irgendwie anders
3528 : }
3529 :
3530 24 : void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, OUString& rStr)
3531 : {
3532 24 : GetInputString(nCol, nRow, rStr);
3533 24 : rStr = ScGlobal::pCharClass->uppercase(rStr.trim());
3534 24 : }
3535 :
3536 : // Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
3537 :
3538 7008 : void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos)
3539 : {
3540 7008 : ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
3541 7008 : if( pDrawLayer )
3542 : {
3543 5026 : double fValX = GetColOffset( MAXCOL + 1 ) * HMM_PER_TWIPS;
3544 5026 : double fValY = GetRowOffset( MAXROW + 1 ) * HMM_PER_TWIPS;
3545 5026 : const long nMax = ::std::numeric_limits<long>::max();
3546 : // #i113884# Avoid int32 overflow with possible negative results than can cause bad effects.
3547 : // If the draw page size is smaller than all rows, only the bottom of the sheet is affected.
3548 5026 : long x = ( fValX > (double)nMax ) ? nMax : (long) fValX;
3549 5026 : long y = ( fValY > (double)nMax ) ? nMax : (long) fValY;
3550 :
3551 5026 : if ( IsLayoutRTL() ) // IsNegativePage
3552 4 : x = -x;
3553 :
3554 5026 : pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ), bUpdateNoteCaptionPos );
3555 : }
3556 :
3557 : // #i102616# actions that modify the draw page size count as sheet modification
3558 : // (exception: InitDrawLayer)
3559 7008 : if (bResetStreamValid && IsStreamValid())
3560 0 : SetStreamValid(false);
3561 7008 : }
3562 :
3563 2 : void ScTable::SetRangeName(ScRangeName* pNew)
3564 : {
3565 2 : delete mpRangeName;
3566 2 : mpRangeName = pNew;
3567 :
3568 : //fdo#39792: mark stream as invalid, otherwise new ScRangeName will not be written to file
3569 2 : if (IsStreamValid())
3570 0 : SetStreamValid(false);
3571 2 : }
3572 :
3573 3786 : ScRangeName* ScTable::GetRangeName() const
3574 : {
3575 3786 : if (!mpRangeName)
3576 954 : mpRangeName = new ScRangeName;
3577 3786 : return mpRangeName;
3578 : }
3579 :
3580 7638 : sal_uLong ScTable::GetRowOffset( SCROW nRow, bool bHiddenAsZero ) const
3581 : {
3582 7638 : sal_uLong n = 0;
3583 7638 : if ( mpHiddenRows && mpRowHeights )
3584 : {
3585 7638 : if (nRow == 0)
3586 380 : return 0;
3587 7258 : else if (nRow == 1)
3588 230 : return GetRowHeight(0, NULL, NULL, bHiddenAsZero );
3589 :
3590 7028 : n = GetTotalRowHeight(0, nRow-1, bHiddenAsZero);
3591 : #if OSL_DEBUG_LEVEL > 0
3592 : if (n == ::std::numeric_limits<unsigned long>::max())
3593 : OSL_FAIL("ScTable::GetRowOffset: row heights overflow");
3594 : #endif
3595 : }
3596 : else
3597 : {
3598 : OSL_FAIL("GetRowOffset: Data missing");
3599 : }
3600 7028 : return n;
3601 : }
3602 :
3603 3992 : SCROW ScTable::GetRowForHeight(sal_uLong nHeight) const
3604 : {
3605 3992 : sal_uInt32 nSum = 0;
3606 :
3607 : ScFlatBoolRowSegments::RangeData aData;
3608 12624776 : for (SCROW nRow = 0; nRow <= MAXROW; ++nRow)
3609 : {
3610 12624764 : if (!mpHiddenRows->getRangeData(nRow, aData))
3611 0 : break;
3612 :
3613 12624764 : if (aData.mbValue)
3614 : {
3615 0 : nRow = aData.mnRow2;
3616 0 : continue;
3617 : }
3618 :
3619 12624764 : sal_uInt32 nNew = mpRowHeights->getValue(nRow);
3620 12624764 : nSum += nNew;
3621 12624764 : if (nSum > nHeight)
3622 : {
3623 3980 : return nRow < MAXROW ? nRow + 1 : MAXROW;
3624 : }
3625 : }
3626 12 : return -1;
3627 : }
3628 :
3629 7638 : sal_uLong ScTable::GetColOffset( SCCOL nCol, bool bHiddenAsZero ) const
3630 : {
3631 7638 : sal_uLong n = 0;
3632 7638 : if ( pColWidth )
3633 : {
3634 : SCCOL i;
3635 5163456 : for( i = 0; i < nCol; i++ )
3636 5155818 : if (!( bHiddenAsZero && ColHidden(i) ))
3637 5154008 : n += pColWidth[i];
3638 : }
3639 : else
3640 : {
3641 : OSL_FAIL("GetColumnOffset: Data missing");
3642 : }
3643 7638 : return n;
3644 228 : }
3645 :
3646 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|