LibreOffice Module sc (master) 1
dociter.cxx
Go to the documentation of this file.
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 <svl/numformat.hxx>
21#include <svl/zforlist.hxx>
22
23#include <global.hxx>
24#include <dociter.hxx>
25#include <document.hxx>
26#include <table.hxx>
27#include <column.hxx>
28#include <formulacell.hxx>
29#include <attarray.hxx>
30#include <patattr.hxx>
31#include <docoptio.hxx>
32#include <cellform.hxx>
33#include <segmenttree.hxx>
34#include <progress.hxx>
35#include <queryparam.hxx>
36#include <queryentry.hxx>
37#include <globstr.hrc>
38#include <scresid.hxx>
39#include <cellvalue.hxx>
40#include <scmatrix.hxx>
41#include <rowheightcontext.hxx>
42#include <queryevaluator.hxx>
43
44#include <o3tl/safeint.hxx>
45#include <tools/fract.hxx>
46#include <editeng/editobj.hxx>
47#include <svl/sharedstring.hxx>
49#include <osl/diagnose.h>
50#include <sal/log.hxx>
51
52#include <algorithm>
53#include <limits>
54#include <vector>
55
56using ::rtl::math::approxEqual;
57using ::std::vector;
58using ::std::set;
59
60// iterators have very high frequency use -> custom debug.
61// #define debugiter(...) fprintf(stderr, __VA_ARGS__)
62#define debugiter(...)
63
64static void ScAttrArray_IterGetNumberFormat( sal_uInt32& nFormat, const ScAttrArray*& rpArr,
65 SCROW& nAttrEndRow, const ScAttrArray* pNewArr, SCROW nRow,
66 const ScDocument& rDoc, const ScInterpreterContext* pContext = nullptr )
67{
68 if ( rpArr == pNewArr && nAttrEndRow >= nRow )
69 return;
70
71 SCROW nRowStart = 0;
72 SCROW nRowEnd = rDoc.MaxRow();
73 const ScPatternAttr* pPattern = pNewArr->GetPatternRange( nRowStart, nRowEnd, nRow );
74 if( !pPattern )
75 {
76 pPattern = rDoc.GetDefPattern();
77 nRowEnd = rDoc.MaxRow();
78 }
79
80 nFormat = pPattern->GetNumberFormat( pContext ? pContext->GetFormatTable() : rDoc.GetFormatTable() );
81 rpArr = pNewArr;
82 nAttrEndRow = nRowEnd;
83}
84
86 SubtotalFlags nSubTotalFlags, bool bTextZero )
87 : mrDoc(*rContext.mpDoc)
88 , mrContext(rContext)
89 , pAttrArray(nullptr)
90 , nNumFormat(0) // Initialized in GetNumberFormat
91 , nNumFmtIndex(0)
92 , maStartPos(rRange.aStart)
93 , maEndPos(rRange.aEnd)
94 , mnCol(0)
95 , mnTab(0)
96 , nAttrEndRow(0)
97 , mnSubTotalFlags(nSubTotalFlags)
98 , nNumFmtType(SvNumFormatType::UNDEFINED)
99 , bNumValid(false)
100 , bCalcAsShown((*rContext.mpDoc).GetDocOptions().IsCalcAsShown())
101 , bTextAsZero(bTextZero)
102 , mpCells(nullptr)
103{
104 SCTAB nDocMaxTab = mrDoc.GetTableCount() - 1;
105
110 if (!ValidTab(maStartPos.Tab()) || maStartPos.Tab() > nDocMaxTab) maStartPos.SetTab(nDocMaxTab);
111 if (!ValidTab(maEndPos.Tab()) || maEndPos.Tab() > nDocMaxTab) maEndPos.SetTab(nDocMaxTab);
112}
113
115{
116 // Position of the head of the current block + offset within the block
117 // equals the logical element position.
118 return maCurPos.first->position + maCurPos.second;
119}
120
122{
123 ++maCurPos.first;
124 maCurPos.second = 0;
125}
126
128{
129 if (maCurPos.second + 1 < maCurPos.first->size)
130 // Move within the same block.
131 ++maCurPos.second;
132 else
133 // Move to the next block.
134 IncBlock();
135}
136
137bool ScValueIterator::GetThis(double& rValue, FormulaError& rErr)
138{
139 while (true)
140 {
141 bool bNextColumn = !mpCells || maCurPos.first == mpCells->end();
142 if (!bNextColumn)
143 {
144 if (GetRow() > maEndPos.Row())
145 bNextColumn = true;
146 }
147
148 ScColumn* pCol;
149 if (!bNextColumn)
150 pCol = &(mrDoc.maTabs[mnTab])->aCol[mnCol];
151 else
152 {
153 // Find the next available column.
154 do
155 {
156 ++mnCol;
157 while (mnCol > maEndPos.Col() || mnCol >= mrDoc.maTabs[mnTab]->GetAllocatedColumnsCount())
158 {
159 mnCol = maStartPos.Col();
160 ++mnTab;
161 if (mnTab > maEndPos.Tab())
162 {
163 rErr = FormulaError::NONE;
164 return false;
165 }
166 }
167 pCol = &(mrDoc.maTabs[mnTab])->aCol[mnCol];
168 }
169 while (pCol->IsEmptyData());
170
171 mpCells = &pCol->maCells;
172 maCurPos = mpCells->position(maStartPos.Row());
173 }
174
175 SCROW nCurRow = GetRow();
176 SCROW nLastRow;
177 // Skip all filtered or hidden rows, depending on mnSubTotalFlags
179 mrDoc.RowFiltered( nCurRow, mnTab, nullptr, &nLastRow ) ) ||
181 mrDoc.RowHidden( nCurRow, mnTab, nullptr, &nLastRow ) ) )
182 {
183 maCurPos = mpCells->position(maCurPos.first, nLastRow+1);
184 continue;
185 }
186
187 switch (maCurPos.first->type)
188 {
190 {
191 bNumValid = false;
192 rValue = sc::numeric_block::at(*maCurPos.first->data, maCurPos.second);
193 rErr = FormulaError::NONE;
194 if (bCalcAsShown)
195 {
197 nAttrEndRow, pCol->pAttrArray.get(), nCurRow, mrDoc, &mrContext);
198 rValue = mrDoc.RoundValueAsShown(rValue, nNumFormat, &mrContext);
199 }
200 return true; // Found it!
201 }
202 break;
204 {
205 ScFormulaCell& rCell = *sc::formula_block::at(*maCurPos.first->data, maCurPos.second);
207 {
208 // Skip subtotal formula cells.
209 IncPos();
210 break;
211 }
212
213 if (rCell.GetErrorOrValue(rErr, rValue))
214 {
215 if ( rErr != FormulaError::NONE && ( mnSubTotalFlags & SubtotalFlags::IgnoreErrVal ) )
216 {
217 IncPos();
218 break;
219 }
220 bNumValid = false;
221 return true; // Found it!
222 }
223 else if (bTextAsZero)
224 {
225 rValue = 0.0;
226 bNumValid = false;
227 return true;
228 }
229 IncPos();
230 }
231 break;
234 {
235 if (bTextAsZero)
236 {
237 rErr = FormulaError::NONE;
238 rValue = 0.0;
239 nNumFmtType = SvNumFormatType::NUMBER;
240 nNumFmtIndex = 0;
241 bNumValid = true;
242 return true;
243 }
244 IncBlock();
245 }
246 break;
248 default:
249 // Skip the whole block.
250 IncBlock();
251 }
252 }
253}
254
256{
258 {
259 SCROW nCurRow = GetRow();
260 const ScColumn* pCol = &(mrDoc.maTabs[mnTab])->aCol[mnCol];
261 nNumFmtIndex = pCol->GetNumberFormat(mrContext, nCurRow);
263 bNumValid = true;
264 }
265
268}
269
270bool ScValueIterator::GetFirst(double& rValue, FormulaError& rErr)
271{
272 mnCol = maStartPos.Col();
273 mnTab = maStartPos.Tab();
274
275 const ScTable* pTab = mrDoc.FetchTable(mnTab);
276 if (!pTab)
277 return false;
278
279 nNumFormat = 0; // Initialized in GetNumberFormat
280 pAttrArray = nullptr;
281 nAttrEndRow = 0;
282
283 auto nCol = maStartPos.Col();
284 if (nCol < pTab->GetAllocatedColumnsCount())
285 {
286 mpCells = &pTab->aCol[nCol].maCells;
287 maCurPos = mpCells->position(maStartPos.Row());
288 }
289 else
290 mpCells = nullptr;
291 return GetThis(rValue, rErr);
292}
293
294bool ScValueIterator::GetNext(double& rValue, FormulaError& rErr)
295{
296 IncPos();
297 return GetThis(rValue, rErr);
298}
299
301{
302}
303
305{
306}
307
309{
310 ScTable* pTab = rDoc.FetchTable(nTab);
311 if (!pTab)
312 return nullptr;
313 if (nCol >= pTab->GetAllocatedColumnsCount())
314 return nullptr;
315 return &pTab->aCol[nCol].maCells;
316}
317
319{
320 assert(nTab < rDoc.GetTableCount() && "index out of bounds, FIX IT");
321 ScColumn* pCol = &rDoc.maTabs[nTab]->aCol[nCol];
322 return pCol->pAttrArray.get();
323}
324
326 ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, const ScRefCellValue* pCell)
327{
328 assert(nTab < rDoc.GetTableCount() && "index out of bounds, FIX IT");
329 ScQueryEvaluator queryEvaluator(rDoc, *rDoc.maTabs[nTab], rParam);
330 return queryEvaluator.ValidQuery(nRow, pCell);
331}
332
334 : mpCells(nullptr)
335 , mpParam(pParam)
336 , mrDoc(rDoc)
337 , mrContext(rContext)
338 , pAttrArray(nullptr)
339 , nNumFormat(0) // Initialized in GetNumberFormat
340 , nNumFmtIndex(0)
341 , nCol(mpParam->mnField)
342 , nRow(mpParam->nRow1)
343 , nAttrEndRow(0)
344 , nTab(mpParam->nTab)
345 , nNumFmtType(SvNumFormatType::ALL)
346 , bCalcAsShown(rDoc.GetDocOptions().IsCalcAsShown())
347{
348 SCSIZE i;
350 for (i=0; (i<nCount) && (mpParam->GetEntry(i).bDoQuery); i++)
351 {
352 ScQueryEntry& rEntry = mpParam->GetEntry(i);
354 rItems.resize(1);
355 ScQueryEntry::Item& rItem = rItems.front();
356 sal_uInt32 nIndex = 0;
357 bool bNumber = mrDoc.GetFormatTable()->IsNumberFormat(
358 rItem.maString.getString(), nIndex, rItem.mfVal);
360 }
361}
362
364{
365}
366
368{
369 // Start with the current row position, and find the first row position
370 // that satisfies the query.
371
372 // If the query starts in the same column as the result vector we can
373 // prefetch the cell which saves us one fetch in the success case.
374 SCCOLROW nFirstQueryField = mpParam->GetEntry(0).nField;
375 ScRefCellValue aCell;
376
377 while (true)
378 {
379 if (maCurPos.first == mpCells->end() || nRow > mpParam->nRow2)
380 {
381 // Bottom of the range reached. Bail out.
382 rValue.mnError = FormulaError::NONE;
383 return false;
384 }
385
386 if (maCurPos.first->type == sc::element_type_empty)
387 {
388 // Skip the whole empty block.
389 incBlock();
390 continue;
391 }
392
393 ScRefCellValue* pCell = nullptr;
394 if (nCol == static_cast<SCCOL>(nFirstQueryField))
395 {
396 aCell = sc::toRefCell(maCurPos.first, maCurPos.second);
397 pCell = &aCell;
398 }
399
400 if (ScDBQueryDataIterator::IsQueryValid(mrDoc, *mpParam, nTab, nRow, pCell))
401 {
402 if (!pCell)
403 aCell = sc::toRefCell(maCurPos.first, maCurPos.second);
404 switch (aCell.getType())
405 {
406 case CELLTYPE_VALUE:
407 {
408 rValue.mfValue = aCell.getDouble();
409 rValue.mbIsNumber = true;
410 if ( bCalcAsShown )
411 {
412 const ScAttrArray* pNewAttrArray =
414 ScAttrArray_IterGetNumberFormat( nNumFormat, pAttrArray,
415 nAttrEndRow, pNewAttrArray, nRow, mrDoc );
416 rValue.mfValue = mrDoc.RoundValueAsShown( rValue.mfValue, nNumFormat );
417 }
418 nNumFmtType = SvNumFormatType::NUMBER;
419 nNumFmtIndex = 0;
420 rValue.mnError = FormulaError::NONE;
421 return true; // Found it!
422 }
423
424 case CELLTYPE_FORMULA:
425 {
426 if (aCell.getFormula()->IsValue())
427 {
428 rValue.mfValue = aCell.getFormula()->GetValue();
429 rValue.mbIsNumber = true;
430 mrDoc.GetNumberFormatInfo(
431 mrContext, nNumFmtType, nNumFmtIndex, ScAddress(nCol, nRow, nTab));
432 rValue.mnError = aCell.getFormula()->GetErrCode();
433 return true; // Found it!
434 }
435 else if(mpParam->mbSkipString)
436 incPos();
437 else
438 {
439 rValue.maString = aCell.getFormula()->GetString().getString();
440 rValue.mfValue = 0.0;
441 rValue.mnError = aCell.getFormula()->GetErrCode();
442 rValue.mbIsNumber = false;
443 return true;
444 }
445 }
446 break;
447 case CELLTYPE_STRING:
448 case CELLTYPE_EDIT:
449 if (mpParam->mbSkipString)
450 incPos();
451 else
452 {
453 rValue.maString = aCell.getString(&mrDoc);
454 rValue.mfValue = 0.0;
455 rValue.mnError = FormulaError::NONE;
456 rValue.mbIsNumber = false;
457 return true;
458 }
459 break;
460 default:
461 incPos();
462 }
463 }
464 else
465 incPos();
466 }
467// statement unreachable
468}
469
471{
472 if (mpParam->bHasHeader)
473 ++nRow;
474
475 mpCells = ScDBQueryDataIterator::GetColumnCellStore(mrDoc, nTab, nCol);
476 if (!mpCells)
477 return false;
478
479 maCurPos = mpCells->position(nRow);
480 return getCurrent(rValue);
481}
482
484{
485 if (!mpCells || maCurPos.first == mpCells->end())
486 return false;
487
488 incPos();
489 return getCurrent(rValue);
490}
491
493{
494 ++maCurPos.first;
495 maCurPos.second = 0;
496
497 nRow = maCurPos.first->position;
498}
499
501{
502 if (maCurPos.second + 1 < maCurPos.first->size)
503 {
504 // Move within the same block.
505 ++maCurPos.second;
506 ++nRow;
507 }
508 else
509 // Move to the next block.
510 incBlock();
511}
512
514 : mpParam(pParam)
515 , mnCurRow(0)
516{
517 SCSIZE nC, nR;
518 mpParam->mpMatrix->GetDimensions(nC, nR);
519 mnRows = static_cast<SCROW>(nR);
520}
521
523{
524}
525
527{
528 // Starting from row == mnCurRow, get the first row that satisfies all the
529 // query parameters.
530 for ( ;mnCurRow < mnRows; ++mnCurRow)
531 {
532 const ScMatrix& rMat = *mpParam->mpMatrix;
533 if (rMat.IsEmpty(mpParam->mnField, mnCurRow))
534 // Don't take empty values into account.
535 continue;
536
537 bool bIsStrVal = rMat.IsStringOrEmpty(mpParam->mnField, mnCurRow);
538 if (bIsStrVal && mpParam->mbSkipString)
539 continue;
540
541 if (isValidQuery(mnCurRow, rMat))
542 {
543 rValue.maString = rMat.GetString(mpParam->mnField, mnCurRow).getString();
544 rValue.mfValue = rMat.GetDouble(mpParam->mnField, mnCurRow);
545 rValue.mbIsNumber = !bIsStrVal;
546 rValue.mnError = FormulaError::NONE;
547 return true;
548 }
549 }
550 return false;
551}
552
554{
555 mnCurRow = mpParam->bHasHeader ? 1 : 0;
556 return getCurrent(rValue);
557}
558
560{
561 ++mnCurRow;
562 return getCurrent(rValue);
563}
564
565namespace {
566
567bool isQueryByValue(const ScQueryEntry::Item& rItem, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
568{
569 if (rItem.meType == ScQueryEntry::ByString)
570 return false;
571
572 if (!rMat.IsValueOrEmpty(nCol, nRow))
573 return false;
574
575 return true;
576}
577
578bool isQueryByString(const ScQueryEntry& rEntry, const ScQueryEntry::Item& rItem, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
579{
580 switch (rEntry.eOp)
581 {
582 case SC_EQUAL:
583 case SC_NOT_EQUAL:
584 case SC_CONTAINS:
586 case SC_BEGINS_WITH:
587 case SC_ENDS_WITH:
590 return true;
591 default:
592 ;
593 }
594
595 return rItem.meType == ScQueryEntry::ByString && rMat.IsStringOrEmpty(nCol, nRow);
596}
597
598}
599
601{
602 SCSIZE nEntryCount = mpParam->GetEntryCount();
603 vector<bool> aResults;
604 aResults.reserve(nEntryCount);
605
606 const CollatorWrapper& rCollator = ScGlobal::GetCollator(mpParam->bCaseSens);
607
608 for (SCSIZE i = 0; i < nEntryCount; ++i)
609 {
610 const ScQueryEntry& rEntry = mpParam->GetEntry(i);
611 const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
612 if (!rEntry.bDoQuery)
613 continue;
614
615 switch (rEntry.eOp)
616 {
617 case SC_EQUAL:
618 case SC_LESS:
619 case SC_GREATER:
620 case SC_LESS_EQUAL:
621 case SC_GREATER_EQUAL:
622 case SC_NOT_EQUAL:
623 break;
624 default:
625 // Only the above operators are supported.
626 SAL_WARN("sc.core", "Unsupported operator " << rEntry.eOp
627 << " in ScDBQueryDataIterator::DataAccessMatrix::isValidQuery()");
628 continue;
629 }
630
631 bool bValid = false;
632
633 SCSIZE nField = static_cast<SCSIZE>(rEntry.nField);
634 if (isQueryByValue(rItem, rMat, nField, nRow))
635 {
636 // By value
637 double fMatVal = rMat.GetDouble(nField, nRow);
638 bool bEqual = approxEqual(fMatVal, rItem.mfVal);
639 switch (rEntry.eOp)
640 {
641 case SC_EQUAL:
642 bValid = bEqual;
643 break;
644 case SC_LESS:
645 bValid = (fMatVal < rItem.mfVal) && !bEqual;
646 break;
647 case SC_GREATER:
648 bValid = (fMatVal > rItem.mfVal) && !bEqual;
649 break;
650 case SC_LESS_EQUAL:
651 bValid = (fMatVal < rItem.mfVal) || bEqual;
652 break;
653 case SC_GREATER_EQUAL:
654 bValid = (fMatVal > rItem.mfVal) || bEqual;
655 break;
656 case SC_NOT_EQUAL:
657 bValid = !bEqual;
658 break;
659 default:
660 ;
661 }
662 }
663 else if (isQueryByString(rEntry, rItem, rMat, nField, nRow))
664 {
665 // By string
666 do
667 {
668 // Equality check first.
669 svl::SharedString aMatStr = rMat.GetString(nField, nRow);
670 svl::SharedString aQueryStr = rEntry.GetQueryItem().maString;
671 bool bDone = false;
672 rtl_uString* p1 = mpParam->bCaseSens ? aMatStr.getData() : aMatStr.getDataIgnoreCase();
673 rtl_uString* p2 = mpParam->bCaseSens ? aQueryStr.getData() : aQueryStr.getDataIgnoreCase();
674 switch (rEntry.eOp)
675 {
676 case SC_EQUAL:
677 bValid = (p1 == p2);
678 bDone = true;
679 break;
680 case SC_NOT_EQUAL:
681 bValid = (p1 != p2);
682 bDone = true;
683 break;
684 default:
685 ;
686 }
687
688 if (bDone)
689 break;
690
691 // Unequality check using collator.
692 sal_Int32 nCompare = rCollator.compareString(aMatStr.getString(), aQueryStr.getString());
693 switch (rEntry.eOp)
694 {
695 case SC_LESS :
696 bValid = (nCompare < 0);
697 break;
698 case SC_GREATER :
699 bValid = (nCompare > 0);
700 break;
701 case SC_LESS_EQUAL :
702 bValid = (nCompare <= 0);
703 break;
704 case SC_GREATER_EQUAL :
705 bValid = (nCompare >= 0);
706 break;
707 default:
708 ;
709 }
710 }
711 while (false);
712 }
713
714 if (aResults.empty())
715 // First query entry.
716 aResults.push_back(bValid);
717 else if (rEntry.eConnect == SC_AND)
718 {
719 // For AND op, tuck the result into the last result value.
720 size_t n = aResults.size();
721 aResults[n-1] = aResults[n-1] && bValid;
722 }
723 else
724 // For OR op, store its own result.
725 aResults.push_back(bValid);
726 }
727
728 // Row is valid as long as there is at least one result being true.
729 return std::find(aResults.begin(), aResults.end(), true) != aResults.end();
730}
731
733 : mfValue(std::numeric_limits<double>::quiet_NaN())
734 , mnError(FormulaError::NONE), mbIsNumber(true)
735{
736}
737
738ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument& rDocument, const ScInterpreterContext& rContext, std::unique_ptr<ScDBQueryParamBase> pParam) :
739 mpParam (std::move(pParam))
740{
741 switch (mpParam->GetType())
742 {
744 {
746 mpData.reset(new DataAccessInternal(p, rDocument, rContext));
747 }
748 break;
750 {
751 ScDBQueryParamMatrix* p = static_cast<ScDBQueryParamMatrix*>(mpParam.get());
752 mpData.reset(new DataAccessMatrix(p));
753 }
754 }
755}
756
758{
759 return mpData->getFirst(rValue);
760}
761
763{
764 return mpData->getNext(rValue);
765}
766
768 mrDoc(rDoc),
769 mnTab(0),
770 mnCol(0),
771 mnIndex(0)
772{
773 ScTable *pTab = mrDoc.FetchTable(mnTab);
774 ScColumn *pCol = pTab ? pTab->FetchColumn(mnCol) : nullptr;
775 if (pCol)
776 {
777 mbNullCol = false;
779 }
780 else
781 mbNullCol = true;
782}
783
785{
786 return next();
787}
788
790{
791 if (mnIndex >= maEntries.size() || mbNullCol)
792 {
793 while (mnIndex >= maEntries.size() || mbNullCol)
794 {
795 mnIndex = 0;
796 mnCol++;
797 if (mnCol > mrDoc.MaxCol())
798 {
799 mnCol = 0;
800 mnTab++;
801 if (mnTab >= mrDoc.GetTableCount())
802 return nullptr;
803 }
804 ScTable *pTab = mrDoc.FetchTable(mnTab);
805 ScColumn *pCol = pTab ? pTab->FetchColumn(mnCol) : nullptr;
806 if (pCol)
807 {
808 mbNullCol = false;
810 }
811 else
812 mbNullCol = true;
813 }
814 }
815
816 return &maEntries[mnIndex++];
817}
818
819ScCellIterator::ScCellIterator( ScDocument& rDoc, const ScRange& rRange, SubtotalFlags nSubTotalFlags ) :
820 mrDoc(rDoc),
821 maStartPos(rRange.aStart),
822 maEndPos(rRange.aEnd),
823 mnSubTotalFlags(nSubTotalFlags)
824{
825 init();
826}
827
829{
830 ++maCurColPos.first;
831 maCurColPos.second = 0;
832
833 maCurPos.SetRow(maCurColPos.first->position);
834}
835
837{
838 if (maCurColPos.second + 1 < maCurColPos.first->size)
839 {
840 // Move within the same block.
841 ++maCurColPos.second;
843 }
844 else
845 // Move to the next block.
846 incBlock();
847}
848
849void ScCellIterator::setPos(size_t nPos)
850{
851 maCurColPos = getColumn()->maCells.position(maCurColPos.first, nPos);
853}
854
856{
857 return &mrDoc.maTabs[maCurPos.Tab()]->aCol[maCurPos.Col()];
858}
859
861{
862 SCTAB nDocMaxTab = mrDoc.GetTableCount() - 1;
863
865
870 if (!ValidTab(maStartPos.Tab(), nDocMaxTab)) maStartPos.SetTab(nDocMaxTab);
871 if (!ValidTab(maEndPos.Tab(), nDocMaxTab)) maEndPos.SetTab(nDocMaxTab);
872
873 while (maEndPos.Tab() > 0 && !mrDoc.maTabs[maEndPos.Tab()])
874 maEndPos.IncTab(-1); // Only the tables in use
875
876 if (maStartPos.Tab() > maEndPos.Tab())
878
879 if (!mrDoc.maTabs[maStartPos.Tab()])
880 {
881 assert(!"Table not found");
882 maStartPos = ScAddress(mrDoc.MaxCol()+1, mrDoc.MaxRow()+1, MAXTAB+1); // -> Abort on GetFirst.
883 }
884 else
885 {
886 maStartPos.SetCol(mrDoc.maTabs[maStartPos.Tab()]->ClampToAllocatedColumns(maStartPos.Col()));
887 }
888
890}
891
893{
894 const ScColumn* pCol = getColumn();
895
896 while (true)
897 {
898 bool bNextColumn = maCurColPos.first == pCol->maCells.end();
899 if (!bNextColumn)
900 {
901 if (maCurPos.Row() > maEndPos.Row())
902 bNextColumn = true;
903 }
904
905 if (bNextColumn)
906 {
907 // Move to the next column.
909 do
910 {
913 || maCurPos.Col() > maEndPos.Col())
914 {
917 if (maCurPos.Tab() > maEndPos.Tab())
918 {
920 return false;
921 }
922 }
923 pCol = getColumn();
924 }
925 while (pCol->IsEmptyData());
926
927 maCurColPos = pCol->maCells.position(maCurPos.Row());
928 }
929
930 if (maCurColPos.first->type == sc::element_type_empty)
931 {
932 incBlock();
933 continue;
934 }
935
936 SCROW nLastRow;
937 // Skip all filtered or hidden rows, depending on mSubTotalFlags
939 pCol->GetDoc().RowFiltered(maCurPos.Row(), maCurPos.Tab(), nullptr, &nLastRow) ) ||
941 pCol->GetDoc().RowHidden(maCurPos.Row(), maCurPos.Tab(), nullptr, &nLastRow) ) )
942 {
943 setPos(nLastRow+1);
944 continue;
945 }
946
947 if (maCurColPos.first->type == sc::element_type_formula)
948 {
950 {
951 ScFormulaCell* pCell = sc::formula_block::at(*maCurColPos.first->data, maCurColPos.second);
952 // Skip formula cells with Subtotal formulae or errors, depending on mnSubTotalFlags
954 ( ( mnSubTotalFlags & SubtotalFlags::IgnoreErrVal ) && pCell->GetErrCode() != FormulaError::NONE ) )
955 {
956 incPos();
957 continue;
958 }
959 }
960 }
961
963 return true;
964 }
965 return false;
966}
967
969{
970 return maCurCell.getString(&mrDoc);
971}
972
974{
975 switch (maCurCell.getType())
976 {
977 case CELLTYPE_STRING:
979 break;
980 case CELLTYPE_EDIT:
982 break;
983 case CELLTYPE_VALUE:
985 break;
986 case CELLTYPE_FORMULA:
988 break;
989 default:
990 return ScCellValue();
991 }
992}
993
995{
996 return maCurCell.hasString();
997}
998
1000{
1001 return maCurCell.isEmpty();
1002}
1003
1005{
1006 ScRefCellValue aOther(mrDoc, rPos);
1007 return maCurCell.equalsWithoutFormat(aOther);
1008}
1009
1011{
1012 if (!ValidTab(maCurPos.Tab()))
1013 return false;
1014
1016 const ScColumn* pCol = getColumn();
1017
1018 maCurColPos = pCol->maCells.position(maCurPos.Row());
1019 return getCurrent();
1020}
1021
1023{
1024 incPos();
1025 return getCurrent();
1026}
1027
1029 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
1030 rDoc( rDocument ),
1031 mnTab( nTable ),
1032 nStartCol( nCol1 ),
1033 nEndCol( nCol2 ),
1034 nStartRow( nRow1 ),
1035 nEndRow( nRow2 ),
1036 mnCol( nCol1 ),
1037 mnRow( nRow1 ),
1038 mbMore( false )
1039{
1040 assert(mnTab < rDoc.GetTableCount() && "index out of bounds, FIX IT");
1041
1042 const ScTable* pTab = rDoc.FetchTable(mnTab);
1043 if (!pTab)
1044 return;
1045
1047 if (nEndCol < nStartCol) // E.g., somewhere completely outside allocated area
1048 nEndCol = nStartCol - 1; // Empty
1049
1050 maColPositions.reserve( nEndCol-nStartCol+1 );
1051
1052 SetTab( mnTab );
1053}
1054
1056{
1057}
1058
1060{
1061 mbMore = false;
1062 mnTab = nTabP;
1063 mnRow = nStartRow;
1064 mnCol = nStartCol;
1065 maColPositions.resize(0);
1066
1067 // Set the start position in each column.
1068 for (SCCOL i = nStartCol; i <= nEndCol; ++i)
1069 {
1070 ScColumn* pCol = &rDoc.maTabs[mnTab]->aCol[i];
1071 ColParam aParam;
1072 aParam.maPos = pCol->maCells.position(nStartRow).first;
1073 aParam.maEnd = pCol->maCells.end();
1074 aParam.mnCol = i;
1075
1076 // find first non-empty element.
1077 while (aParam.maPos != aParam.maEnd) {
1078 if (aParam.maPos->type == sc::element_type_empty)
1079 ++aParam.maPos;
1080 else
1081 {
1082 maColPositions.push_back( aParam );
1083 break;
1084 }
1085 }
1086 }
1087
1088 if (maColPositions.empty())
1089 return;
1090
1091 maColPos = maColPositions.begin();
1092 mbMore = true;
1093 SkipInvalid();
1094}
1095
1097{
1098 if (!mbMore)
1099 {
1100 debugiter("no more !\n");
1101 return nullptr;
1102 }
1103
1104 // Return the current non-empty cell, and move the cursor to the next one.
1105 ColParam& r = *maColPos;
1106
1107 rCol = mnCol = r.mnCol;
1108 rRow = mnRow;
1109 debugiter("return col %d row %d\n", (int)rCol, (int)rRow);
1110
1111 size_t nOffset = static_cast<size_t>(mnRow) - r.maPos->position;
1112 maCurCell = sc::toRefCell(r.maPos, nOffset);
1113 Advance();
1114 debugiter("advance to: col %d row %d\n", (int)maColPos->mnCol, (int)mnRow);
1115
1116 return &maCurCell;
1117}
1118
1120{
1121 rCol = mnCol;
1122 rRow = mnRow;
1123 return mbMore;
1124}
1125
1126// Skip any invalid / empty cells across the current row,
1127// we only advance the cursor if the current entry is invalid.
1128// if we return true we have a valid cursor (or hit the end)
1130{
1131 assert (mbMore);
1132 assert (maColPos != maColPositions.end());
1133
1134 // Find the next non-empty cell in the current row.
1135 while( maColPos != maColPositions.end() )
1136 {
1137 ColParam& r = *maColPos;
1138 assert (r.maPos != r.maEnd);
1139
1140 size_t nRow = static_cast<size_t>(mnRow);
1141
1142 if (nRow >= r.maPos->position)
1143 {
1144 if (nRow < r.maPos->position + r.maPos->size)
1145 {
1146 mnCol = maColPos->mnCol;
1147 debugiter("found valid cell at column %d, row %d\n",
1148 (int)mnCol, (int)mnRow);
1149 assert(r.maPos->type != sc::element_type_empty);
1150 return true;
1151 }
1152 else
1153 {
1154 bool bMoreBlocksInColumn = false;
1155 // This block is behind the current row position. Advance the block.
1156 for (++r.maPos; r.maPos != r.maEnd; ++r.maPos)
1157 {
1158 if (nRow < r.maPos->position + r.maPos->size &&
1159 r.maPos->type != sc::element_type_empty)
1160 {
1161 bMoreBlocksInColumn = true;
1162 break;
1163 }
1164 }
1165 if (!bMoreBlocksInColumn)
1166 {
1167 debugiter("remove column %d at row %d\n",
1168 (int)maColPos->mnCol, (int)nRow);
1170 if (maColPositions.empty())
1171 {
1172 debugiter("no more columns\n");
1173 mbMore = false;
1174 }
1175 }
1176 else
1177 {
1178 debugiter("advanced column %d to block starting row %d, retrying\n",
1179 (int)maColPos->mnCol, r.maPos->position);
1180 }
1181 }
1182 }
1183 else
1184 {
1185 debugiter("skip empty cells at column %d, row %d\n",
1186 (int)maColPos->mnCol, (int)nRow);
1187 ++maColPos;
1188 }
1189 }
1190
1191 // No more columns with anything interesting in them ?
1192 if (maColPositions.empty())
1193 {
1194 debugiter("no more live columns left - done\n");
1195 mbMore = false;
1196 return true;
1197 }
1198
1199 return false;
1200}
1201
1204{
1205 size_t nNextRow = rDoc.MaxRow()+1;
1206
1207 for (const ColParam& r : maColPositions)
1208 {
1209 assert(o3tl::make_unsigned(mnRow) <= r.maPos->position);
1210 nNextRow = std::min (nNextRow, static_cast<size_t>(r.maPos->position));
1211 }
1212
1213 SCROW nRow = std::max(static_cast<SCROW>(nNextRow), mnRow);
1214 debugiter("Next non empty row is %d\n", (int) nRow);
1215 return nRow;
1216}
1217
1219{
1220 assert (mbMore);
1221 assert (maColPos != maColPositions.end());
1222
1223 ++maColPos;
1224
1225 SkipInvalid();
1226}
1227
1229{
1230 if (maColPos == maColPositions.end() ||
1232 {
1233 mnRow++;
1234
1235 if (mnRow > nEndRow)
1236 {
1237 mbMore = false;
1238 return;
1239 }
1240
1241 maColPos = maColPositions.begin();
1242 debugiter("moving to next row\n");
1243 if (SkipInvalidInRow())
1244 {
1245 debugiter("moved to valid cell in next row (or end)\n");
1246 return;
1247 }
1248
1250 maColPos = maColPositions.begin();
1251 bool bCorrect = SkipInvalidInRow();
1252 assert (bCorrect); (void) bCorrect;
1253 }
1254
1255 if (mnRow > nEndRow)
1256 mbMore = false;
1257}
1258
1260 const ScRange& rRange ) :
1261 rDoc( rDocument ),
1262 nEndTab( rRange.aEnd.Tab() ),
1263 bCalcAsShown( rDocument.GetDocOptions().IsCalcAsShown() )
1264{
1265 SCCOL nStartCol = rRange.aStart.Col();
1266 SCROW nStartRow = rRange.aStart.Row();
1267 SCTAB nStartTab = rRange.aStart.Tab();
1268 SCCOL nEndCol = rRange.aEnd.Col();
1269 SCROW nEndRow = rRange.aEnd.Row();
1270 PutInOrder( nStartCol, nEndCol);
1271 PutInOrder( nStartRow, nEndRow);
1272 PutInOrder( nStartTab, nEndTab );
1273
1274 if (!rDoc.ValidCol(nStartCol)) nStartCol = rDoc.MaxCol();
1275 if (!rDoc.ValidCol(nEndCol)) nEndCol = rDoc.MaxCol();
1276 if (!rDoc.ValidRow(nStartRow)) nStartRow = rDoc.MaxRow();
1277 if (!rDoc.ValidRow(nEndRow)) nEndRow = rDoc.MaxRow();
1278 if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
1279 if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
1280
1281 nCurCol = nStartCol;
1282 nCurRow = nStartRow;
1283 nCurTab = nStartTab;
1284
1285 nNumFormat = 0; // Will be initialized in GetNumberFormat()
1286 pAttrArray = nullptr;
1287 nAttrEndRow = 0;
1288
1289 pCellIter.reset( new ScHorizontalCellIterator( rDoc, nStartTab, nStartCol,
1290 nStartRow, nEndCol, nEndRow ) );
1291}
1292
1294{
1295}
1296
1298{
1299 bool bFound = false;
1300 while ( !bFound )
1301 {
1302 ScRefCellValue* pCell = pCellIter->GetNext( nCurCol, nCurRow );
1303 while ( !pCell )
1304 {
1305 if ( nCurTab < nEndTab )
1306 {
1307 pCellIter->SetTab( ++nCurTab);
1308 pCell = pCellIter->GetNext( nCurCol, nCurRow );
1309 }
1310 else
1311 return false;
1312 }
1313 switch (pCell->getType())
1314 {
1315 case CELLTYPE_VALUE:
1316 {
1317 rValue = pCell->getDouble();
1318 rErr = FormulaError::NONE;
1319 if ( bCalcAsShown )
1320 {
1321 ScColumn* pCol = &rDoc.maTabs[nCurTab]->aCol[nCurCol];
1323 nAttrEndRow, pCol->pAttrArray.get(), nCurRow, rDoc );
1324 rValue = rDoc.RoundValueAsShown( rValue, nNumFormat );
1325 }
1326 bFound = true;
1327 }
1328 break;
1329 case CELLTYPE_FORMULA:
1330 {
1331 rErr = pCell->getFormula()->GetErrCode();
1332 if (rErr != FormulaError::NONE || pCell->getFormula()->IsValue())
1333 {
1334 rValue = pCell->getFormula()->GetValue();
1335 bFound = true;
1336 }
1337 }
1338 break;
1339 case CELLTYPE_STRING :
1340 case CELLTYPE_EDIT :
1341 break;
1342 default: ; // nothing
1343 }
1344 }
1345 return bFound;
1346}
1347
1349 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
1350 rDoc( rDocument ),
1351 nTab( nTable ),
1352 nStartCol( nCol1 ),
1353 nStartRow( nRow1 ),
1354 nEndCol( nCol2 ),
1355 nEndRow( nRow2 )
1356{
1357 assert(nTab < rDoc.GetTableCount() && "index out of bounds, FIX IT");
1358 assert(rDoc.maTabs[nTab]);
1359
1360 nRow = nStartRow;
1361 nCol = nStartCol;
1362
1363 pIndices.reset( new SCSIZE[nEndCol-nStartCol+1] );
1364 pNextEnd.reset( new SCROW[nEndCol-nStartCol+1] );
1365 pHorizEnd.reset( new SCCOL[nEndCol-nStartCol+1] );
1366 ppPatterns.reset( new const ScPatternAttr*[nEndCol-nStartCol+1] );
1367
1368 InitForNextRow(true);
1369}
1370
1372{
1373}
1374
1376{
1378 SCCOL nThisHead = 0;
1379
1380 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1381 {
1382 SCCOL nPos = i - nStartCol;
1383 if ( bInitialization || pNextEnd[nPos] < nRow )
1384 {
1385 const ScAttrArray& pArray = rDoc.maTabs[nTab]->ColumnData(i).AttrArray();
1386
1387 SCSIZE nIndex;
1388 if (bInitialization)
1389 {
1390 if ( pArray.Count() )
1391 pArray.Search( nStartRow, nIndex );
1392 else
1393 nIndex = 0;
1394 pIndices[nPos] = nIndex;
1395 pHorizEnd[nPos] = rDoc.MaxCol()+1; // only for assert()
1396 }
1397 else
1398 nIndex = ++pIndices[nPos];
1399
1400 if ( !nIndex && !pArray.Count() )
1401 {
1402 pNextEnd[nPos] = rDoc.MaxRow();
1403 assert( pNextEnd[nPos] >= nRow && "Sequence out of order" );
1405 }
1406 else if ( nIndex < pArray.Count() )
1407 {
1408 const ScPatternAttr* pPattern = pArray.mvData[nIndex].pPattern;
1409 SCROW nThisEnd = pArray.mvData[nIndex].nEndRow;
1410 pNextEnd[nPos] = nThisEnd;
1411 assert( pNextEnd[nPos] >= nRow && "Sequence out of order" );
1412 ppPatterns[nPos] = pPattern;
1413 }
1414 else
1415 {
1416 assert(!"AttrArray does not range to MAXROW");
1417 pNextEnd[nPos] = rDoc.MaxRow();
1418 ppPatterns[nPos] = nullptr;
1419 }
1420 }
1421
1422 if ( nMinNextEnd > pNextEnd[nPos] )
1424
1425 // store positions of ScHorizontalAttrIterator elements (minimizing expensive ScPatternAttr comparisons)
1426 if (i > nStartCol && ppPatterns[nThisHead] != ppPatterns[nPos])
1427 {
1428 pHorizEnd[nThisHead] = i - 1;
1429 nThisHead = nPos; // start position of the next horizontal group
1430 }
1431 }
1432
1433 pHorizEnd[nThisHead] = nEndCol; // set the end position of the last horizontal group, too
1434}
1435
1437{
1438 assert(nTab < rDoc.GetTableCount() && "index out of bounds, FIX IT");
1439 for (;;)
1440 {
1441 if ( nCol <= nEndCol )
1442 {
1443 const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
1444 rRow = nRow;
1445 rCol1 = nCol;
1446 assert( pHorizEnd[nCol-nStartCol] < rDoc.MaxCol()+1 && "missing stored data" );
1448 rCol2 = nCol;
1449 ++nCol; // Count up for next call
1450 return pPat; // Found it!
1451 }
1452
1453 // Next row
1454 ++nRow;
1455 if ( nRow > nEndRow ) // Already at the end?
1456 return nullptr; // Found nothing
1457 nCol = nStartCol; // Start at the left again
1458
1459 if ( nRow > nMinNextEnd )
1460 InitForNextRow(false);
1461 }
1462}
1463
1464static bool IsGreater( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1465{
1466 return ( nRow1 > nRow2 ) || ( nRow1 == nRow2 && nCol1 > nCol2 );
1467}
1468
1470 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1471 : aCellIter( rDocument, nTable, nCol1, nRow1, nCol2, nRow2 )
1472 , aAttrIter( rDocument, nTable, nCol1, nRow1, nCol2, nRow2 )
1473 , nNextCol( nCol1 )
1474 , nNextRow( nRow1 )
1475 , nCellCol( 0 )
1476 , nCellRow( 0 )
1477 , nAttrCol1( 0 )
1478 , nAttrCol2( 0 )
1479 , nAttrRow( 0 )
1480 , nFoundStartCol( 0 )
1481 , nFoundEndCol( 0 )
1482 , nFoundRow( 0 )
1483 , pFoundPattern( nullptr )
1484{
1487}
1488
1490{
1491}
1492
1494{
1495 // Forward iterators
1498
1499 while (pCell && pCell->isEmpty())
1501
1504
1505 if ( pPattern && nAttrRow == nNextRow && nAttrCol1 < nNextCol )
1507
1508 // Find next area
1509 bool bFound = true;
1510 bool bUseCell = false;
1511
1512 if ( pCell && pPattern )
1513 {
1514 if ( IsGreater( nCellCol, nCellRow, nAttrCol1, nAttrRow ) ) // Only attributes at the beginning?
1515 {
1520 if ( nCellRow == nAttrRow && nCellCol <= nAttrCol2 ) // Area also contains cell?
1521 nFoundEndCol = nCellCol - 1; // Only until right before the cell
1522 else
1523 nFoundEndCol = nAttrCol2; // Everything
1524 }
1525 else
1526 {
1527 bUseCell = true;
1528 if ( nAttrRow == nCellRow && nAttrCol1 == nCellCol ) // Attributes on the cell?
1530 else
1531 pFoundPattern = nullptr;
1532 }
1533 }
1534 else if ( pCell ) // Just a cell -> take over right away
1535 {
1536 pFoundPattern = nullptr;
1537 bUseCell = true; // Cell position
1538 }
1539 else if ( pPattern ) // Just attributes -> take over right away
1540 {
1546 }
1547 else // Nothing
1548 bFound = false;
1549
1550 if ( bUseCell ) // Cell position
1551 {
1552 if (pCell)
1553 maFoundCell = *pCell;
1554 else
1556
1559 }
1560
1561 if (bFound)
1562 {
1564 nNextCol = nFoundEndCol + 1;
1565 }
1566
1567 return bFound;
1568}
1569
1571 SCCOL nCol1, SCROW nRow1,
1572 SCCOL nCol2, SCROW nRow2) :
1573 rDoc( rDocument ),
1574 nTab( nTable ),
1575 nEndCol( nCol2 ),
1576 nStartRow( nRow1 ),
1577 nEndRow( nRow2 ),
1578 nCol( nCol1 )
1579{
1580 if ( ValidTab(nTab) && nTab < rDoc.GetTableCount() && rDoc.maTabs[nTab] )
1581 pColIter = rDoc.maTabs[nTab]->ColumnData(nCol).CreateAttrIterator( nStartRow, nEndRow );
1582}
1583
1585{
1586}
1587
1589{
1590 while ( pColIter )
1591 {
1592 const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
1593 if ( pPattern )
1594 {
1595 rCol = nCol;
1596 return pPattern;
1597 }
1598
1599 ++nCol;
1600 if ( nCol <= nEndCol )
1601 pColIter = rDoc.maTabs[nTab]->ColumnData(nCol).CreateAttrIterator( nStartRow, nEndRow );
1602 else
1603 pColIter.reset();
1604 }
1605 return nullptr; // Nothing anymore
1606}
1607
1609 mnTab(nTab), maRanges(nMaxRow)
1610{
1611}
1612
1613ScDocRowHeightUpdater::ScDocRowHeightUpdater(ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, const vector<TabRanges>* pTabRangesArray) :
1614 mrDoc(rDoc), mpOutDev(pOutDev), mfPPTX(fPPTX), mfPPTY(fPPTY), mpTabRangesArray(pTabRangesArray)
1615{
1616}
1617
1618void ScDocRowHeightUpdater::update(const bool bOnlyUsedRows)
1619{
1620 if (!mpTabRangesArray || mpTabRangesArray->empty())
1621 {
1622 // No ranges defined. Update all rows in all tables.
1623 updateAll(bOnlyUsedRows);
1624 return;
1625 }
1626
1627 sal_uInt64 nCellCount = 0;
1628 for (const auto& rTabRanges : *mpTabRangesArray)
1629 {
1630 const SCTAB nTab = rTabRanges.mnTab;
1631 if (!ValidTab(nTab) || nTab >= mrDoc.GetTableCount() || !mrDoc.maTabs[nTab])
1632 continue;
1633
1635 ScFlatBoolRowSegments::RangeIterator aRangeItr(rTabRanges.maRanges);
1636 for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
1637 {
1638 if (!aData.mbValue)
1639 continue;
1640
1641 nCellCount += mrDoc.maTabs[nTab]->GetWeightedCount(aData.mnRow1, aData.mnRow2);
1642 }
1643 }
1644
1645 ScProgress aProgress(mrDoc.GetDocumentShell(), ScResId(STR_PROGRESS_HEIGHTING), nCellCount, true);
1646
1647 Fraction aZoom(1, 1);
1648 sal_uInt64 nProgressStart = 0;
1649 for (const auto& rTabRanges : *mpTabRangesArray)
1650 {
1651 const SCTAB nTab = rTabRanges.mnTab;
1652 if (!ValidTab(nTab) || nTab >= mrDoc.GetTableCount() || !mrDoc.maTabs[nTab])
1653 continue;
1654
1655 sc::RowHeightContext aCxt(mrDoc.MaxRow(), mfPPTX, mfPPTY, aZoom, aZoom, mpOutDev);
1657 ScFlatBoolRowSegments::RangeIterator aRangeItr(rTabRanges.maRanges);
1658 for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
1659 {
1660 if (!aData.mbValue)
1661 continue;
1662
1663 mrDoc.maTabs[nTab]->SetOptimalHeight(
1664 aCxt, aData.mnRow1, aData.mnRow2, true, &aProgress, nProgressStart);
1665
1666 nProgressStart += mrDoc.maTabs[nTab]->GetWeightedCount(aData.mnRow1, aData.mnRow2);
1667 }
1668 }
1669}
1670
1671void ScDocRowHeightUpdater::updateAll(const bool bOnlyUsedRows)
1672{
1673 sal_uInt64 nCellCount = 0;
1674 for (SCTAB nTab = 0; nTab < mrDoc.GetTableCount(); ++nTab)
1675 {
1676 if (!ValidTab(nTab) || !mrDoc.maTabs[nTab])
1677 continue;
1678
1679 nCellCount += mrDoc.maTabs[nTab]->GetWeightedCount();
1680 }
1681
1682 ScProgress aProgress(mrDoc.GetDocumentShell(), ScResId(STR_PROGRESS_HEIGHTING), nCellCount, true);
1683
1684 Fraction aZoom(1, 1);
1685 sc::RowHeightContext aCxt(mrDoc.MaxRow(), mfPPTX, mfPPTY, aZoom, aZoom, mpOutDev);
1686 sal_uInt64 nProgressStart = 0;
1687 for (SCTAB nTab = 0; nTab < mrDoc.GetTableCount(); ++nTab)
1688 {
1689 if (!ValidTab(nTab) || !mrDoc.maTabs[nTab])
1690 continue;
1691
1692 SCCOL nEndCol = 0;
1693 SCROW nEndRow = mrDoc.MaxRow();
1694 if (!bOnlyUsedRows || mrDoc.GetPrintArea(nTab, nEndCol, nEndRow))
1695 mrDoc.maTabs[nTab]->SetOptimalHeight(aCxt, 0, nEndRow, true, &aProgress, nProgressStart);
1696 nProgressStart += mrDoc.maTabs[nTab]->GetWeightedCount();
1697 }
1698}
1699
1701 SCCOL nCol1, SCROW nRow1,
1702 SCCOL nCol2, SCROW nRow2) :
1703 rDoc( rDocument ),
1704 nTab( nTable ),
1705 nEndCol( nCol2 ),
1706 nStartRow( nRow1 ),
1707 nEndRow( nRow2 ),
1708 nIterStartCol( nCol1 ),
1709 nIterEndCol( nCol1 )
1710{
1711 if ( ValidTab(nTab) && nTab < rDoc.GetTableCount() && rDoc.maTabs[nTab] )
1712 {
1713 pColIter = rDoc.maTabs[nTab]->ColumnData(nIterStartCol).CreateAttrIterator( nStartRow, nEndRow );
1714 while ( nIterEndCol < nEndCol &&
1715 rDoc.maTabs[nTab]->ColumnData(nIterEndCol).IsAllAttrEqual(
1716 rDoc.maTabs[nTab]->ColumnData(nIterEndCol+1), nStartRow, nEndRow ) )
1717 ++nIterEndCol;
1718 }
1719}
1720
1722{
1723}
1724
1726{
1727 if (pColIter)
1728 {
1729 SCROW nNextRow = pColIter->GetNextRow();
1730 pColIter = rDoc.maTabs[nTab]->ColumnData(nIterStartCol).CreateAttrIterator( nNextRow, nEndRow );
1731 }
1732}
1733
1735 SCROW& rRow1, SCROW& rRow2 )
1736{
1737 while ( pColIter )
1738 {
1739 const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
1740 if ( pPattern )
1741 {
1742 rCol1 = nIterStartCol;
1743 rCol2 = nIterEndCol;
1744 return pPattern;
1745 }
1746
1748 if ( nIterStartCol <= nEndCol )
1749 {
1751 pColIter = rDoc.maTabs[nTab]->ColumnData(nIterStartCol).CreateAttrIterator( nStartRow, nEndRow );
1752 while ( nIterEndCol < nEndCol &&
1753 rDoc.maTabs[nTab]->ColumnData(nIterEndCol).IsAllAttrEqual(
1754 rDoc.maTabs[nTab]->ColumnData(nIterEndCol+1), nStartRow, nEndRow ) )
1755 ++nIterEndCol;
1756 }
1757 else
1758 pColIter.reset();
1759 }
1760 return nullptr; // Nothing anymore
1761}
1762
1764 mrBreaks(rBreaks),
1765 maItr(rBreaks.begin()), maEnd(rBreaks.end())
1766{
1767}
1768
1770{
1771 maItr = mrBreaks.begin();
1772 return maItr == maEnd ? NOT_FOUND : *maItr;
1773}
1774
1776{
1777 ++maItr;
1778 return maItr == maEnd ? NOT_FOUND : *maItr;
1779}
1780
1781/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const Point maEnd
bool ValidTab(SCTAB nTab)
Definition: address.hxx:111
const SCTAB MAXTAB
Definition: address.hxx:70
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:150
const NodeContext & mrContext
sal_Int32 compareString(const OUString &s1, const OUString &s2) const
virtual std::unique_ptr< EditTextObject > Clone() const=0
void IncTab(SCTAB nDelta=1)
Definition: address.hxx:320
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:316
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
void IncRow(SCROW nDelta=1)
Definition: address.hxx:312
SCCOL Col() const
Definition: address.hxx:279
bool Search(SCROW nRow, SCSIZE &nIndex) const
Definition: attarray.cxx:194
SCSIZE Count() const
Definition: attarray.hxx:226
const ScPatternAttr * GetPatternRange(SCROW &rStartRow, SCROW &rEndRow, SCROW nRow) const
Returns if you search for attributes at nRow the range from rStartRow to rEndRow where that attribute...
Definition: attarray.cxx:254
std::vector< ScAttrEntry > mvData
Definition: attarray.hxx:98
ScDocument & rDoc
Definition: dociter.hxx:273
ScAttrRectIterator(ScDocument &rDocument, SCTAB nTable, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: dociter.cxx:1700
std::unique_ptr< ScAttrIterator > pColIter
Definition: dociter.hxx:281
const ScPatternAttr * GetNext(SCCOL &rCol1, SCCOL &rCol2, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1734
void incBlock()
Definition: dociter.cxx:828
ScRefCellValue maCurCell
Definition: dociter.hxx:217
ScAddress maEndPos
Definition: dociter.hxx:211
ScAddress maCurPos
Definition: dociter.hxx:212
bool hasString() const
Definition: dociter.cxx:994
bool getCurrent()
Definition: dociter.cxx:892
void incPos()
Definition: dociter.cxx:836
void setPos(size_t nPos)
Definition: dociter.cxx:849
ScAddress maStartPos
Definition: dociter.hxx:210
OUString getString() const
Definition: dociter.cxx:968
bool isEmpty() const
Definition: dociter.cxx:999
ScCellIterator(ScDocument &rDoc, const ScRange &rRange, SubtotalFlags nSubTotalFlags=SubtotalFlags::NONE)
Definition: dociter.cxx:819
bool equalsWithoutFormat(const ScAddress &rPos) const
Definition: dociter.cxx:1004
const ScColumn * getColumn() const
Definition: dociter.cxx:855
PositionType maCurColPos
Definition: dociter.hxx:214
SubtotalFlags mnSubTotalFlags
Definition: dociter.hxx:215
ScCellValue getCellValue() const
Definition: dociter.cxx:973
ScDocument & mrDoc
Definition: dociter.hxx:209
std::unique_ptr< ScAttrArray > pAttrArray
Definition: column.hxx:118
std::vector< sc::FormulaGroupEntry > GetFormulaGroupEntries()
Get all non-grouped formula cells and formula cell groups in the whole column.
Definition: column.cxx:2448
bool IsEmptyData() const
Definition: column2.cxx:1284
sc::CellStoreType maCells
Definition: column.hxx:197
ScDocument & GetDoc() const
Definition: column.hxx:127
sal_uInt32 GetNumberFormat(const ScInterpreterContext &rContext, SCROW nRow) const
Definition: column.hxx:980
virtual bool getCurrent(Value &rValue) override
Definition: dociter.cxx:367
virtual bool getFirst(Value &rValue) override
Definition: dociter.cxx:470
virtual bool getNext(Value &rValue) override
Definition: dociter.cxx:483
DataAccessInternal(ScDBQueryParamInternal *pParam, ScDocument &rDoc, const ScInterpreterContext &rContext)
Definition: dociter.cxx:333
ScDBQueryParamInternal * mpParam
Definition: dociter.hxx:143
virtual bool getCurrent(Value &rValue) override
Definition: dociter.cxx:526
bool isValidQuery(SCROW mnRow, const ScMatrix &rMat) const
Definition: dociter.cxx:600
virtual bool getFirst(Value &rValue) override
Definition: dociter.cxx:553
DataAccessMatrix(ScDBQueryParamMatrix *pParam)
Definition: dociter.cxx:513
virtual bool getNext(Value &rValue) override
Definition: dociter.cxx:559
ScDBQueryParamMatrix * mpParam
Definition: dociter.hxx:169
::std::unique_ptr< ScDBQueryParamBase > mpParam
Definition: dociter.hxx:174
static const ScAttrArray * GetAttrArrayByCol(ScDocument &rDoc, SCTAB nTab, SCCOL nCol)
Definition: dociter.cxx:318
ScDBQueryDataIterator(ScDocument &rDocument, const ScInterpreterContext &rContext, std::unique_ptr< ScDBQueryParamBase > pParam)
Definition: dociter.cxx:738
bool GetNext(Value &rValue)
Does NOT reset rValue if no value found!
Definition: dociter.cxx:762
bool GetFirst(Value &rValue)
Does NOT reset rValue if no value found!
Definition: dociter.cxx:757
static const sc::CellStoreType * GetColumnCellStore(ScDocument &rDoc, SCTAB nTab, SCCOL nCol)
Definition: dociter.cxx:308
::std::unique_ptr< DataAccess > mpData
Definition: dociter.hxx:175
static bool IsQueryValid(ScDocument &rDoc, const ScQueryParam &rParam, SCTAB nTab, SCROW nRow, const ScRefCellValue *pCell)
Definition: dociter.cxx:325
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1588
ScDocument & rDoc
Definition: dociter.hxx:252
std::unique_ptr< ScAttrIterator > pColIter
Definition: dociter.hxx:259
ScDocAttrIterator(ScDocument &rDocument, SCTAB nTable, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: dociter.cxx:1570
void update(const bool bOnlyUsedRows=false)
Definition: dociter.cxx:1618
const ::std::vector< TabRanges > * mpTabRangesArray
Definition: dociter.hxx:470
ScDocument & mrDoc
Definition: dociter.hxx:466
void updateAll(const bool bOnlyUsedRows)
Definition: dociter.cxx:1671
ScDocRowHeightUpdater(ScDocument &rDoc, OutputDevice *pOutDev, double fPPTX, double fPPTY, const ::std::vector< TabRanges > *pTabRangesArray)
Passing a NULL pointer to pTabRangesArray forces the heights of all rows in all tables to be updated.
Definition: dociter.cxx:1613
VclPtr< OutputDevice > mpOutDev
Definition: dociter.hxx:467
SC_DLLPUBLIC SCCOL GetAllocatedColumnsCount(SCTAB nTab) const
Definition: documen3.cxx:2139
SC_DLLPUBLIC ScPatternAttr * GetDefPattern() const
Definition: document.cxx:6045
bool ValidRow(SCROW nRow) const
Definition: document.hxx:900
SC_DLLPUBLIC ScTable * FetchTable(SCTAB nTab)
Definition: document.cxx:2509
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4475
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
SC_DLLPUBLIC double RoundValueAsShown(double fVal, sal_uInt32 nFormat, const ScInterpreterContext *pContext=nullptr) const
Definition: documen4.cxx:627
TableContainer maTabs
Definition: document.hxx:378
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4416
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:899
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
SC_DLLPUBLIC bool GetPrintArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow, bool bNotes=true) const
Definition: documen2.cxx:611
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
bool getFirst(RangeData &rRange)
bool getNext(RangeData &rRange)
bool GetErrorOrValue(FormulaError &rErr, double &rVal)
bool IsSubTotal() const
double GetValue()
ScFormulaCell * Clone() const
const svl::SharedString & GetString()
FormulaError GetErrCode()
ScDocument & mrDoc
Definition: dociter.hxx:188
sc::FormulaGroupEntry * first()
Definition: dociter.cxx:784
ScFormulaGroupIterator(ScDocument &rDoc)
Definition: dociter.cxx:767
std::vector< sc::FormulaGroupEntry > maEntries
Definition: dociter.hxx:193
sc::FormulaGroupEntry * next()
Definition: dociter.cxx:789
static SC_DLLPUBLIC CollatorWrapper & GetCollator()
case-insensitive collator
Definition: global.cxx:1095
std::unique_ptr< SCROW[]> pNextEnd
Definition: dociter.hxx:367
std::unique_ptr< SCCOL[]> pHorizEnd
Definition: dociter.hxx:368
std::unique_ptr< SCSIZE[]> pIndices
Definition: dociter.hxx:369
std::unique_ptr< const ScPatternAttr *[]> ppPatterns
Definition: dociter.hxx:371
ScHorizontalAttrIterator(ScDocument &rDocument, SCTAB nTable, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: dociter.cxx:1348
void InitForNextRow(bool bInitialization)
Definition: dociter.cxx:1375
const ScPatternAttr * GetNext(SCCOL &rCol1, SCCOL &rCol2, SCROW &rRow)
Definition: dociter.cxx:1436
void SetTab(SCTAB nTab)
Set a(nother) sheet and (re)init.
Definition: dociter.cxx:1059
bool GetPos(SCCOL &rCol, SCROW &rRow)
Definition: dociter.cxx:1119
ScRefCellValue * GetNext(SCCOL &rCol, SCROW &rRow)
Definition: dociter.cxx:1096
ScRefCellValue maCurCell
Definition: dociter.hxx:312
std::vector< ColParam >::iterator maColPos
Definition: dociter.hxx:301
ScHorizontalCellIterator(ScDocument &rDocument, SCTAB nTable, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: dociter.cxx:1028
std::vector< ColParam > maColPositions
Definition: dociter.hxx:302
SCROW FindNextNonEmptyRow()
Find the next row that has some real content in one of its columns.
Definition: dociter.cxx:1203
ScHorizontalValueIterator(ScDocument &rDocument, const ScRange &rRange)
Definition: dociter.cxx:1259
std::unique_ptr< ScHorizontalCellIterator > pCellIter
Definition: dociter.hxx:339
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
Definition: dociter.cxx:1297
const ScAttrArray * pAttrArray
Definition: dociter.hxx:337
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
Definition: scmatrix.cxx:3238
bool IsStringOrEmpty(SCSIZE nIndex) const
Definition: scmatrix.cxx:3258
bool IsEmpty(SCSIZE nC, SCSIZE nR) const
Definition: scmatrix.cxx:3268
double GetDouble(SCSIZE nC, SCSIZE nR) const
Definition: scmatrix.cxx:3223
bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
Definition: scmatrix.cxx:3298
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
Definition: patattr.cxx:1398
bool ValidQuery(SCROW nRow, const ScRefCellValue *pCell=nullptr, sc::TableColumnBlockPositionSet *pBlockPos=nullptr)
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
::std::set< SCROW >::const_iterator maItr
Definition: dociter.hxx:437
::std::set< SCROW >::const_iterator maEnd
Definition: dociter.hxx:438
ScRowBreakIterator(::std::set< SCROW > &rBreaks)
Definition: dociter.cxx:1763
static constexpr SCROW NOT_FOUND
Definition: dociter.hxx:429
::std::set< SCROW > & mrBreaks
Definition: dociter.hxx:436
ScColumn * FetchColumn(SCCOL nCol)
Definition: table2.cxx:1236
ScColContainer aCol
Definition: table.hxx:162
SCCOL GetAllocatedColumnsCount() const
Definition: table.hxx:1164
SCCOL ClampToAllocatedColumns(SCCOL nCol) const
Definition: table.hxx:1163
ScRefCellValue * pCell
Definition: dociter.hxx:399
ScHorizontalCellIterator aCellIter
Definition: dociter.hxx:391
const ScPatternAttr * pFoundPattern
Definition: dociter.hxx:408
ScHorizontalAttrIterator aAttrIter
Definition: dociter.hxx:392
const ScPatternAttr * pPattern
Definition: dociter.hxx:403
ScRefCellValue maFoundCell
Definition: dociter.hxx:410
ScUsedAreaIterator(ScDocument &rDocument, SCTAB nTable, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: dociter.cxx:1469
SvNumFormatType nNumFmtType
Definition: dociter.hxx:66
const ScDocument & mrDoc
Definition: dociter.hxx:55
bool GetFirst(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
Definition: dociter.cxx:270
SubtotalFlags mnSubTotalFlags
Definition: dociter.hxx:65
ScAddress maEndPos
Definition: dociter.hxx:61
void GetCurNumFmtInfo(SvNumFormatType &nType, sal_uInt32 &nIndex)
Definition: dociter.cxx:255
bool GetThis(double &rValue, FormulaError &rErr)
See if the cell at the current position is a non-empty cell.
Definition: dociter.cxx:137
bool bTextAsZero
Definition: dociter.hxx:69
sal_uInt32 nNumFormat
Definition: dociter.hxx:58
ScAddress maStartPos
Definition: dociter.hxx:60
ScValueIterator(ScInterpreterContext &rContext, const ScRange &rRange, SubtotalFlags nSubTotalFlags=SubtotalFlags::NONE, bool bTextAsZero=false)
Definition: dociter.cxx:85
ScInterpreterContext & mrContext
Definition: dociter.hxx:56
sal_uInt32 nNumFmtIndex
Definition: dociter.hxx:59
void IncBlock()
Definition: dociter.cxx:121
SCROW nAttrEndRow
Definition: dociter.hxx:64
const sc::CellStoreType * mpCells
Definition: dociter.hxx:71
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
Definition: dociter.cxx:294
const ScAttrArray * pAttrArray
Definition: dociter.hxx:57
bool bCalcAsShown
Definition: dociter.hxx:68
SCROW GetRow() const
Definition: dociter.cxx:114
PositionType maCurPos
Definition: dociter.hxx:72
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
const OUString & getString() const
rtl_uString * getDataIgnoreCase()
rtl_uString * getData()
int nCount
static void ScAttrArray_IterGetNumberFormat(sal_uInt32 &nFormat, const ScAttrArray *&rpArr, SCROW &nAttrEndRow, const ScAttrArray *pNewArr, SCROW nRow, const ScDocument &rDoc, const ScInterpreterContext *pContext=nullptr)
Definition: dociter.cxx:64
#define debugiter(...)
Definition: dociter.cxx:62
static bool IsGreater(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: dociter.cxx:1464
sal_Int32 mnRow
sal_Int32 mnCol
UNDEFINED
FormulaError
@ SC_AND
Definition: global.hxx:855
@ CELLTYPE_EDIT
Definition: global.hxx:277
@ CELLTYPE_STRING
Definition: global.hxx:275
@ CELLTYPE_FORMULA
Definition: global.hxx:276
@ CELLTYPE_VALUE
Definition: global.hxx:274
SubtotalFlags
Definition: global.hxx:240
@ SC_DOES_NOT_CONTAIN
Definition: global.hxx:846
@ SC_LESS_EQUAL
Definition: global.hxx:838
@ SC_LESS
Definition: global.hxx:836
@ SC_GREATER_EQUAL
Definition: global.hxx:839
@ SC_CONTAINS
Definition: global.hxx:845
@ SC_ENDS_WITH
Definition: global.hxx:849
@ SC_DOES_NOT_END_WITH
Definition: global.hxx:850
@ SC_BEGINS_WITH
Definition: global.hxx:847
@ SC_GREATER
Definition: global.hxx:837
@ SC_EQUAL
Definition: global.hxx:835
@ SC_NOT_EQUAL
Definition: global.hxx:840
@ SC_DOES_NOT_BEGIN_WITH
Definition: global.hxx:848
static void incPos(const sal_Unicode c, sal_Int32 &rPos, ESelection &rSel)
Definition: inputhdl.cxx:344
sal_Int32 nIndex
void * p
sal_Int64 n
sal_uInt16 nPos
#define SAL_WARN(area, stream)
def position(n=-1)
constexpr OUStringLiteral aData
NONE
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
enumrange< T >::Iterator begin(enumrange< T >)
end
const mdds::mtv::element_t element_type_edittext
Definition: mtvelements.hxx:48
const mdds::mtv::element_t element_type_formula
Definition: mtvelements.hxx:49
mdds::mtv::soa::multi_type_vector< CellStoreTraits > CellStoreType
Cell container.
ScRefCellValue toRefCell(const sc::CellStoreType::const_iterator &itPos, size_t nOffset)
const mdds::mtv::element_t element_type_numeric
Mapped standard element types (for convenience).
Definition: mtvelements.hxx:55
const mdds::mtv::element_t element_type_string
Definition: mtvelements.hxx:47
const mdds::mtv::element_t element_type_empty
Definition: mtvelements.hxx:56
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
Store arbitrary cell value of any kind.
Definition: cellvalue.hxx:32
ScMatrixRef mpMatrix
Definition: queryparam.hxx:197
TabRanges(SCTAB nTab, SCROW nMaxRow)
Definition: dociter.cxx:1608
sc::CellStoreType::const_iterator maEnd
Definition: dociter.hxx:297
sc::CellStoreType::const_iterator maPos
Definition: dociter.hxx:296
SvNumFormatType GetNumberFormatType(sal_uInt32 nFIndex) const
svl::SharedString maString
Definition: queryentry.hxx:49
Each instance of this struct represents a single filtering criteria.
Definition: queryentry.hxx:34
SCCOLROW nField
Definition: queryentry.hxx:61
const Item & GetQueryItem() const
Definition: queryentry.hxx:85
ScQueryConnect eConnect
Definition: queryentry.hxx:63
std::vector< Item > QueryItemsType
Definition: queryentry.hxx:58
ScQueryOp eOp
Definition: queryentry.hxx:62
QueryItemsType & GetQueryItems()
Definition: queryentry.hxx:75
SC_DLLPUBLIC const ScQueryEntry & GetEntry(SCSIZE n) const
Definition: queryparam.cxx:116
SC_DLLPUBLIC SCSIZE GetEntryCount() const
Definition: queryparam.cxx:111
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:137
const EditTextObject * getEditText() const
Definition: cellvalue.hxx:136
double getDouble() const
Definition: cellvalue.hxx:134
bool isEmpty() const
Definition: cellvalue.cxx:667
OUString getString(const ScDocument *pDoc) const
Retrieve string value.
Definition: cellvalue.cxx:657
bool equalsWithoutFormat(const ScRefCellValue &r) const
Definition: cellvalue.cxx:683
const svl::SharedString * getSharedString() const
Definition: cellvalue.hxx:135
bool hasString() const
Definition: cellvalue.cxx:614
CellType getType() const
Definition: cellvalue.hxx:133
sal_uInt32 mnIndex
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
SvNumFormatType