summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/Library_sc.mk3
-rw-r--r--sc/inc/cell.hxx12
-rw-r--r--sc/inc/dociter.hxx8
-rw-r--r--sc/inc/formulaiter.hxx45
-rw-r--r--sc/source/core/data/cell.cxx57
-rw-r--r--sc/source/core/data/dociter.cxx107
-rw-r--r--sc/source/core/data/document.cxx1
-rw-r--r--sc/source/core/data/formulaiter.cxx80
-rw-r--r--sc/source/core/tool/detfunc.cxx1
-rw-r--r--sc/source/ui/Accessibility/AccessibleCell.cxx36
-rw-r--r--sc/source/ui/app/transobj.cxx1
-rw-r--r--sc/source/ui/docshell/tablink.cxx1
-rw-r--r--sc/source/ui/unoobj/cellsuno.cxx1
13 files changed, 262 insertions, 91 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 1935b7afb528..2ee7004024f6 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -143,7 +143,8 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/drawpage \
sc/source/core/data/drwlayer \
sc/source/core/data/fillinfo \
- sc/source/core/data/funcdesc \
+ sc/source/core/data/formulaiter \
+ sc/source/core/data/funcdesc \
sc/source/core/data/global \
sc/source/core/data/global2 \
sc/source/core/data/globalx \
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 4230272c793c..0d3469893625 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -602,18 +602,6 @@ public:
bool InterpretFormulaGroup();
};
-// Iterator for references in a formula cell
-class ScDetectiveRefIter
-{
-private:
- ScTokenArray* pCode;
- ScAddress aPos;
-public:
- ScDetectiveRefIter( ScFormulaCell* pCell );
- bool GetNextRef( ScRange& rRange );
- ScToken* GetNextRefToken();
-};
-
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index c104a33a8186..80f3738abc91 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -24,6 +24,7 @@
#include <tools/solar.h>
#include "global.hxx"
#include "scdllapi.h"
+#include "cellvalue.hxx"
#include <memory>
@@ -217,11 +218,13 @@ private:
ScAddress maStartPos;
ScAddress maEndPos;
ScAddress maCurPos;
+ ScCellValue maCurCell;
SCSIZE nColRow;
bool bSubTotal;
ScBaseCell* GetThis();
void init();
+ bool getCurrent();
public:
ScCellIterator(ScDocument* pDocument,
SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
@@ -232,6 +235,11 @@ public:
ScBaseCell* GetFirst();
ScBaseCell* GetNext();
const ScAddress& GetPos() const { return maCurPos; }
+
+ bool first();
+ bool next();
+
+ const ScCellValue& get() const;
};
class ScQueryCellIterator // walk through all non-empty cells in an area
diff --git a/sc/inc/formulaiter.hxx b/sc/inc/formulaiter.hxx
new file mode 100644
index 000000000000..dbde7e1b49ec
--- /dev/null
+++ b/sc/inc/formulaiter.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef SC_FORMULAITER_HXX
+#define SC_FORMULAITER_HXX
+
+#include "address.hxx"
+
+class ScTokenArray;
+class ScFormulaCell;
+class ScToken;
+
+/**
+ * Iterator for references in a formula cell.
+ */
+class ScDetectiveRefIter
+{
+private:
+ ScTokenArray* pCode;
+ ScAddress aPos;
+public:
+ ScDetectiveRefIter( ScFormulaCell* pCell );
+ bool GetNextRef( ScRange& rRange );
+ ScToken* GetNextRefToken();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 4aac6b5179b3..aa777e58d830 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1980,61 +1980,4 @@ EditTextObject* ScFormulaCell::CreateURLObject()
return CreateURLObjectFromURL( *pDocument, aURL, aCellText );
}
-// ============================================================================
-
-ScDetectiveRefIter::ScDetectiveRefIter( ScFormulaCell* pCell )
-{
- pCode = pCell->GetCode();
- pCode->Reset();
- aPos = pCell->aPos;
-}
-
-static bool lcl_ScDetectiveRefIter_SkipRef( ScToken* p )
-{
- ScSingleRefData& rRef1 = p->GetSingleRef();
- if ( rRef1.IsColDeleted() || rRef1.IsRowDeleted() || rRef1.IsTabDeleted()
- || !rRef1.Valid() )
- return true;
- if ( p->GetType() == svDoubleRef || p->GetType() == svExternalDoubleRef )
- {
- ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
- if ( rRef2.IsColDeleted() || rRef2.IsRowDeleted() || rRef2.IsTabDeleted()
- || !rRef2.Valid() )
- return true;
- }
- return false;
-}
-
-bool ScDetectiveRefIter::GetNextRef( ScRange& rRange )
-{
- bool bRet = false;
- ScToken* p = GetNextRefToken();
- if( p )
- {
- SingleDoubleRefProvider aProv( *p );
- rRange.aStart.Set( aProv.Ref1.nCol, aProv.Ref1.nRow, aProv.Ref1.nTab );
- rRange.aEnd.Set( aProv.Ref2.nCol, aProv.Ref2.nRow, aProv.Ref2.nTab );
- bRet = true;
- }
-
- return bRet;
-}
-
-ScToken* ScDetectiveRefIter::GetNextRefToken()
-{
- ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
- if (p)
- p->CalcAbsIfRel( aPos );
-
- while ( p && lcl_ScDetectiveRefIter_SkipRef( p ) )
- {
- p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
- if (p)
- p->CalcAbsIfRel( aPos );
- }
- return p;
-}
-
-// ============================================================================
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index d5417d5cb5ed..5446bbc09d3f 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -36,12 +36,12 @@
#include "queryentry.hxx"
#include "globstr.hrc"
#include "tools/fract.hxx"
+#include "editeng/editobj.hxx"
#include <vector>
using ::rtl::math::approxEqual;
using ::std::vector;
-using ::rtl::OUString;
using ::std::set;
// STATIC DATA -----------------------------------------------------------
@@ -1051,6 +1051,111 @@ ScBaseCell* ScCellIterator::GetNext()
return GetThis();
}
+bool ScCellIterator::getCurrent()
+{
+ ScColumn* pCol = &(pDoc->maTabs[maCurPos.Tab()])->aCol[maCurPos.Col()];
+ while (true)
+ {
+ if (maCurPos.Row() > maEndPos.Row())
+ {
+ maCurPos.SetRow(maStartPos.Row());
+ do
+ {
+ maCurPos.IncCol();
+ if (maCurPos.Col() > maEndPos.Col())
+ {
+ maCurPos.SetCol(maStartPos.Col());
+ maCurPos.IncTab();
+ if (maCurPos.Tab() > maEndPos.Tab())
+ {
+ maCurCell.clear();
+ return false; // Over and out
+ }
+ }
+ pCol = &(pDoc->maTabs[maCurPos.Tab()])->aCol[maCurPos.Col()];
+ } while ( pCol->maItems.empty() );
+ pCol->Search(maCurPos.Row(), nColRow);
+ }
+
+ while ( (nColRow < pCol->maItems.size()) && (pCol->maItems[nColRow].nRow < maCurPos.Row()) )
+ ++nColRow;
+
+ if (nColRow < pCol->maItems.size() && pCol->maItems[nColRow].nRow <= maEndPos.Row())
+ {
+ maCurPos.SetRow(pCol->maItems[nColRow].nRow);
+ if (!bSubTotal || !pDoc->maTabs[maCurPos.Tab()]->RowFiltered(maCurPos.Row()))
+ {
+ ScBaseCell* pCell = pCol->maItems[nColRow].pCell;
+
+ if ( bSubTotal && pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->IsSubTotal() )
+ maCurPos.IncRow(); // Don't subtotal rows
+ else
+ {
+ // Found it!
+ maCurCell.clear();
+ maCurCell.meType = pCell->GetCellType();
+ switch (maCurCell.meType)
+ {
+ case CELLTYPE_VALUE:
+ maCurCell.mfValue = static_cast<const ScValueCell*>(pCell)->GetValue();
+ break;
+ case CELLTYPE_STRING:
+ {
+ const OUString& rStr = static_cast<const ScStringCell*>(pCell)->GetString();
+ maCurCell.mpString = new OUString(rStr);
+ }
+ break;
+ case CELLTYPE_EDIT:
+ {
+ const EditTextObject* pData = static_cast<const ScEditCell*>(pCell)->GetData();
+ maCurCell.mpEditText = pData->Clone();
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ maCurCell.mpFormula = static_cast<const ScFormulaCell*>(pCell)->Clone();
+ break;
+ default:
+ maCurCell.meType = CELLTYPE_NONE;
+ }
+
+ if (maCurCell.meType != CELLTYPE_NONE)
+ return true;
+
+ maCurPos.IncRow();
+ }
+ }
+ else
+ maCurPos.IncRow();
+ }
+ else
+ maCurPos.SetRow(maEndPos.Row() + 1); // Next column
+ }
+ return false;
+}
+
+bool ScCellIterator::first()
+{
+ if (!ValidTab(maCurPos.Tab()))
+ return false;
+
+ maCurPos = maStartPos;
+ ScColumn* pCol = &(pDoc->maTabs[maCurPos.Tab()])->aCol[maCurPos.Col()];
+ pCol->Search(maCurPos.Row(), nColRow);
+ return getCurrent();
+}
+
+bool ScCellIterator::next()
+{
+ maCurPos.IncRow();
+ return getCurrent();
+}
+
+const ScCellValue& ScCellIterator::get() const
+{
+ return maCurCell;
+}
+
//-------------------------------------------------------------------------------
ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index dcdb2abc35d6..a0ec2342cfa2 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -88,6 +88,7 @@
#include "defaultsoptions.hxx"
#include "editutil.hxx"
#include "stringutil.hxx"
+#include "formulaiter.hxx"
#include <map>
#include <limits>
diff --git a/sc/source/core/data/formulaiter.cxx b/sc/source/core/data/formulaiter.cxx
new file mode 100644
index 000000000000..4a28acf2156d
--- /dev/null
+++ b/sc/source/core/data/formulaiter.cxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "formulaiter.hxx"
+
+#include "cell.hxx"
+#include "formula/token.hxx"
+
+using namespace formula;
+
+ScDetectiveRefIter::ScDetectiveRefIter( ScFormulaCell* pCell )
+{
+ pCode = pCell->GetCode();
+ pCode->Reset();
+ aPos = pCell->aPos;
+}
+
+static bool lcl_ScDetectiveRefIter_SkipRef( ScToken* p )
+{
+ ScSingleRefData& rRef1 = p->GetSingleRef();
+ if ( rRef1.IsColDeleted() || rRef1.IsRowDeleted() || rRef1.IsTabDeleted()
+ || !rRef1.Valid() )
+ return true;
+ if ( p->GetType() == svDoubleRef || p->GetType() == svExternalDoubleRef )
+ {
+ ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
+ if ( rRef2.IsColDeleted() || rRef2.IsRowDeleted() || rRef2.IsTabDeleted()
+ || !rRef2.Valid() )
+ return true;
+ }
+ return false;
+}
+
+bool ScDetectiveRefIter::GetNextRef( ScRange& rRange )
+{
+ bool bRet = false;
+ ScToken* p = GetNextRefToken();
+ if( p )
+ {
+ SingleDoubleRefProvider aProv( *p );
+ rRange.aStart.Set( aProv.Ref1.nCol, aProv.Ref1.nRow, aProv.Ref1.nTab );
+ rRange.aEnd.Set( aProv.Ref2.nCol, aProv.Ref2.nRow, aProv.Ref2.nTab );
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+ScToken* ScDetectiveRefIter::GetNextRefToken()
+{
+ ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ if (p)
+ p->CalcAbsIfRel( aPos );
+
+ while ( p && lcl_ScDetectiveRefIter_SkipRef( p ) )
+ {
+ p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ if (p)
+ p->CalcAbsIfRel( aPos );
+ }
+ return p;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index 359e95eac13e..57981eccabd4 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -66,6 +66,7 @@
#include "postit.hxx"
#include "rangelst.hxx"
#include "reftokenhelper.hxx"
+#include "formulaiter.hxx"
#include <vector>
diff --git a/sc/source/ui/Accessibility/AccessibleCell.cxx b/sc/source/ui/Accessibility/AccessibleCell.cxx
index 95ac6ebb2ce2..33a99a1c2826 100644
--- a/sc/source/ui/Accessibility/AccessibleCell.cxx
+++ b/sc/source/ui/Accessibility/AccessibleCell.cxx
@@ -30,8 +30,9 @@
#include "miscuno.hxx"
#include "editsrc.hxx"
#include "dociter.hxx"
-#include "cell.hxx"
#include "markdata.hxx"
+#include "cellvalue.hxx"
+#include "formulaiter.hxx"
#include <unotools/accessiblestatesethelper.hxx>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
@@ -361,43 +362,38 @@ void ScAccessibleCell::FillDependends(utl::AccessibleRelationSetHelper* pRelatio
{
if (mpDoc)
{
- ScCellIterator aCellIter( mpDoc, 0,0, maCellAddress.Tab(), MAXCOL,MAXROW, maCellAddress.Tab() );
- ScBaseCell* pCell = aCellIter.GetFirst();
- while (pCell)
+ ScRange aRange(0, 0, maCellAddress.Tab(), MAXCOL, MAXROW, maCellAddress.Tab());
+ ScCellIterator aCellIter(mpDoc, aRange);
+
+ for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next())
{
- if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ const ScCellValue& rVal = aCellIter.get();
+ if (rVal.meType == CELLTYPE_FORMULA)
{
- sal_Bool bFound(false);
- ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ bool bFound = false;
+ ScDetectiveRefIter aIter(rVal.mpFormula);
ScRange aRef;
while ( !bFound && aIter.GetNextRef( aRef ) )
{
if (aRef.In(maCellAddress))
- bFound = sal_True;
+ bFound = true;
}
if (bFound)
AddRelation(aCellIter.GetPos(), AccessibleRelationType::CONTROLLER_FOR, pRelationSet);
}
- pCell = aCellIter.GetNext();
}
}
}
void ScAccessibleCell::FillPrecedents(utl::AccessibleRelationSetHelper* pRelationSet)
{
- if (mpDoc)
+ if (mpDoc && mpDoc->GetCellType(maCellAddress) == CELLTYPE_FORMULA)
{
- ScBaseCell* pBaseCell = mpDoc->GetCell(maCellAddress);
- if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_FORMULA))
+ ScDetectiveRefIter aIter(mpDoc->GetFormulaCell(maCellAddress));
+ ScRange aRef;
+ while ( aIter.GetNextRef( aRef ) )
{
- ScFormulaCell* pFCell = (ScFormulaCell*) pBaseCell;
-
- ScDetectiveRefIter aIter( pFCell );
- ScRange aRef;
- while ( aIter.GetNextRef( aRef ) )
- {
- AddRelation( aRef, AccessibleRelationType::CONTROLLED_BY, pRelationSet);
- }
+ AddRelation( aRef, AccessibleRelationType::CONTROLLED_BY, pRelationSet);
}
}
}
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 71046f43acb2..b98c05527b2a 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -62,6 +62,7 @@
#include "dociter.hxx"
#include "cellsuno.hxx"
#include "stringutil.hxx"
+#include "formulaiter.hxx"
using namespace com::sun::star;
diff --git a/sc/source/ui/docshell/tablink.cxx b/sc/source/ui/docshell/tablink.cxx
index a16f51ba1279..9105ee293886 100644
--- a/sc/source/ui/docshell/tablink.cxx
+++ b/sc/source/ui/docshell/tablink.cxx
@@ -42,6 +42,7 @@
#include "dociter.hxx"
#include "formula/opcode.hxx"
#include "cell.hxx"
+#include "formulaiter.hxx"
using ::rtl::OUString;
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 4ee76daf2582..a64feb1a448f 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -120,6 +120,7 @@
#include "formula/grammar.hxx"
#include "editeng/escapementitem.hxx"
#include "stringutil.hxx"
+#include "formulaiter.hxx"
#include <list>
#include <boost/scoped_ptr.hpp>