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 nEndCol = rDoc.maTabs[mnTab]->ClampToAllocatedColumns(nEndCol);
1043 if (nEndCol < nStartCol) // E.g., somewhere completely outside allocated area
1044 nEndCol = nStartCol - 1; // Empty
1045
1046 maColPositions.reserve( nEndCol-nStartCol+1 );
1047
1048 SetTab( mnTab );
1049}
1050
1052{
1053}
1054
1056{
1057 mbMore = false;
1058 mnTab = nTabP;
1059 mnRow = nStartRow;
1060 mnCol = nStartCol;
1061 maColPositions.resize(0);
1062
1063 // Set the start position in each column.
1064 for (SCCOL i = nStartCol; i <= nEndCol; ++i)
1065 {
1066 ScColumn* pCol = &rDoc.maTabs[mnTab]->aCol[i];
1067 ColParam aParam;
1068 aParam.maPos = pCol->maCells.position(nStartRow).first;
1069 aParam.maEnd = pCol->maCells.end();
1070 aParam.mnCol = i;
1071
1072 // find first non-empty element.
1073 while (aParam.maPos != aParam.maEnd) {
1074 if (aParam.maPos->type == sc::element_type_empty)
1075 ++aParam.maPos;
1076 else
1077 {
1078 maColPositions.push_back( aParam );
1079 break;
1080 }
1081 }
1082 }
1083
1084 if (maColPositions.empty())
1085 return;
1086
1087 maColPos = maColPositions.begin();
1088 mbMore = true;
1089 SkipInvalid();
1090}
1091
1093{
1094 if (!mbMore)
1095 {
1096 debugiter("no more !\n");
1097 return nullptr;
1098 }
1099
1100 // Return the current non-empty cell, and move the cursor to the next one.
1101 ColParam& r = *maColPos;
1102
1103 rCol = mnCol = r.mnCol;
1104 rRow = mnRow;
1105 debugiter("return col %d row %d\n", (int)rCol, (int)rRow);
1106
1107 size_t nOffset = static_cast<size_t>(mnRow) - r.maPos->position;
1108 maCurCell = sc::toRefCell(r.maPos, nOffset);
1109 Advance();
1110 debugiter("advance to: col %d row %d\n", (int)maColPos->mnCol, (int)mnRow);
1111
1112 return &maCurCell;
1113}
1114
1116{
1117 rCol = mnCol;
1118 rRow = mnRow;
1119 return mbMore;
1120}
1121
1122// Skip any invalid / empty cells across the current row,
1123// we only advance the cursor if the current entry is invalid.
1124// if we return true we have a valid cursor (or hit the end)
1126{
1127 assert (mbMore);
1128 assert (maColPos != maColPositions.end());
1129
1130 // Find the next non-empty cell in the current row.
1131 while( maColPos != maColPositions.end() )
1132 {
1133 ColParam& r = *maColPos;
1134 assert (r.maPos != r.maEnd);
1135
1136 size_t nRow = static_cast<size_t>(mnRow);
1137
1138 if (nRow >= r.maPos->position)
1139 {
1140 if (nRow < r.maPos->position + r.maPos->size)
1141 {
1142 mnCol = maColPos->mnCol;
1143 debugiter("found valid cell at column %d, row %d\n",
1144 (int)mnCol, (int)mnRow);
1145 assert(r.maPos->type != sc::element_type_empty);
1146 return true;
1147 }
1148 else
1149 {
1150 bool bMoreBlocksInColumn = false;
1151 // This block is behind the current row position. Advance the block.
1152 for (++r.maPos; r.maPos != r.maEnd; ++r.maPos)
1153 {
1154 if (nRow < r.maPos->position + r.maPos->size &&
1155 r.maPos->type != sc::element_type_empty)
1156 {
1157 bMoreBlocksInColumn = true;
1158 break;
1159 }
1160 }
1161 if (!bMoreBlocksInColumn)
1162 {
1163 debugiter("remove column %d at row %d\n",
1164 (int)maColPos->mnCol, (int)nRow);
1166 if (maColPositions.empty())
1167 {
1168 debugiter("no more columns\n");
1169 mbMore = false;
1170 }
1171 }
1172 else
1173 {
1174 debugiter("advanced column %d to block starting row %d, retrying\n",
1175 (int)maColPos->mnCol, r.maPos->position);
1176 }
1177 }
1178 }
1179 else
1180 {
1181 debugiter("skip empty cells at column %d, row %d\n",
1182 (int)maColPos->mnCol, (int)nRow);
1183 ++maColPos;
1184 }
1185 }
1186
1187 // No more columns with anything interesting in them ?
1188 if (maColPositions.empty())
1189 {
1190 debugiter("no more live columns left - done\n");
1191 mbMore = false;
1192 return true;
1193 }
1194
1195 return false;
1196}
1197
1200{
1201 size_t nNextRow = rDoc.MaxRow()+1;
1202
1203 for (const ColParam& r : maColPositions)
1204 {
1205 assert(o3tl::make_unsigned(mnRow) <= r.maPos->position);
1206 nNextRow = std::min (nNextRow, static_cast<size_t>(r.maPos->position));
1207 }
1208
1209 SCROW nRow = std::max(static_cast<SCROW>(nNextRow), mnRow);
1210 debugiter("Next non empty row is %d\n", (int) nRow);
1211 return nRow;
1212}
1213
1215{
1216 assert (mbMore);
1217 assert (maColPos != maColPositions.end());
1218
1219 ++maColPos;
1220
1221 SkipInvalid();
1222}
1223
1225{
1226 if (maColPos == maColPositions.end() ||
1228 {
1229 mnRow++;
1230
1231 if (mnRow > nEndRow)
1232 {
1233 mbMore = false;
1234 return;
1235 }
1236
1237 maColPos = maColPositions.begin();
1238 debugiter("moving to next row\n");
1239 if (SkipInvalidInRow())
1240 {
1241 debugiter("moved to valid cell in next row (or end)\n");
1242 return;
1243 }
1244
1246 maColPos = maColPositions.begin();
1247 bool bCorrect = SkipInvalidInRow();
1248 assert (bCorrect); (void) bCorrect;
1249 }
1250
1251 if (mnRow > nEndRow)
1252 mbMore = false;
1253}
1254
1256 const ScRange& rRange ) :
1257 rDoc( rDocument ),
1258 nEndTab( rRange.aEnd.Tab() ),
1259 bCalcAsShown( rDocument.GetDocOptions().IsCalcAsShown() )
1260{
1261 SCCOL nStartCol = rRange.aStart.Col();
1262 SCROW nStartRow = rRange.aStart.Row();
1263 SCTAB nStartTab = rRange.aStart.Tab();
1264 SCCOL nEndCol = rRange.aEnd.Col();
1265 SCROW nEndRow = rRange.aEnd.Row();
1266 PutInOrder( nStartCol, nEndCol);
1267 PutInOrder( nStartRow, nEndRow);
1268 PutInOrder( nStartTab, nEndTab );
1269
1270 if (!rDoc.ValidCol(nStartCol)) nStartCol = rDoc.MaxCol();
1271 if (!rDoc.ValidCol(nEndCol)) nEndCol = rDoc.MaxCol();
1272 if (!rDoc.ValidRow(nStartRow)) nStartRow = rDoc.MaxRow();
1273 if (!rDoc.ValidRow(nEndRow)) nEndRow = rDoc.MaxRow();
1274 if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
1275 if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
1276
1277 nCurCol = nStartCol;
1278 nCurRow = nStartRow;
1279 nCurTab = nStartTab;
1280
1281 nNumFormat = 0; // Will be initialized in GetNumberFormat()
1282 pAttrArray = nullptr;
1283 nAttrEndRow = 0;
1284
1285 pCellIter.reset( new ScHorizontalCellIterator( rDoc, nStartTab, nStartCol,
1286 nStartRow, nEndCol, nEndRow ) );
1287}
1288
1290{
1291}
1292
1294{
1295 bool bFound = false;
1296 while ( !bFound )
1297 {
1298 ScRefCellValue* pCell = pCellIter->GetNext( nCurCol, nCurRow );
1299 while ( !pCell )
1300 {
1301 if ( nCurTab < nEndTab )
1302 {
1303 pCellIter->SetTab( ++nCurTab);
1304 pCell = pCellIter->GetNext( nCurCol, nCurRow );
1305 }
1306 else
1307 return false;
1308 }
1309 switch (pCell->getType())
1310 {
1311 case CELLTYPE_VALUE:
1312 {
1313 rValue = pCell->getDouble();
1314 rErr = FormulaError::NONE;
1315 if ( bCalcAsShown )
1316 {
1317 ScColumn* pCol = &rDoc.maTabs[nCurTab]->aCol[nCurCol];
1319 nAttrEndRow, pCol->pAttrArray.get(), nCurRow, rDoc );
1320 rValue = rDoc.RoundValueAsShown( rValue, nNumFormat );
1321 }
1322 bFound = true;
1323 }
1324 break;
1325 case CELLTYPE_FORMULA:
1326 {
1327 rErr = pCell->getFormula()->GetErrCode();
1328 if (rErr != FormulaError::NONE || pCell->getFormula()->IsValue())
1329 {
1330 rValue = pCell->getFormula()->GetValue();
1331 bFound = true;
1332 }
1333 }
1334 break;
1335 case CELLTYPE_STRING :
1336 case CELLTYPE_EDIT :
1337 break;
1338 default: ; // nothing
1339 }
1340 }
1341 return bFound;
1342}
1343
1345 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
1346 rDoc( rDocument ),
1347 nTab( nTable ),
1348 nStartCol( nCol1 ),
1349 nStartRow( nRow1 ),
1350 nEndCol( nCol2 ),
1351 nEndRow( nRow2 )
1352{
1353 assert(nTab < rDoc.GetTableCount() && "index out of bounds, FIX IT");
1354 assert(rDoc.maTabs[nTab]);
1355
1356 nRow = nStartRow;
1357 nCol = nStartCol;
1358
1359 pIndices.reset( new SCSIZE[nEndCol-nStartCol+1] );
1360 pNextEnd.reset( new SCROW[nEndCol-nStartCol+1] );
1361 pHorizEnd.reset( new SCCOL[nEndCol-nStartCol+1] );
1362 ppPatterns.reset( new const ScPatternAttr*[nEndCol-nStartCol+1] );
1363
1364 InitForNextRow(true);
1365}
1366
1368{
1369}
1370
1372{
1374 SCCOL nThisHead = 0;
1375
1376 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1377 {
1378 SCCOL nPos = i - nStartCol;
1379 if ( bInitialization || pNextEnd[nPos] < nRow )
1380 {
1381 const ScAttrArray& pArray = rDoc.maTabs[nTab]->ColumnData(i).AttrArray();
1382
1383 SCSIZE nIndex;
1384 if (bInitialization)
1385 {
1386 if ( pArray.Count() )
1387 pArray.Search( nStartRow, nIndex );
1388 else
1389 nIndex = 0;
1390 pIndices[nPos] = nIndex;
1391 pHorizEnd[nPos] = rDoc.MaxCol()+1; // only for assert()
1392 }
1393 else
1394 nIndex = ++pIndices[nPos];
1395
1396 if ( !nIndex && !pArray.Count() )
1397 {
1398 pNextEnd[nPos] = rDoc.MaxRow();
1399 assert( pNextEnd[nPos] >= nRow && "Sequence out of order" );
1401 }
1402 else if ( nIndex < pArray.Count() )
1403 {
1404 const ScPatternAttr* pPattern = pArray.mvData[nIndex].pPattern;
1405 SCROW nThisEnd = pArray.mvData[nIndex].nEndRow;
1406 pNextEnd[nPos] = nThisEnd;
1407 assert( pNextEnd[nPos] >= nRow && "Sequence out of order" );
1408 ppPatterns[nPos] = pPattern;
1409 }
1410 else
1411 {
1412 assert(!"AttrArray does not range to MAXROW");
1413 pNextEnd[nPos] = rDoc.MaxRow();
1414 ppPatterns[nPos] = nullptr;
1415 }
1416 }
1417
1418 if ( nMinNextEnd > pNextEnd[nPos] )
1420
1421 // store positions of ScHorizontalAttrIterator elements (minimizing expensive ScPatternAttr comparisons)
1422 if (i > nStartCol && ppPatterns[nThisHead] != ppPatterns[nPos])
1423 {
1424 pHorizEnd[nThisHead] = i - 1;
1425 nThisHead = nPos; // start position of the next horizontal group
1426 }
1427 }
1428
1429 pHorizEnd[nThisHead] = nEndCol; // set the end position of the last horizontal group, too
1430}
1431
1433{
1434 assert(nTab < rDoc.GetTableCount() && "index out of bounds, FIX IT");
1435 for (;;)
1436 {
1437 if ( nCol <= nEndCol )
1438 {
1439 const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
1440 rRow = nRow;
1441 rCol1 = nCol;
1442 assert( pHorizEnd[nCol-nStartCol] < rDoc.MaxCol()+1 && "missing stored data" );
1444 rCol2 = nCol;
1445 ++nCol; // Count up for next call
1446 return pPat; // Found it!
1447 }
1448
1449 // Next row
1450 ++nRow;
1451 if ( nRow > nEndRow ) // Already at the end?
1452 return nullptr; // Found nothing
1453 nCol = nStartCol; // Start at the left again
1454
1455 if ( nRow > nMinNextEnd )
1456 InitForNextRow(false);
1457 }
1458}
1459
1460static bool IsGreater( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1461{
1462 return ( nRow1 > nRow2 ) || ( nRow1 == nRow2 && nCol1 > nCol2 );
1463}
1464
1466 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1467 : aCellIter( rDocument, nTable, nCol1, nRow1, nCol2, nRow2 )
1468 , aAttrIter( rDocument, nTable, nCol1, nRow1, nCol2, nRow2 )
1469 , nNextCol( nCol1 )
1470 , nNextRow( nRow1 )
1471 , nCellCol( 0 )
1472 , nCellRow( 0 )
1473 , nAttrCol1( 0 )
1474 , nAttrCol2( 0 )
1475 , nAttrRow( 0 )
1476 , nFoundStartCol( 0 )
1477 , nFoundEndCol( 0 )
1478 , nFoundRow( 0 )
1479 , pFoundPattern( nullptr )
1480{
1483}
1484
1486{
1487}
1488
1490{
1491 // Forward iterators
1494
1495 while (pCell && pCell->isEmpty())
1497
1500
1501 if ( pPattern && nAttrRow == nNextRow && nAttrCol1 < nNextCol )
1503
1504 // Find next area
1505 bool bFound = true;
1506 bool bUseCell = false;
1507
1508 if ( pCell && pPattern )
1509 {
1510 if ( IsGreater( nCellCol, nCellRow, nAttrCol1, nAttrRow ) ) // Only attributes at the beginning?
1511 {
1516 if ( nCellRow == nAttrRow && nCellCol <= nAttrCol2 ) // Area also contains cell?
1517 nFoundEndCol = nCellCol - 1; // Only until right before the cell
1518 else
1519 nFoundEndCol = nAttrCol2; // Everything
1520 }
1521 else
1522 {
1523 bUseCell = true;
1524 if ( nAttrRow == nCellRow && nAttrCol1 == nCellCol ) // Attributes on the cell?
1526 else
1527 pFoundPattern = nullptr;
1528 }
1529 }
1530 else if ( pCell ) // Just a cell -> take over right away
1531 {
1532 pFoundPattern = nullptr;
1533 bUseCell = true; // Cell position
1534 }
1535 else if ( pPattern ) // Just attributes -> take over right away
1536 {
1542 }
1543 else // Nothing
1544 bFound = false;
1545
1546 if ( bUseCell ) // Cell position
1547 {
1548 if (pCell)
1549 maFoundCell = *pCell;
1550 else
1552
1555 }
1556
1557 if (bFound)
1558 {
1560 nNextCol = nFoundEndCol + 1;
1561 }
1562
1563 return bFound;
1564}
1565
1567 SCCOL nCol1, SCROW nRow1,
1568 SCCOL nCol2, SCROW nRow2) :
1569 rDoc( rDocument ),
1570 nTab( nTable ),
1571 nEndCol( nCol2 ),
1572 nStartRow( nRow1 ),
1573 nEndRow( nRow2 ),
1574 nCol( nCol1 )
1575{
1576 if ( ValidTab(nTab) && nTab < rDoc.GetTableCount() && rDoc.maTabs[nTab] )
1577 pColIter = rDoc.maTabs[nTab]->ColumnData(nCol).CreateAttrIterator( nStartRow, nEndRow );
1578}
1579
1581{
1582}
1583
1585{
1586 while ( pColIter )
1587 {
1588 const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
1589 if ( pPattern )
1590 {
1591 rCol = nCol;
1592 return pPattern;
1593 }
1594
1595 ++nCol;
1596 if ( nCol <= nEndCol )
1597 pColIter = rDoc.maTabs[nTab]->ColumnData(nCol).CreateAttrIterator( nStartRow, nEndRow );
1598 else
1599 pColIter.reset();
1600 }
1601 return nullptr; // Nothing anymore
1602}
1603
1605 mnTab(nTab), maRanges(nMaxRow)
1606{
1607}
1608
1609ScDocRowHeightUpdater::ScDocRowHeightUpdater(ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, const vector<TabRanges>* pTabRangesArray) :
1610 mrDoc(rDoc), mpOutDev(pOutDev), mfPPTX(fPPTX), mfPPTY(fPPTY), mpTabRangesArray(pTabRangesArray)
1611{
1612}
1613
1615{
1616 if (!mpTabRangesArray || mpTabRangesArray->empty())
1617 {
1618 // No ranges defined. Update all rows in all tables.
1619 updateAll();
1620 return;
1621 }
1622
1623 sal_uInt64 nCellCount = 0;
1624 for (const auto& rTabRanges : *mpTabRangesArray)
1625 {
1626 const SCTAB nTab = rTabRanges.mnTab;
1627 if (!ValidTab(nTab) || nTab >= mrDoc.GetTableCount() || !mrDoc.maTabs[nTab])
1628 continue;
1629
1631 ScFlatBoolRowSegments::RangeIterator aRangeItr(rTabRanges.maRanges);
1632 for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
1633 {
1634 if (!aData.mbValue)
1635 continue;
1636
1637 nCellCount += mrDoc.maTabs[nTab]->GetWeightedCount(aData.mnRow1, aData.mnRow2);
1638 }
1639 }
1640
1641 ScProgress aProgress(mrDoc.GetDocumentShell(), ScResId(STR_PROGRESS_HEIGHTING), nCellCount, true);
1642
1643 Fraction aZoom(1, 1);
1644 sal_uInt64 nProgressStart = 0;
1645 for (const auto& rTabRanges : *mpTabRangesArray)
1646 {
1647 const SCTAB nTab = rTabRanges.mnTab;
1648 if (!ValidTab(nTab) || nTab >= mrDoc.GetTableCount() || !mrDoc.maTabs[nTab])
1649 continue;
1650
1651 sc::RowHeightContext aCxt(mrDoc.MaxRow(), mfPPTX, mfPPTY, aZoom, aZoom, mpOutDev);
1653 ScFlatBoolRowSegments::RangeIterator aRangeItr(rTabRanges.maRanges);
1654 for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
1655 {
1656 if (!aData.mbValue)
1657 continue;
1658
1659 mrDoc.maTabs[nTab]->SetOptimalHeight(
1660 aCxt, aData.mnRow1, aData.mnRow2, true, &aProgress, nProgressStart);
1661
1662 nProgressStart += mrDoc.maTabs[nTab]->GetWeightedCount(aData.mnRow1, aData.mnRow2);
1663 }
1664 }
1665}
1666
1668{
1669 sal_uInt64 nCellCount = 0;
1670 for (SCTAB nTab = 0; nTab < mrDoc.GetTableCount(); ++nTab)
1671 {
1672 if (!ValidTab(nTab) || !mrDoc.maTabs[nTab])
1673 continue;
1674
1675 nCellCount += mrDoc.maTabs[nTab]->GetWeightedCount();
1676 }
1677
1678 ScProgress aProgress(mrDoc.GetDocumentShell(), ScResId(STR_PROGRESS_HEIGHTING), nCellCount, true);
1679
1680 Fraction aZoom(1, 1);
1681 sc::RowHeightContext aCxt(mrDoc.MaxRow(), mfPPTX, mfPPTY, aZoom, aZoom, mpOutDev);
1682 sal_uInt64 nProgressStart = 0;
1683 for (SCTAB nTab = 0; nTab < mrDoc.GetTableCount(); ++nTab)
1684 {
1685 if (!ValidTab(nTab) || !mrDoc.maTabs[nTab])
1686 continue;
1687
1688 mrDoc.maTabs[nTab]->SetOptimalHeight(aCxt, 0, mrDoc.MaxRow(), true, &aProgress, nProgressStart);
1689 nProgressStart += mrDoc.maTabs[nTab]->GetWeightedCount();
1690 }
1691}
1692
1694 SCCOL nCol1, SCROW nRow1,
1695 SCCOL nCol2, SCROW nRow2) :
1696 rDoc( rDocument ),
1697 nTab( nTable ),
1698 nEndCol( nCol2 ),
1699 nStartRow( nRow1 ),
1700 nEndRow( nRow2 ),
1701 nIterStartCol( nCol1 ),
1702 nIterEndCol( nCol1 )
1703{
1704 if ( ValidTab(nTab) && nTab < rDoc.GetTableCount() && rDoc.maTabs[nTab] )
1705 {
1706 pColIter = rDoc.maTabs[nTab]->ColumnData(nIterStartCol).CreateAttrIterator( nStartRow, nEndRow );
1707 while ( nIterEndCol < nEndCol &&
1708 rDoc.maTabs[nTab]->ColumnData(nIterEndCol).IsAllAttrEqual(
1709 rDoc.maTabs[nTab]->ColumnData(nIterEndCol+1), nStartRow, nEndRow ) )
1710 ++nIterEndCol;
1711 }
1712}
1713
1715{
1716}
1717
1719{
1720 if (pColIter)
1721 {
1722 SCROW nNextRow = pColIter->GetNextRow();
1723 pColIter = rDoc.maTabs[nTab]->ColumnData(nIterStartCol).CreateAttrIterator( nNextRow, nEndRow );
1724 }
1725}
1726
1728 SCROW& rRow1, SCROW& rRow2 )
1729{
1730 while ( pColIter )
1731 {
1732 const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
1733 if ( pPattern )
1734 {
1735 rCol1 = nIterStartCol;
1736 rCol2 = nIterEndCol;
1737 return pPattern;
1738 }
1739
1741 if ( nIterStartCol <= nEndCol )
1742 {
1744 pColIter = rDoc.maTabs[nTab]->ColumnData(nIterStartCol).CreateAttrIterator( nStartRow, nEndRow );
1745 while ( nIterEndCol < nEndCol &&
1746 rDoc.maTabs[nTab]->ColumnData(nIterEndCol).IsAllAttrEqual(
1747 rDoc.maTabs[nTab]->ColumnData(nIterEndCol+1), nStartRow, nEndRow ) )
1748 ++nIterEndCol;
1749 }
1750 else
1751 pColIter.reset();
1752 }
1753 return nullptr; // Nothing anymore
1754}
1755
1757 mrBreaks(rBreaks),
1758 maItr(rBreaks.begin()), maEnd(rBreaks.end())
1759{
1760}
1761
1763{
1764 maItr = mrBreaks.begin();
1765 return maItr == maEnd ? NOT_FOUND : *maItr;
1766}
1767
1769{
1770 ++maItr;
1771 return maItr == maEnd ? NOT_FOUND : *maItr;
1772}
1773
1774/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
int mnIndex
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:1693
std::unique_ptr< ScAttrIterator > pColIter
Definition: dociter.hxx:281
const ScPatternAttr * GetNext(SCCOL &rCol1, SCCOL &rCol2, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1727
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:1252
sc::CellStoreType maCells
Definition: column.hxx:196
ScDocument & GetDoc() const
Definition: column.hxx:127
sal_uInt32 GetNumberFormat(const ScInterpreterContext &rContext, SCROW nRow) const
Definition: column.hxx:967
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:1584
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:1566
const ::std::vector< TabRanges > * mpTabRangesArray
Definition: dociter.hxx:470
ScDocument & mrDoc
Definition: dociter.hxx:466
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:1609
VclPtr< OutputDevice > mpOutDev
Definition: dociter.hxx:467
SC_DLLPUBLIC SCCOL GetAllocatedColumnsCount(SCTAB nTab) const
Definition: documen3.cxx:2156
SC_DLLPUBLIC ScPatternAttr * GetDefPattern() const
Definition: document.cxx:6164
bool ValidRow(SCROW nRow) const
Definition: document.hxx:899
ScTable * FetchTable(SCTAB nTab)
Definition: document.cxx:2544
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:891
SC_DLLPUBLIC bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4562
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:892
SC_DLLPUBLIC double RoundValueAsShown(double fVal, sal_uInt32 nFormat, const ScInterpreterContext *pContext=nullptr) const
Definition: documen4.cxx:634
TableContainer maTabs
Definition: document.hxx:377
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4492
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1081
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:898
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:461
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:316
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:1093
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:1344
void InitForNextRow(bool bInitialization)
Definition: dociter.cxx:1371
const ScPatternAttr * GetNext(SCCOL &rCol1, SCCOL &rCol2, SCROW &rRow)
Definition: dociter.cxx:1432
void SetTab(SCTAB nTab)
Set a(nother) sheet and (re)init.
Definition: dociter.cxx:1055
bool GetPos(SCCOL &rCol, SCROW &rRow)
Definition: dociter.cxx:1115
ScRefCellValue * GetNext(SCCOL &rCol, SCROW &rRow)
Definition: dociter.cxx:1092
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:1199
ScHorizontalValueIterator(ScDocument &rDocument, const ScRange &rRange)
Definition: dociter.cxx:1255
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:1293
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:3026
bool IsStringOrEmpty(SCSIZE nIndex) const
Definition: scmatrix.cxx:3046
bool IsEmpty(SCSIZE nC, SCSIZE nR) const
Definition: scmatrix.cxx:3056
double GetDouble(SCSIZE nC, SCSIZE nR) const
Definition: scmatrix.cxx:3011
bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
Definition: scmatrix.cxx:3086
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
Definition: patattr.cxx:1301
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:1756
static constexpr SCROW NOT_FOUND
Definition: dociter.hxx:429
::std::set< SCROW > & mrBreaks
Definition: dociter.hxx:436
ScColumn * FetchColumn(SCCOL nCol)
Definition: table2.cxx:1235
ScColContainer aCol
Definition: table.hxx:160
SCCOL GetAllocatedColumnsCount() const
Definition: table.hxx:1127
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:1465
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:1460
sal_Int32 mnRow
sal_Int32 mnCol
UNDEFINED
FormulaError
@ SC_AND
Definition: global.hxx:854
@ CELLTYPE_EDIT
Definition: global.hxx:276
@ CELLTYPE_STRING
Definition: global.hxx:274
@ CELLTYPE_FORMULA
Definition: global.hxx:275
@ CELLTYPE_VALUE
Definition: global.hxx:273
SubtotalFlags
Definition: global.hxx:239
@ SC_DOES_NOT_CONTAIN
Definition: global.hxx:845
@ SC_LESS_EQUAL
Definition: global.hxx:837
@ SC_LESS
Definition: global.hxx:835
@ SC_GREATER_EQUAL
Definition: global.hxx:838
@ SC_CONTAINS
Definition: global.hxx:844
@ SC_ENDS_WITH
Definition: global.hxx:848
@ SC_DOES_NOT_END_WITH
Definition: global.hxx:849
@ SC_BEGINS_WITH
Definition: global.hxx:846
@ SC_GREATER
Definition: global.hxx:836
@ SC_EQUAL
Definition: global.hxx:834
@ SC_NOT_EQUAL
Definition: global.hxx:839
@ SC_DOES_NOT_BEGIN_WITH
Definition: global.hxx:847
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:49
const mdds::mtv::element_t element_type_formula
Definition: mtvelements.hxx:50
ScRefCellValue toRefCell(const sc::CellStoreType::const_iterator &itPos, size_t nOffset)
mdds::mtv::soa::multi_type_vector< CellFunc, CellStoreTrait > CellStoreType
const mdds::mtv::element_t element_type_numeric
Mapped standard element types (for convenience).
Definition: mtvelements.hxx:56
const mdds::mtv::element_t element_type_string
Definition: mtvelements.hxx:48
const mdds::mtv::element_t element_type_empty
Definition: mtvelements.hxx:57
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:1604
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_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