summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
Diffstat (limited to 'sc')
-rw-r--r--sc/CppunitTest_sc_ucalc.mk90
-rw-r--r--sc/Module_sc.mk22
-rw-r--r--sc/Package_qa_unit.mk44
-rw-r--r--sc/inc/address.hxx2
-rw-r--r--sc/inc/dbcolect.hxx2
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/reffind.hxx5
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/qa/unit/Makefile53
-rw-r--r--sc/qa/unit/makefile.mk132
-rw-r--r--sc/qa/unit/ucalc.cxx123
-rw-r--r--sc/source/core/data/documen3.cxx8
-rw-r--r--sc/source/core/data/table2.cxx14
-rw-r--r--sc/source/core/data/table4.cxx263
-rw-r--r--sc/source/core/tool/compiler.cxx1
-rw-r--r--sc/source/core/tool/dbcolect.cxx26
-rw-r--r--sc/source/core/tool/reffind.cxx196
-rw-r--r--sc/source/filter/excel/excform.cxx19
-rw-r--r--sc/source/filter/excel/excform8.cxx83
-rw-r--r--sc/source/filter/excel/read.cxx4
-rw-r--r--sc/source/filter/excel/xilink.cxx234
-rw-r--r--sc/source/filter/excel/xistyle.cxx4
-rw-r--r--sc/source/filter/inc/excform.hxx11
-rw-r--r--sc/source/filter/inc/xilink.hxx23
-rw-r--r--sc/source/ui/docshell/impex.cxx13
-rw-r--r--sc/source/ui/vba/vbaworkbook.hxx2
-rw-r--r--sc/source/ui/vba/vbaworksheet.cxx117
-rw-r--r--sc/source/ui/vba/vbaworksheet.hxx4
-rw-r--r--sc/source/ui/vba/vbaworksheets.cxx39
-rw-r--r--sc/source/ui/vba/vbaworksheets.hxx1
-rw-r--r--sc/source/ui/view/editsh.cxx7
-rw-r--r--sc/source/ui/view/viewfun4.cxx2
32 files changed, 1139 insertions, 408 deletions
diff --git a/sc/CppunitTest_sc_ucalc.mk b/sc/CppunitTest_sc_ucalc.mk
new file mode 100644
index 000000000000..5a92c164b2a7
--- /dev/null
+++ b/sc/CppunitTest_sc_ucalc.mk
@@ -0,0 +1,90 @@
+#*************************************************************************
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License or as specified alternatively below. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Bjoern Michaelsen, Canonical Ltd. <bjoern.michaelsen@canonical.com>
+# Portions created by the Initial Developer are Copyright (C) 2010 the
+# Initial Developer. All Rights Reserved.
+#
+# Major Contributor(s):
+#
+# For minor contributions see the git repository.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sc_ucalc))
+
+$(eval $(call gb_CppunitTest_add_package_headers,sc_ucalc,sc_qa_unit))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sc_ucalc, \
+ sc/qa/unit/ucalc \
+))
+
+$(eval $(call gb_CppunitTest_set_args,sc_ucalc,\
+ --headless \
+ --invisible \
+ "-env:UNO_TYPES=$(foreach binrdb,udkapi.rdb types.rdb,\
+ file://$(if $(filter WNT,$(OS)),/)$(OUTDIR)/bin/$(binrdb))" \
+ "-env:UNO_SERVICES=$(foreach rdb,$(OUTDIR)/xml/ure/services.rdb $(WORKDIR)/CustomTarget/sc/qa/unit/services.rdb,\
+ file://$(if $(filter WNT,$(OS)),/)$(rdb))" \
+ $(foreach dir,URE_INTERNAL_LIB_DIR OOO_BASE_DIR BRAND_BASE_DIR, \
+ -env:$(dir)=file://$(if $(filter WNT,$(OS)),/$(OUTDIR)/bin,$(OUTDIR)/lib)) \
+))
+
+$(eval $(call gb_CppunitTest_add_library_objects,sc_ucalc,sc))
+
+$(eval $(call gb_CppunitTest_add_linked_libs,sc_ucalc, \
+ avmedia \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ for \
+ forui \
+ i18nisolang1 \
+ sal \
+ salhelper \
+ sb \
+ sfx \
+ sot \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ tk \
+ tl \
+ ucbhelper \
+ utl \
+ vbahelper \
+ vcl \
+ xo \
+ $(gb_STDLIBS) \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sc_ucalc,\
+ -I$(realpath $(SRCDIR)/sc/inc/pch) \
+ -I$(realpath $(SRCDIR)/sc/source/ui/inc) \
+ -I$(realpath $(SRCDIR)/sc/inc) \
+ $$(INCLUDE) \
+ -I$(OUTDIR)/inc/offuh \
+ -I$(OUTDIR)/inc \
+))
+
+# vim: set noet sw=4:
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index 6878587be498..7cd8ba891ac7 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -23,13 +23,19 @@
$(eval $(call gb_Module_Module,sc))
$(eval $(call gb_Module_add_targets,sc,\
- AllLangResTarget_sc \
- Library_sc \
- Library_scd \
- Library_scfilt \
- Library_scui \
- Library_vbaobj \
- Package_uiconfig \
- Package_xml \
+ AllLangResTarget_sc \
+ Library_sc \
+ Library_scd \
+ Library_scfilt \
+ Library_scui \
+ Library_vbaobj \
+ Package_uiconfig \
+ Package_xml \
))
+$(eval $(call gb_Module_add_check_targets,sc,\
+ CppunitTest_sc_ucalc \
+ Package_qa_unit \
+))
+
+# vim: set noet ts=4 sw=4:
diff --git a/sc/Package_qa_unit.mk b/sc/Package_qa_unit.mk
new file mode 100644
index 000000000000..8db8cb798f07
--- /dev/null
+++ b/sc/Package_qa_unit.mk
@@ -0,0 +1,44 @@
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Bjoern Michaelsen <bjoern.michaelsen@canonical.com> (Canonical Ltd.)
+# Portions created by the Initial Developer are Copyright (C) 2011 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s): Bjoern Michaelsen <bjoern.michaelsen@canonical.com> (Canonical Ltd.)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Package_Package,sc_qa_unit,$(WORKDIR)/CustomTarget/sc/qa/unit))
+$(eval $(call gb_Package_add_customtarget,sc_qa_unit,sc/qa/unit))
+
+# dependencies that cause the CustomTarget Makefile to be called recursively for
+# (re)build
+$(eval $(call gb_CustomTarget_add_outdir_dependencies,sc/qa/unit,\
+ $(foreach newcomponentfile,\
+ framework/util/fwk \
+ sfx2/util/sfx \
+ unoxml/source/service/unoxml,\
+ $(OUTDIR)/xml/component/$(newcomponentfile).component) \
+ $(foreach oldcomponentfile, \
+ i18npool \
+ ucb1 \
+ ucpfile1, \
+ $(OUTDIR)/xml/$(oldcomponentfile).component) \
+))
+
+# vim: set noet sw=4:
diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index 96842785c8f3..74920c7575b7 100644
--- a/sc/inc/address.hxx
+++ b/sc/inc/address.hxx
@@ -487,7 +487,7 @@ public:
const ::com::sun::star::uno::Sequence<
const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
- sal_uInt16 ParseAny( const String&, ScDocument* = NULL,
+ SC_DLLPUBLIC sal_uInt16 ParseAny( const String&, ScDocument* = NULL,
const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
SC_DLLPUBLIC sal_uInt16 ParseCols( const String&, ScDocument* = NULL,
const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
diff --git a/sc/inc/dbcolect.hxx b/sc/inc/dbcolect.hxx
index 8583b710e437..8f26f667f5f8 100644
--- a/sc/inc/dbcolect.hxx
+++ b/sc/inc/dbcolect.hxx
@@ -122,6 +122,7 @@ public:
bool operator== (const ScDBData& rData) const;
+ SCTAB GetTable() const;
const String& GetName() const { return aName; }
void GetName(String& rName) const { rName = aName; }
void SetName(const String& rName) { aName = rName; }
@@ -214,6 +215,7 @@ public:
virtual sal_Bool IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const;
ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const;
ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
+ ScDBData* GetFilterDBAtTable(SCTAB nTab) const;
ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab );
sal_Bool SearchName( const String& rName, sal_uInt16& rIndex ) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index f41edffbe291..901bc3615ac2 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -484,6 +484,8 @@ public:
ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab,
sal_Bool bStartOnly = false) const;
ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
+ ScDBData* GetFilterDBAtTable(SCTAB nTab) const;
+
SC_DLLPUBLIC const ScRangeData* GetRangeAtBlock( const ScRange& rBlock, String* pName=NULL ) const;
diff --git a/sc/inc/reffind.hxx b/sc/inc/reffind.hxx
index cc2f330194e9..63dcf12c65e8 100644
--- a/sc/inc/reffind.hxx
+++ b/sc/inc/reffind.hxx
@@ -42,14 +42,13 @@ private:
String aFormula;
formula::FormulaGrammar::AddressConvention eConv;
ScDocument* pDoc;
+ ScAddress maPos;
xub_StrLen nFound;
xub_StrLen nSelStart;
xub_StrLen nSelEnd;
public:
- static const sal_Unicode pDelimiters[];
-
- ScRefFinder( const String& rFormula,
+ ScRefFinder( const String& rFormula, const ScAddress& rPos,
ScDocument* pDocument = NULL,
formula::FormulaGrammar::AddressConvention eConvP = formula::FormulaGrammar::CONV_OOO );
~ScRefFinder();
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 14f8ddf821bb..5e22e5b1c9b8 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -690,6 +690,7 @@ public:
/// @return the index of the last changed row (flags and row height, auto pagebreak is ignored).
SCROW GetLastChangedRow() const;
+ bool IsDataFiltered() const;
sal_uInt8 GetColFlags( SCCOL nCol ) const;
sal_uInt8 GetRowFlags( SCROW nRow ) const;
diff --git a/sc/qa/unit/Makefile b/sc/qa/unit/Makefile
new file mode 100644
index 000000000000..87694f116f34
--- /dev/null
+++ b/sc/qa/unit/Makefile
@@ -0,0 +1,53 @@
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Bjoern Michaelsen <bjoern.michaelsen@canonical.com> (Canonical Ltd.)
+# Portions created by the Initial Developer are Copyright (C) 2011 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s): Bjoern Michaelsen <bjoern.michaelsen@canonical.com> (Canonical Ltd.)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+MYDIR := $(realpath $(dir $(firstword $(MAKEFILE_LIST))))
+
+all : services.rdb
+
+services.rdb : $(foreach newcomponentfile,\
+ framework/util/fwk \
+ sfx2/util/sfx \
+ unoxml/source/service/unoxml,\
+ $(OUTDIR)/xml/component/$(newcomponentfile).component \
+)
+
+services.rdb : $(foreach oldcomponentfile, \
+ i18npool \
+ ucb1 \
+ ucpfile1, \
+ $(OUTDIR)/xml/$(oldcomponentfile).component \
+)
+
+services.rdb :
+ echo '<?xml version="1.0"?><components xmlns="http://openoffice.org/2010/uno-components">' > $@
+ $(gb_AWK) -- \
+ '/^<\?xml version.*/ { next; } \
+ { gsub(/vnd.sun.star.expand:\$$OOO_BASE_DIR\/program/, "vnd.sun.star.expand:$$OOO_BASE_DIR",$$0); gsub(/vnd.sun.star.expand:\$$BRAND_BASE_DIR\/program/, "vnd.sun.star.expand:$$BRAND_BASE_DIR",$$0); print; }' \
+ $^ >> $@
+ echo '</components>' >> $@
+
+.PHONY : all
+# vim: set noet sw=4 ts=4:
diff --git a/sc/qa/unit/makefile.mk b/sc/qa/unit/makefile.mk
deleted file mode 100644
index d252433fd56b..000000000000
--- a/sc/qa/unit/makefile.mk
+++ /dev/null
@@ -1,132 +0,0 @@
-# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-#
-# Version: MPL 1.1 / GPLv3+ / LGPLv3+
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (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.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Initial Developer of the Original Code is
-# Novell, Inc.
-# Portions created by the Initial Developer are Copyright (C) 2010 the
-# Initial Developer. All Rights Reserved.
-#
-# Contributor(s): Michael Meeks <michael.meeks@novell.com>
-# Caolan McNamara <caolanm@redhat.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
-# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
-# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
-# instead of those above.
-#
-
-PRJ=..$/..
-PRJNAME=sc
-TARGET=qa_unit
-
-ENABLE_EXCEPTIONS=TRUE
-
-.INCLUDE : settings.mk
-
-CFLAGSCXX += $(CPPUNIT_CFLAGS) -I../../source/ui/inc
-
-SHL1TARGET = $(TARGET)
-SHL1OBJS = $(SLO)$/ucalc.obj
-SHL1STDLIBS= \
- $(BASICLIB) \
- $(VBAHELPERLIB) \
- $(SFXLIB) \
- $(SVTOOLLIB) \
- $(SVLLIB) \
- $(SVXCORELIB) \
- $(EDITENGLIB) \
- $(SVXLIB) \
- $(BASEGFXLIB) \
- $(DRAWINGLAYERLIB) \
- $(VCLLIB) \
- $(CPPULIB) \
- $(CPPUHELPERLIB) \
- $(COMPHELPERLIB) \
- $(UCBHELPERLIB) \
- $(TKLIB) \
- $(VOSLIB) \
- $(SALLIB) \
- $(SALHELPERLIB) \
- $(TOOLSLIB) \
- $(I18NISOLANGLIB) \
- $(UNOTOOLSLIB) \
- $(SOTLIB) \
- $(XMLOFFLIB) \
- $(AVMEDIALIB) \
- $(FORLIB) \
- $(FORUILIB) \
- $(CPPUNITLIB)
-SHL1IMPLIB = i$(SHL1TARGET)
-SHL1LIBS=$(SLB)$/scalc3.lib $(SLB)$/scalc3c.lib
-DEF1NAME = $(SHL1TARGET)
-SHL1VERSIONMAP=version.map
-
-.INCLUDE: target.mk
-
-.IF "$(OS)" == "WNT"
-my_file = file:///
-.ELSE
-my_file = file://
-.END
-
-ALLTAR: test
-
-test_components = \
- component/framework/util/fwk \
- component/sfx2/util/sfx \
- component/unoxml/source/service/unoxml \
- ucb1 \
- ucpfile1 \
- i18npool
-
-#Make a services.rdb with the services we know we need to get up and running
-$(MISC)/$(TARGET)/services.input : makefile.mk
- $(MKDIRHIER) $(@:d)
- echo \
- '<list>$(test_components:^"<filename>":+".component</filename>")</list>' \
- > $@
-
-$(MISC)/$(TARGET)/services.rdb .ERRREMOVE : makefile.mk $(MISC)/$(TARGET)/services.input
- $(MKDIRHIER) $(@:d)
- $(XSLTPROC) --nonet --stringparam prefix $(SOLARXMLDIR)/ -o $@.tmp \
- $(SOLARENV)/bin/packcomponents.xslt $(MISC)/$(TARGET)/services.input
- cat $(MISC)/$@.tmp | sed 's|/program/|/|g' > $@
-
-#Tweak things so that we use the .res files in the solver
-STAR_RESOURCEPATH:=$(PWD)/$(BIN)$(PATH_SEPERATOR)$(SOLARBINDIR)
-.EXPORT : STAR_RESOURCEPATH
-
-.IF "$(OS)" != "DRAGONFLY"
-
-test .PHONY: $(SHL1TARGETN) $(MISC)/$(TARGET)/services.rdb
- @echo ----------------------------------------------------------
- @echo - start unit test \#1 on library $(SHL1TARGETN)
- @echo ----------------------------------------------------------
- $(CPPUNITTESTER) $(SHL1TARGETN) --headless --invisible \
- '-env:UNO_TYPES=$(my_file)$(SOLARBINDIR)/udkapi.rdb $(my_file)$(SOLARBINDIR)$/types.rdb' \
- '-env:UNO_SERVICES=$(my_file)$(SOLARXMLDIR)/ure/services.rdb $(my_file)$(PWD)/$(MISC)/$(TARGET)/services.rdb'\
- -env:URE_INTERNAL_LIB_DIR="$(my_file)$(SOLARSHAREDBIN)" \
- -env:OOO_BASE_DIR="$(my_file)$(SOLARSHAREDBIN)" \
- -env:BRAND_BASE_DIR="$(my_file)$(SOLARSHAREDBIN)"
-
-.ELSE
-
-test .PHONY: $(SHL1TARGETN)
- @echo ----------------------------------------------------------
- @echo - WARNING!!, test disabled on your platform
- @echo - Please test manually, and enable if it works
- @echo ----------------------------------------------------------
-
-.ENDIF
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d742718417ad..4d15f31a6371 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -39,12 +39,8 @@
// the need for manually calling regcomp and knowing what
// services we need, and in what .so they are implemented
-#include "precompiled_sc.hxx"
-#include <cppunit/TestAssert.h>
-#include <cppunit/TestFixture.h>
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/plugin/TestPlugIn.h>
+#include <sal/cppunit.h>
#include <sal/config.h>
#include <osl/file.hxx>
@@ -61,6 +57,7 @@
#include "scmatrix.hxx"
#include "drwlayer.hxx"
#include "scitems.hxx"
+#include "reffind.hxx"
#include "docsh.hxx"
#include "funcdesc.hxx"
@@ -229,6 +226,7 @@ public:
void testInput();
void testSUM();
void testVolatileFunc();
+ void testFuncParam();
void testNamedRange();
void testCSV();
void testMatrix();
@@ -255,11 +253,19 @@ public:
*/
void testCVEs();
+ /**
+ * Test toggling relative/absolute flag of cell and cell range references.
+ * This corresponds with hitting Shift-F4 while the cursor is on a formula
+ * cell.
+ */
+ void testToggleRefFlag();
+
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testCollator);
CPPUNIT_TEST(testInput);
CPPUNIT_TEST(testSUM);
CPPUNIT_TEST(testVolatileFunc);
+ CPPUNIT_TEST(testFuncParam);
CPPUNIT_TEST(testNamedRange);
CPPUNIT_TEST(testCSV);
CPPUNIT_TEST(testMatrix);
@@ -271,6 +277,7 @@ public:
CPPUNIT_TEST(testStreamValid);
CPPUNIT_TEST(testFunctionLists);
CPPUNIT_TEST(testCVEs);
+ CPPUNIT_TEST(testToggleRefFlag);
CPPUNIT_TEST_SUITE_END();
private:
@@ -412,6 +419,29 @@ void Test::testVolatileFunc()
m_pDoc->DeleteTab(0);
}
+void Test::testFuncParam()
+{
+ rtl::OUString aTabName(RTL_CONSTASCII_USTRINGPARAM("foo"));
+ CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet",
+ m_pDoc->InsertTab (0, aTabName));
+
+ // First, the normal case, with no missing parameters.
+ m_pDoc->SetString(0, 0, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=AVERAGE(1;2;3)")));
+ m_pDoc->CalcFormulaTree(false, true);
+ double val;
+ m_pDoc->GetValue(0, 0, 0, val);
+ CPPUNIT_ASSERT_MESSAGE("incorrect result", val == 2);
+
+ // Now function with missing parameters. Missing values should be treated
+ // as zeros.
+ m_pDoc->SetString(0, 0, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=AVERAGE(1;;;)")));
+ m_pDoc->CalcFormulaTree(false, true);
+ m_pDoc->GetValue(0, 0, 0, val);
+ CPPUNIT_ASSERT_MESSAGE("incorrect result", val == 0.25);
+
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testNamedRange()
{
rtl::OUString aTabName(RTL_CONSTASCII_USTRINGPARAM("Sheet1"));
@@ -491,15 +521,15 @@ void Test::testCVEs()
bool bResult;
bResult = testLoad(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Quattro Pro 6.0")),
- m_aPWDURL + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/CVE/CVE-2007-5745-1.wb2")));
+ m_aPWDURL + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/qa/unit/CVE/CVE-2007-5745-1.wb2")));
CPPUNIT_ASSERT_MESSAGE("CVE-2007-5745 regression", bResult == true);
bResult = testLoad(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Quattro Pro 6.0")),
- m_aPWDURL + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/CVE/CVE-2007-5745-2.wb2")));
+ m_aPWDURL + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/qa/unit/CVE/CVE-2007-5745-2.wb2")));
CPPUNIT_ASSERT_MESSAGE("CVE-2007-5745 regression", bResult == true);
bResult = testLoad(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Quattro Pro 6.0")),
- m_aPWDURL + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/CVE/CVE-2007-5747-1.wb2")));
+ m_aPWDURL + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/qa/unit/CVE/CVE-2007-5747-1.wb2")));
CPPUNIT_ASSERT_MESSAGE("CVE-2007-5747 regression", bResult == false);
}
@@ -1619,6 +1649,83 @@ void Test::testGraphicsInGroup()
m_pDoc->DeleteTab(0);
}
+void Test::testToggleRefFlag()
+{
+ // In this test, there is no need to insert formula string into a cell in
+ // the document, as ScRefFinder does not depend on the content of the
+ // document except for the sheet names.
+
+ OUString aTabName(RTL_CONSTASCII_USTRINGPARAM("Test"));
+ m_pDoc->InsertTab(0, aTabName);
+
+ {
+ // Calc A1: basic 2D reference
+
+ OUString aFormula(RTL_CONSTASCII_USTRINGPARAM("=B100"));
+ ScAddress aPos(1, 5, 0);
+ ScRefFinder aFinder(aFormula, aPos, m_pDoc, formula::FormulaGrammar::CONV_OOO);
+
+ // Original
+ CPPUNIT_ASSERT_MESSAGE("Does not equal the original text.", aFormula.equals(aFinder.GetText()));
+
+ // column relative / row relative -> column absolute / row absolute
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=$B$100"));
+
+ // column absolute / row absolute -> column relative / row absolute
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=B$100"));
+
+ // column relative / row absolute -> column absolute / row relative
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=$B100"));
+
+ // column absolute / row relative -> column relative / row relative
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=B100"));
+ }
+
+ {
+ // Excel R1C1: basic 2D reference
+
+ OUString aFormula(RTL_CONSTASCII_USTRINGPARAM("=R2C1"));
+ ScAddress aPos(3, 5, 0);
+ ScRefFinder aFinder(aFormula, aPos, m_pDoc, formula::FormulaGrammar::CONV_XL_R1C1);
+
+ // Original
+ CPPUNIT_ASSERT_MESSAGE("Does not equal the original text.", aFormula.equals(aFinder.GetText()));
+
+ // column absolute / row absolute -> column relative / row absolute
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=R2C[-3]"));
+
+ // column relative / row absolute - > column absolute / row relative
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=R[-4]C1"));
+
+ // column absolute / row relative -> column relative / row relative
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=R[-4]C[-3]"));
+
+ // column relative / row relative -> column absolute / row absolute
+ aFinder.ToggleRel(0, aFormula.getLength());
+ aFormula = aFinder.GetText();
+ CPPUNIT_ASSERT_MESSAGE("Wrong conversion.", aFormula.equalsAscii("=R2C1"));
+ }
+
+ // TODO: Add more test cases esp. for 3D references, Excel A1 syntax, and
+ // partial selection within formula string.
+
+ m_pDoc->DeleteTab(0);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 888b1a16d551..583ea6cc8956 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -238,6 +238,14 @@ ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nC
return NULL;
}
+ScDBData* ScDocument::GetFilterDBAtTable(SCTAB nTab) const
+{
+ if (pDBCollection)
+ return pDBCollection->GetFilterDBAtTable(nTab);
+ else
+ return NULL;
+}
+
ScDPCollection* ScDocument::GetDPCollection()
{
if (!pDPCollection)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 7293cf1eed04..646be060b6a9 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2628,6 +2628,20 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
DecRecalcLevel();
}
+bool ScTable::IsDataFiltered() const
+{
+ bool bAnyQuery = false;
+ ScDBData* pDBData = pDocument->GetFilterDBAtTable(nTab);
+ if ( pDBData )
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam );
+ if ( aParam.GetEntry(0).bDoQuery )
+ bAnyQuery = true;
+ }
+ return bAnyQuery;
+}
+
void ScTable::SetColFlags( SCCOL nCol, sal_uInt8 nNewFlags )
{
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index e7ba2153a3f1..55b4da849665 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -79,6 +79,7 @@
#include "rangenam.hxx"
#include "docpool.hxx"
#include "progress.hxx"
+#include "segmenttree.hxx"
#include <math.h>
@@ -199,7 +200,7 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
rMinDigits = 0;
rListData = NULL;
rCmd = FILL_SIMPLE;
- if ( nScFillModeMouseModifier & KEY_MOD1 )
+ if ( (nScFillModeMouseModifier & KEY_MOD1) || IsDataFiltered() )
return ; // Ctrl-Taste: Copy
SCCOL nAddX;
@@ -525,10 +526,15 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
sal_uLong nIMin = nIStart;
sal_uLong nIMax = nIEnd;
PutInOrder(nIMin,nIMax);
- if (bVertical)
- DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL);
- else
- DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL);
+ sal_Bool bHasFiltered = IsDataFiltered();
+
+ if (!bHasFiltered)
+ {
+ if (bVertical)
+ DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL);
+ else
+ DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL);
+ }
sal_uLong nProgress = rProgress.GetState();
@@ -575,7 +581,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
pNewPattern = NULL;
}
- if ( bVertical && nISrcStart == nISrcEnd )
+ if ( bVertical && nISrcStart == nISrcEnd && !bHasFiltered )
{
// Attribute komplett am Stueck setzen
if (pNewPattern || pSrcPattern != pDocument->GetDefPattern())
@@ -593,37 +599,44 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
break; // Schleife abbrechen
}
- if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) )
+ if (!RowFiltered( nRow ))
{
- // Vorlage auch uebernehmen
- //! am AttrArray mit ApplyPattern zusammenfassen ??
- if ( pStyleSheet )
- aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet );
+ if ( bHasFiltered )
+ DeleteArea(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow),
+ static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), IDF_AUTOFILL);
- // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen
- if ( pNewPattern )
- aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern );
- else
- aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern );
- }
+ if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) )
+ {
+ // Vorlage auch uebernehmen
+ //! am AttrArray mit ApplyPattern zusammenfassen ??
+ if ( pStyleSheet )
+ aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet );
- if (nAtSrc==nISrcEnd)
- {
- if ( nAtSrc != nISrcStart )
- { // mehr als eine Source-Zelle
- nAtSrc = nISrcStart;
+ // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen
+ if ( pNewPattern )
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern );
+ else
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern );
+ }
+
+ if (nAtSrc==nISrcEnd)
+ {
+ if ( nAtSrc != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nAtSrc = nISrcStart;
+ bGetPattern = sal_True;
+ }
+ }
+ else if (bPositive)
+ {
+ ++nAtSrc;
+ bGetPattern = sal_True;
+ }
+ else
+ {
+ --nAtSrc;
bGetPattern = sal_True;
}
- }
- else if (bPositive)
- {
- ++nAtSrc;
- bGetPattern = sal_True;
- }
- else
- {
- --nAtSrc;
- bGetPattern = sal_True;
}
if (rInner == nIEnd) break;
@@ -691,7 +704,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
{
sal_uLong nSource = nISrcStart;
double nDelta;
- if ( nScFillModeMouseModifier & KEY_MOD1 )
+ if ( (nScFillModeMouseModifier & KEY_MOD1) || bHasFiltered )
nDelta = 0.0;
else if ( bPositive )
nDelta = 1.0;
@@ -708,6 +721,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
ScBaseCell* pSrcCell = NULL;
CellType eCellType = CELLTYPE_NONE;
sal_Bool bIsOrdinalSuffix = false;
+ sal_Bool bRowFiltered = false;
rInner = nIStart;
while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
@@ -733,7 +747,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
((ScStringCell*)pSrcCell)->GetString( aValue );
else
((ScEditCell*)pSrcCell)->GetString( aValue );
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered )
{
nCellDigits = 0; // look at each source cell individually
nHeadNoneTail = lcl_DecompValueString(
@@ -752,94 +766,103 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
else
eCellType = CELLTYPE_NONE;
}
- switch (eCellType)
- {
- case CELLTYPE_VALUE:
- aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta));
- break;
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- if ( nHeadNoneTail )
- {
- // #i48009# with the "nStringValue+(long)nDelta" expression within the
- // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
- // so nNextValue is now calculated ahead.
- sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
- String aStr;
- if ( nHeadNoneTail < 0 )
+ bRowFiltered = mpFilteredRows->getValue(nRow);
+
+ if (!bRowFiltered)
+ {
+ switch (eCellType)
+ {
+ case CELLTYPE_VALUE:
+ aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta));
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ if ( nHeadNoneTail )
{
- aCol[nCol].Insert( static_cast<SCROW>(nRow),
- lcl_getSuffixCell( pDocument,
- nNextValue, nCellDigits, aValue,
- eCellType, bIsOrdinalSuffix));
+ // #i48009# with the "nStringValue+(long)nDelta" expression within the
+ // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
+ // so nNextValue is now calculated ahead.
+ sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
+
+ String aStr;
+ if ( nHeadNoneTail < 0 )
+ {
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ lcl_getSuffixCell( pDocument,
+ nNextValue, nCellDigits, aValue,
+ eCellType, bIsOrdinalSuffix));
+ }
+ else
+ {
+ aStr = aValue;
+ aStr += lcl_ValueString( nNextValue, nCellDigits );
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ new ScStringCell( aStr));
+ }
}
else
{
- aStr = aValue;
- aStr += lcl_ValueString( nNextValue, nCellDigits );
- aCol[nCol].Insert( static_cast<SCROW>(nRow),
- new ScStringCell( aStr));
- }
- }
- else
- {
- ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
- switch ( eCellType )
- {
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
- break;
- default:
+ ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
+ switch ( eCellType )
{
- // added to avoid warnings
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
}
}
+ break;
+ case CELLTYPE_FORMULA :
+ FillFormula( nFormulaCounter, bFirst,
+ (ScFormulaCell*) pSrcCell,
+ static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow), (rInner == nIEnd) );
+ if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
+ nMaxFormCnt = nFormulaCounter - nActFormCnt;
+ break;
+ default:
+ {
+ // added to avoid warnings
}
- break;
- case CELLTYPE_FORMULA :
- FillFormula( nFormulaCounter, bFirst,
- (ScFormulaCell*) pSrcCell,
- static_cast<SCCOL>(nCol),
- static_cast<SCROW>(nRow), (rInner == nIEnd) );
- if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
- nMaxFormCnt = nFormulaCounter - nActFormCnt;
- break;
- default:
- {
- // added to avoid warnings
}
- }
- if (nSource==nISrcEnd)
- {
- if ( nSource != nISrcStart )
- { // mehr als eine Source-Zelle
- nSource = nISrcStart;
+ if (nSource==nISrcEnd)
+ {
+ if ( nSource != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nSource = nISrcStart;
+ bGetCell = sal_True;
+ }
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered )
+ {
+ if ( bPositive )
+ nDelta += 1.0;
+ else
+ nDelta -= 1.0;
+ }
+ nFormulaCounter = nActFormCnt;
+ bFirst = false;
+ }
+ else if (bPositive)
+ {
+ ++nSource;
bGetCell = sal_True;
}
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ else
{
- if ( bPositive )
- nDelta += 1.0;
- else
- nDelta -= 1.0;
+ --nSource;
+ bGetCell = sal_True;
}
- nFormulaCounter = nActFormCnt;
- bFirst = false;
- }
- else if (bPositive)
- {
- ++nSource;
- bGetCell = sal_True;
- }
- else
- {
- --nSource;
- bGetCell = sal_True;
}
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+
// Progress in der inneren Schleife nur bei teuren Zellen,
// und auch dann nicht fuer jede einzelne
@@ -847,8 +870,6 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
if ( eCellType == CELLTYPE_FORMULA || eCellType == CELLTYPE_EDIT )
rProgress.SetStateOnPercent( nProgress );
- if (rInner == nIEnd) break;
- if (bPositive) ++rInner; else --rInner;
}
rProgress.SetStateOnPercent( nProgress );
}
@@ -936,6 +957,30 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n
}
else if ( eFillCmd == FILL_SIMPLE ) // Auffuellen mit Muster
{
+ if ((eFillDir == FILL_TO_BOTTOM)||(eFillDir == FILL_TO_TOP))
+ {
+ long nBegin = 0;
+ long nEnd = 0;
+ if (nEndY > nRow1)
+ {
+ nBegin = nRow2+1;
+ nEnd = nEndY;
+ }
+ else
+ {
+ nBegin = nEndY;
+ nEnd = nRow1 -1;
+ }
+
+ long nNonFiltered = CountNonFilteredRows(nBegin, nEnd);
+ long nFiltered = nEnd + 1 - nBegin - nNonFiltered;
+
+ if (nIndex > 0)
+ nIndex = nIndex - nFiltered;
+ else
+ nIndex = nIndex + nFiltered;
+ }
+
long nPosIndex = nIndex;
while ( nPosIndex < 0 )
nPosIndex += nSrcCount;
@@ -966,7 +1011,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n
((ScStringCell*)pCell)->GetString( aValue );
else
((ScEditCell*)pCell)->GetString( aValue );
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() )
{
sal_Int32 nVal;
sal_uInt16 nCellDigits = 0; // look at each source cell individually
@@ -987,7 +1032,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n
{
// dabei kann's keinen Ueberlauf geben...
double nVal = ((ScValueCell*)pCell)->GetValue();
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() )
nVal += (double) nDelta;
Color* pColor;
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index c30f57a03a99..ad3052585784 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -3788,6 +3788,7 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula )
eLastOp == ocArrayColSep ||
eLastOp == ocArrayOpen) &&
(eOp == ocSep ||
+ eOp == ocClose ||
eOp == ocArrayRowSep ||
eOp == ocArrayColSep ||
eOp == ocArrayClose) )
diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx
index 89234f9d4b37..4118f9dcd7f9 100644
--- a/sc/source/core/tool/dbcolect.cxx
+++ b/sc/source/core/tool/dbcolect.cxx
@@ -222,6 +222,11 @@ ScDBData& ScDBData::operator= (const ScDBData& rData)
return *this;
}
+SCTAB ScDBData::GetTable() const
+{
+ return nTable;
+}
+
bool ScDBData::operator== (const ScDBData& rData) const
{
// Daten, die nicht in den Params sind
@@ -820,6 +825,27 @@ ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCO
return NULL;
}
+ScDBData* ScDBCollection::GetFilterDBAtTable(SCTAB nTab) const
+{
+ ScDBData* pDataEmpty = NULL;
+ if (pItems)
+ {
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ {
+ ScDBData* pDBTemp = (ScDBData*)pItems[i];
+ if ( pDBTemp->GetTable() == nTab )
+ {
+ sal_Bool bFilter = pDBTemp->HasAutoFilter() || pDBTemp->HasQueryParam();
+
+ if ( bFilter )
+ return pDBTemp;
+ }
+ }
+ }
+
+ return pDataEmpty;
+}
+
sal_Bool ScDBCollection::SearchName( const String& rName, sal_uInt16& rIndex ) const
{
if (rtl::OUString(rName)==rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME)))
diff --git a/sc/source/core/tool/reffind.cxx b/sc/source/core/tool/reffind.cxx
index a3b2ce55585d..b6061bc7f230 100644
--- a/sc/source/core/tool/reffind.cxx
+++ b/sc/source/core/tool/reffind.cxx
@@ -42,16 +42,18 @@
// STATIC DATA -----------------------------------------------------------
+namespace {
+
// incl. Doppelpunkt -> Doppelte Referenzen werden einzeln behandelt
-const sal_Unicode ScRefFinder::pDelimiters[] = {
+const sal_Unicode pDelimiters[] = {
'=','(',')','+','-','*','/','^','&',' ','{','}','<','>',':', 0
};
// =======================================================================
-inline sal_Bool IsText( sal_Unicode c )
+inline bool IsText( sal_Unicode c )
{
- bool bFound = ScGlobal::UnicodeStrChr( ScRefFinder::pDelimiters, c );
+ bool bFound = ScGlobal::UnicodeStrChr( pDelimiters, c );
if (bFound)
// This is one of delimiters, therefore not text.
return false;
@@ -61,23 +63,160 @@ inline sal_Bool IsText( sal_Unicode c )
return c != sep;
}
-inline sal_Bool IsText( sal_Bool& bQuote, sal_Unicode c )
+inline bool IsText( bool& bQuote, sal_Unicode c )
{
- if ( c == '\'' )
+ if (c == '\'')
{
bQuote = !bQuote;
- return sal_True;
+ return true;
+ }
+ if (bQuote)
+ return true;
+
+ return IsText(c);
+}
+
+/**
+ * Find first character position that is considered text. A character is
+ * considered a text when it's within the ascii range and when it's not a
+ * delimiter.
+ */
+xub_StrLen FindStartPos(const sal_Unicode* p, xub_StrLen nStartPos, xub_StrLen nEndPos)
+{
+ while (nStartPos <= nEndPos && !IsText(p[nStartPos]))
+ ++nStartPos;
+
+ return nStartPos;
+}
+
+xub_StrLen FindEndPosA1(const sal_Unicode* p, xub_StrLen nStartPos, xub_StrLen nEndPos)
+{
+ bool bQuote = false;
+ xub_StrLen nNewEnd = nStartPos;
+ while (nNewEnd <= nEndPos && IsText(bQuote, p[nNewEnd]))
+ ++nNewEnd;
+
+ return nNewEnd;
+}
+
+xub_StrLen FindEndPosR1C1(const sal_Unicode* p, xub_StrLen nStartPos, xub_StrLen nEndPos)
+{
+ xub_StrLen nNewEnd = nStartPos;
+ p = &p[nStartPos];
+ for (; nNewEnd <= nEndPos; ++p, ++nNewEnd)
+ {
+ if (*p == '\'')
+ {
+ // Skip until the closing quote.
+ for (; nNewEnd <= nEndPos; ++p, ++nNewEnd)
+ if (*p == '\'')
+ break;
+ }
+ else if (*p == '[')
+ {
+ // Skip until the closing braket.
+ for (; nNewEnd <= nEndPos; ++p, ++nNewEnd)
+ if (*p == ']')
+ break;
+ }
+ else if (!IsText(*p))
+ break;
+ }
+
+ return nNewEnd;
+}
+
+/**
+ * Find last character position that is considred text, from the specified
+ * start position.
+ */
+xub_StrLen FindEndPos(const sal_Unicode* p, xub_StrLen nStartPos, xub_StrLen nEndPos,
+ formula::FormulaGrammar::AddressConvention eConv)
+{
+ switch (eConv)
+ {
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ return FindEndPosR1C1(p, nStartPos, nEndPos);
+ case formula::FormulaGrammar::CONV_OOO:
+ case formula::FormulaGrammar::CONV_XL_A1:
+ default:
+ return FindEndPosA1(p, nStartPos, nEndPos);
}
- if ( bQuote )
- return sal_True;
- return IsText( c );
}
-ScRefFinder::ScRefFinder(const String& rFormula, ScDocument* pDocument,
- formula::FormulaGrammar::AddressConvention eConvP) :
+void ExpandToTextA1(const sal_Unicode* p, xub_StrLen nLen, xub_StrLen& rStartPos, xub_StrLen& rEndPos)
+{
+ while (rStartPos > 0 && IsText(p[rStartPos - 1]) )
+ --rStartPos;
+ if (rEndPos)
+ --rEndPos;
+ while (rEndPos+1 < nLen && IsText(p[rEndPos + 1]) )
+ ++rEndPos;
+}
+
+void ExpandToTextR1C1(const sal_Unicode* p, xub_StrLen nLen, xub_StrLen& rStartPos, xub_StrLen& rEndPos)
+{
+ // move back the start position to the first text character.
+ if (rStartPos > 0)
+ {
+ for (--rStartPos; rStartPos > 0; --rStartPos)
+ {
+ sal_Unicode c = p[rStartPos];
+ if (c == '\'')
+ {
+ // Skip until the opening quote.
+ for (--rStartPos; rStartPos > 0; --rStartPos)
+ {
+ c = p[rStartPos];
+ if (c == '\'')
+ break;
+ }
+ }
+ else if (c == ']')
+ {
+ // Skip until the opening braket.
+ for (--rStartPos; rStartPos > 0; --rStartPos)
+ {
+ if (c == '[')
+ break;
+ }
+ }
+ else if (!IsText(c))
+ {
+ ++rStartPos;
+ break;
+ }
+ }
+ }
+
+ // move forward the end position to the last text character.
+ rEndPos = FindEndPosR1C1(p, rEndPos, nLen-1);
+}
+
+void ExpandToText(const sal_Unicode* p, xub_StrLen nLen, xub_StrLen& rStartPos, xub_StrLen& rEndPos,
+ formula::FormulaGrammar::AddressConvention eConv)
+{
+ switch (eConv)
+ {
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ ExpandToTextR1C1(p, nLen, rStartPos, rEndPos);
+ break;
+ case formula::FormulaGrammar::CONV_OOO:
+ case formula::FormulaGrammar::CONV_XL_A1:
+ default:
+ ExpandToTextA1(p, nLen, rStartPos, rEndPos);
+ }
+}
+
+}
+
+ScRefFinder::ScRefFinder(
+ const String& rFormula, const ScAddress& rPos,
+ ScDocument* pDocument, formula::FormulaGrammar::AddressConvention eConvP) :
aFormula( rFormula ),
eConv( eConvP ),
- pDoc( pDocument )
+ pDoc( pDocument ),
+ maPos(rPos)
{
nSelStart = nSelEnd = nFound = 0;
}
@@ -107,15 +246,9 @@ void ScRefFinder::ToggleRel( xub_StrLen nStartPos, xub_StrLen nEndPos )
// Selektion erweitern, und statt Selektion Start- und Endindex
if ( nEndPos < nStartPos )
- {
- xub_StrLen nTemp = nStartPos; nStartPos = nEndPos; nEndPos = nTemp;
- }
- while (nStartPos > 0 && IsText(pSource[nStartPos - 1]) )
- --nStartPos;
- if (nEndPos)
- --nEndPos;
- while (nEndPos+1 < nLen && IsText(pSource[nEndPos + 1]) )
- ++nEndPos;
+ ::std::swap(nEndPos, nStartPos);
+
+ ExpandToText(pSource, nLen, nStartPos, nEndPos, eConv);
String aResult;
String aExpr;
@@ -126,27 +259,20 @@ void ScRefFinder::ToggleRel( xub_StrLen nStartPos, xub_StrLen nEndPos )
xub_StrLen nLoopStart = nStartPos;
while ( nLoopStart <= nEndPos )
{
- // Formel zerlegen
-
- xub_StrLen nEStart = nLoopStart;
- while ( nEStart <= nEndPos && !IsText(pSource[nEStart]) )
- ++nEStart;
-
- sal_Bool bQuote = false;
- xub_StrLen nEEnd = nEStart;
- while ( nEEnd <= nEndPos && IsText(bQuote,pSource[nEEnd]) )
- ++nEEnd;
+ // Determine the stard and end positions of a text segment.
+ xub_StrLen nEStart = FindStartPos(pSource, nLoopStart, nEndPos);
+ xub_StrLen nEEnd = FindEndPos(pSource, nEStart, nEndPos, eConv);
aSep = aFormula.Copy( nLoopStart, nEStart-nLoopStart );
aExpr = aFormula.Copy( nEStart, nEEnd-nEStart );
- // Test, ob aExpr eine Referenz ist
-
- sal_uInt16 nResult = aAddr.Parse( aExpr, pDoc, pDoc->GetAddressConvention() );
+ // Check the validity of the expression, and toggle the relative flag.
+ ScAddress::Details aDetails(eConv, maPos.Row(), maPos.Col());
+ sal_uInt16 nResult = aAddr.Parse(aExpr, pDoc, aDetails);
if ( nResult & SCA_VALID )
{
sal_uInt16 nFlags = lcl_NextFlags( nResult );
- aAddr.Format( aExpr, nFlags, pDoc, pDoc->GetAddressConvention() );
+ aAddr.Format(aExpr, nFlags, pDoc, aDetails);
xub_StrLen nAbsStart = nStartPos+aResult.Len()+aSep.Len();
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 62f3622cd87a..949cb0fb0615 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -480,7 +480,7 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s
else
aIn >> nXclFunc;
if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
- DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount, pFuncInfo->mnMinParamCount );
+ DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount );
else
DoMulArgs( ocNoName, 0 );
}
@@ -498,7 +498,7 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s
else
aIn >> nXclFunc;
if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
- DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount );
+ DoMulArgs( pFuncInfo->meOpCode, nParamCount );
else
DoMulArgs( ocNoName, 0 );
}
@@ -1525,7 +1525,7 @@ sal_Bool ExcelToSc::GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sa
return !rRangeList.empty();
}
-void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz, sal_uInt8 nMinParamCount )
+void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz )
{
TokenId eParam[ 256 ];
sal_Int32 nLauf;
@@ -1589,19 +1589,6 @@ void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz, sal_uInt8 nMinParamCo
}
}
- // FIXME: ideally we'd want to import all missing args, but this
- // conflicts with lots of fn's understanding of nParams - we need
- // a function table, and pre-call argument normalisation 1st.
- sal_Int16 nLastRemovable = nLast - nMinParamCount;
-
- // skip missing parameters at end of parameter list
- while( nSkipEnd < nLastRemovable &&
- aPool.IsSingleOp( eParam[ nSkipEnd + 1 ], ocMissing ) )
- nSkipEnd++;
-
-// fprintf (stderr, "Fn %d nSkipEnd %d nLast %d nMinParamCnt %d %d\n",
-// eId, nSkipEnd, nLast, nMinParamCount, nLastRemovable);
-
// [Parameter{;Parameter}]
if( nLast > nSkipEnd )
{
diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx
index aebb75418f36..f989abc3c196 100644
--- a/sc/source/filter/excel/excform8.cxx
+++ b/sc/source/filter/excel/excform8.cxx
@@ -42,9 +42,51 @@
#include "externalrefmgr.hxx"
#include <vector>
+#include <cstring>
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
using ::std::vector;
+namespace {
+
+/**
+ * Extract a file path from OLE link path. An OLE link path is expected to
+ * be in the following format:
+ *
+ * Excel.Sheet.8 \3 [file path]
+ */
+bool extractFilePath(const OUString& rUrl, OUString& rPath)
+{
+ const char* prefix = "Excel.Sheet.8\3";
+ size_t nPrefixLen = ::std::strlen(prefix);
+
+ sal_Int32 n = rUrl.getLength();
+ if (n <= static_cast<sal_Int32>(nPrefixLen))
+ // needs to have the specified prefix.
+ return false;
+
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rUrl.getStr();
+ for (size_t i = 0; i < static_cast<size_t>(n); ++i, ++p)
+ {
+ if (i < nPrefixLen)
+ {
+ sal_Unicode pc = static_cast<sal_Unicode>(*prefix++);
+ if (pc != *p)
+ return false;
+
+ continue;
+ }
+ aBuf.append(*p);
+ }
+
+ rPath = aBuf.makeStringAndClear();
+ return true;
+}
+
+}
+
ExcelToSc8::ExternalTabInfo::ExternalTabInfo() :
mnFileId(0), mbExternal(false)
{
@@ -92,6 +134,20 @@ bool ExcelToSc8::Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB&
return GetExternalFileIdFromXti(nIxti, rExtInfo.mnFileId);
}
+bool ExcelToSc8::HandleOleLink(sal_uInt16 nXtiIndex, const XclImpExtName& rExtName, ExternalTabInfo& rExtInfo)
+{
+ const String* pUrl = rLinkMan.GetSupbookUrl(nXtiIndex);
+ if (!pUrl)
+ return false;
+
+ OUString aPath;
+ if (!extractFilePath(*pUrl, aPath))
+ // file path extraction failed.
+ return false;
+
+ OUString aFileUrl = ScGlobal::GetAbsDocName(aPath, GetDocShell());
+ return rExtName.CreateOleData(GetDoc(), aFileUrl, rExtInfo.mnFileId, rExtInfo.maTabName, rExtInfo.maRange);
+}
// if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
// otherwise it will seek to the first byte past additional content after <nFormulaLen>
@@ -419,7 +475,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
aIn >> nParamCount >> nXclFunc;
nParamCount &= 0x7F;
if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
- DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount );
+ DoMulArgs( pFuncInfo->meOpCode, nParamCount );
else
DoMulArgs( ocNoName, 0 );
}
@@ -682,8 +738,29 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
aStack << aPool.Store( ocEuroConvert, String() );
}
break;
-
- default: // OLE link
+ case xlExtOLE:
+ {
+ ExternalTabInfo aExtInfo;
+ if (HandleOleLink(nXtiIndex, *pExtName, aExtInfo))
+ {
+ if (aExtInfo.maRange.aStart == aExtInfo.maRange.aEnd)
+ {
+ // single cell
+ aSRD.InitAddress(aExtInfo.maRange.aStart);
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
+ }
+ else
+ {
+ // range
+ aCRD.InitRange(aExtInfo.maRange);
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
+ }
+ }
+ else
+ aStack << aPool.Store(ocNoName, pExtName->GetName());
+ }
+ break;
+ default:
{
aPool << ocBad;
aPool >> aStack;
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index 70feaa4e4e22..96e68a9df01f 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -1125,8 +1125,8 @@ FltError ImportExcel8::Read( void )
case 0x9D: AutoFilterInfo(); break;// AUTOFILTERINFO
case 0x9E: AutoFilter(); break; // AUTOFILTER
case 0x0208: Row34(); break; // ROW [ 34 ]
- case 0x0021:
- case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case EXC_ID2_ARRAY:
+ case EXC_ID3_ARRAY: Array34(); break; // ARRAY [ 34 ]
case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345 ]
case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5 ]
case 0x0867: SheetProtection(); break; // SHEETPROTECTION
diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx
index 634a723238a6..492fe5d2033c 100644
--- a/sc/source/filter/excel/xilink.cxx
+++ b/sc/source/filter/excel/xilink.cxx
@@ -44,6 +44,9 @@
#include <boost/ptr_container/ptr_vector.hpp>
using ::std::vector;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
// ============================================================================
// *** Helper classes ***
@@ -284,7 +287,61 @@ sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMa
// External names =============================================================
-XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, XclSupbookType eSubType, ExcelToSc* pFormulaConv )
+XclImpExtName::MOper::MOper(XclImpStream& rStrm) :
+ mxCached(new ScMatrix(0,0))
+{
+ SCSIZE nLastCol = rStrm.ReaduInt8();
+ SCSIZE nLastRow = rStrm.ReaduInt16();
+ mxCached->Resize(nLastCol+1, nLastRow+1);
+ for (SCSIZE nRow = 0; nRow <= nLastRow; ++nRow)
+ {
+ for (SCSIZE nCol = 0; nCol <= nLastCol; ++nCol)
+ {
+ sal_uInt8 nOp;
+ rStrm >> nOp;
+ switch (nOp)
+ {
+ case 0x01:
+ {
+ double fVal = rStrm.ReadDouble();
+ mxCached->PutDouble(fVal, nCol, nRow);
+ }
+ break;
+ case 0x02:
+ {
+ OUString aStr = rStrm.ReadUniString();
+ mxCached->PutString(aStr, nCol, nRow);
+ }
+ break;
+ case 0x04:
+ {
+ bool bVal = rStrm.ReaduInt8();
+ mxCached->PutBoolean(bVal, nCol, nRow);
+ rStrm.Ignore(7);
+ }
+ break;
+ case 0x10:
+ {
+ sal_uInt8 nErr = rStrm.ReaduInt8();
+ // TODO: Map the error code from xls to calc.
+ mxCached->PutError(nErr, nCol, nRow);
+ rStrm.Ignore(7);
+ }
+ break;
+ default:
+ rStrm.Ignore(8);
+ }
+ }
+ }
+}
+
+const ScMatrix& XclImpExtName::MOper::GetCache() const
+{
+ return *mxCached;
+}
+
+XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, XclSupbookType eSubType, ExcelToSc* pFormulaConv ) :
+ mpMOper(NULL)
{
sal_uInt16 nFlags;
sal_uInt8 nLen;
@@ -312,36 +369,45 @@ XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm
meType = ::get_flagvalue( nFlags, EXC_EXTN_OLE, xlExtOLE, xlExtDDE );
}
- if( (meType == xlExtDDE) && (rStrm.GetRecLeft() > 1) )
- mxDdeMatrix.reset( new XclImpCachedMatrix( rStrm ) );
-
- if (meType == xlExtName)
+ switch (meType)
{
- // TODO: For now, only global external names are supported. In future
- // we should extend this to supporting per-sheet external names.
- if (mnStorageId == 0)
- {
- if (pFormulaConv)
+ case xlExtDDE:
+ if (rStrm.GetRecLeft() > 1)
+ mxDdeMatrix.reset(new XclImpCachedMatrix(rStrm));
+ break;
+ case xlExtName:
+ // TODO: For now, only global external names are supported. In future
+ // we should extend this to supporting per-sheet external names.
+ if (mnStorageId == 0)
{
- const ScTokenArray* pArray = NULL;
- sal_uInt16 nFmlaLen;
- rStrm >> nFmlaLen;
- vector<String> aTabNames;
- sal_uInt16 nCount = rSupbook.GetTabCount();
- aTabNames.reserve(nCount);
- for (sal_uInt16 i = 0; i < nCount; ++i)
- aTabNames.push_back(rSupbook.GetTabName(i));
-
- pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
- if (pArray)
- mxArray.reset(pArray->Clone());
+ if (pFormulaConv)
+ {
+ const ScTokenArray* pArray = NULL;
+ sal_uInt16 nFmlaLen;
+ rStrm >> nFmlaLen;
+ vector<String> aTabNames;
+ sal_uInt16 nCount = rSupbook.GetTabCount();
+ aTabNames.reserve(nCount);
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ aTabNames.push_back(rSupbook.GetTabName(i));
+
+ pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
+ if (pArray)
+ mxArray.reset(pArray->Clone());
+ }
}
- }
+ break;
+ case xlExtOLE:
+ mpMOper = new MOper(rStrm);
+ break;
+ default:
+ ;
}
}
XclImpExtName::~XclImpExtName()
{
+ delete mpMOper;
}
void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic, const String& rTopic ) const
@@ -361,6 +427,124 @@ void XclImpExtName::CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) co
pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
}
+namespace {
+
+/**
+ * Decompose the name into sheet name and range name. An OLE link name is
+ * always formatted like this [ !Sheet1!R1C1:R5C2 ] and it always uses R1C1
+ * notation.
+ */
+bool extractSheetAndRange(const OUString& rName, OUString& rSheet, OUString& rRange)
+{
+ sal_Int32 n = rName.getLength();
+ const sal_Unicode* p = rName.getStr();
+ OUStringBuffer aBuf;
+ bool bInSheet = true;
+ for (sal_Int32 i = 0; i < n; ++i, ++p)
+ {
+ if (i == 0)
+ {
+ // first character must be '!'.
+ if (*p != '!')
+ return false;
+ continue;
+ }
+
+ if (*p == '!')
+ {
+ // sheet name to range separator.
+ if (!bInSheet)
+ return false;
+ rSheet = aBuf.makeStringAndClear();
+ bInSheet = false;
+ continue;
+ }
+
+ aBuf.append(*p);
+ }
+
+ rRange = aBuf.makeStringAndClear();
+ return true;
+}
+
+}
+
+bool XclImpExtName::CreateOleData(ScDocument& rDoc, const OUString& rUrl,
+ sal_uInt16& rFileId, OUString& rTabName, ScRange& rRange) const
+{
+ if (!mpMOper)
+ return false;
+
+ OUString aSheet, aRangeStr;
+ if (!extractSheetAndRange(maName, aSheet, aRangeStr))
+ return false;
+
+ ScRange aRange;
+ sal_uInt16 nRes = aRange.ParseAny(aRangeStr, &rDoc, formula::FormulaGrammar::CONV_XL_R1C1);
+ if ((nRes & SCA_VALID) != SCA_VALID)
+ return false;
+
+ if (aRange.aStart.Tab() != aRange.aEnd.Tab())
+ // We don't support multi-sheet range for this.
+ return false;
+
+ const ScMatrix& rCache = mpMOper->GetCache();
+ SCSIZE nC, nR;
+ rCache.GetDimensions(nC, nR);
+ if (!nC || !nR)
+ // cache matrix is empty.
+ return false;
+
+ ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(rUrl);
+ ScExternalRefCache::TableTypeRef xTab = pRefMgr->getCacheTable(nFileId, aSheet, true, NULL);
+ if (!xTab)
+ // cache table creation failed.
+ return false;
+
+ xTab->setWholeTableCached();
+ for (SCSIZE i = 0; i < nR; ++i)
+ {
+ for (SCSIZE j = 0; j < nC; ++j)
+ {
+ SCCOL nCol = aRange.aStart.Col() + j;
+ SCROW nRow = aRange.aStart.Row() + i;
+
+ ScMatrixValue aVal = rCache.Get(j, i);
+ switch (aVal.nType)
+ {
+ case SC_MATVAL_BOOLEAN:
+ {
+ bool b = aVal.GetBoolean();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0));
+ xTab->setCell(nCol, nRow, pToken, 0, false);
+ }
+ break;
+ case SC_MATVAL_VALUE:
+ {
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(aVal.fVal));
+ xTab->setCell(nCol, nRow, pToken, 0, false);
+ }
+ break;
+ case SC_MATVAL_STRING:
+ {
+ const String& rStr = aVal.GetString();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
+ xTab->setCell(nCol, nRow, pToken, 0, false);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ rFileId = nFileId;
+ rTabName = aSheet;
+ rRange = aRange;
+ return true;
+}
+
bool XclImpExtName::HasFormulaTokens() const
{
return (mxArray.get() != NULL);
@@ -516,9 +700,9 @@ void XclImpSupbook::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv
const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
{
DBG_ASSERT( nXclIndex > 0, "XclImpSupbook::GetExternName - index must be >0" );
- if (meType == EXC_SBTYPE_SELF || nXclIndex >= maExtNameList.size())
+ if (meType == EXC_SBTYPE_SELF || nXclIndex > maExtNameList.size())
return NULL;
- return &maExtNameList.at( nXclIndex - 1 );
+ return &maExtNameList[nXclIndex-1];
}
bool XclImpSupbook::GetLinkData( String& rApplic, String& rTopic ) const
diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
index d4eb332b2fb0..11381e54bb4e 100644
--- a/sc/source/filter/excel/xistyle.cxx
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -1321,8 +1321,8 @@ void XclImpXF::ApplyPatternToAttrList(
pPat = static_cast<const ScPatternAttr*>(&aCache.ApplyTo(*pPat, true));
}
-
- if (pPat)
+ // Make sure we skip unnamed styles.
+ if (pPat && pPat->GetStyleName())
{
// Check for a gap between the last entry and this one.
bool bHasGap = false;
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
index 0744bdf52c64..ebc3696e9a0f 100644
--- a/sc/source/filter/inc/excform.hxx
+++ b/sc/source/filter/inc/excform.hxx
@@ -52,7 +52,7 @@ protected:
const XclBiff meBiff;
// ---------------------------------------------------------------
- void DoMulArgs( DefTokenId eId, sal_uInt8 nNumArgs, sal_uInt8 mnMinParamCount = 0 );
+ void DoMulArgs( DefTokenId eId, sal_uInt8 nNumArgs );
void ExcRelToScRel( sal_uInt16 nRow, sal_uInt8 nCol, ScSingleRefData&, const sal_Bool bName );
@@ -104,6 +104,7 @@ inline sal_Bool ExcelToSc::IsComplRowRange( const sal_uInt16 nRow1, const sal_uI
// ============================================================================
class XclImpLinkManager;
+class XclImpExtName;
class ExcelToSc8 : public ExcelToSc
{
@@ -111,9 +112,10 @@ public:
struct ExternalTabInfo
{
- String maTabName;
- sal_uInt16 mnFileId;
- bool mbExternal;
+ ScRange maRange;
+ ::rtl::OUString maTabName;
+ sal_uInt16 mnFileId;
+ bool mbExternal;
ExternalTabInfo();
};
@@ -128,6 +130,7 @@ private:
virtual bool Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo );
+ bool HandleOleLink(sal_uInt16 nXtiIndex, const XclImpExtName& rExtName, ExternalTabInfo& rExtInfo);
public:
ExcelToSc8( const XclImpRoot& rRoot );
virtual ~ExcelToSc8();
diff --git a/sc/source/filter/inc/xilink.hxx b/sc/source/filter/inc/xilink.hxx
index 2f06ddb2f7b0..2b2e9ac8a03c 100644
--- a/sc/source/filter/inc/xilink.hxx
+++ b/sc/source/filter/inc/xilink.hxx
@@ -32,6 +32,7 @@
#include <map>
#include "xllink.hxx"
#include "xiroot.hxx"
+#include "scmatrix.hxx"
/* ============================================================================
Classes for import of different kinds of internal/external references.
@@ -113,6 +114,19 @@ class XclImpSupbook;
@descr Supported: External defined names, AddIn names, DDE links and OLE objects. */
class XclImpExtName
{
+ /**
+ * MOper, multiple operands, stores cached values of external range
+ * specified in the record.
+ */
+ class MOper
+ {
+ public:
+ MOper(XclImpStream& rStrm);
+ const ScMatrix& GetCache() const;
+ private:
+ ScMatrixRef mxCached;
+ };
+
public:
/** Reads the external name from the stream. */
explicit XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm,
@@ -125,6 +139,14 @@ public:
void CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const;
+ /**
+ * Create OLE link data. OLE link data is converted to external
+ * reference, since OLE link doesn't work cross-platform, and is not very
+ * reliable even on Windows.
+ */
+ bool CreateOleData(ScDocument& rDoc, const ::rtl::OUString& rUrl,
+ sal_uInt16& rFileId, ::rtl::OUString& rTabName, ScRange& rRange) const;
+
bool HasFormulaTokens() const;
inline XclImpExtNameType GetType() const { return meType; }
@@ -136,6 +158,7 @@ private:
typedef ::std::auto_ptr< ScTokenArray > TokenArrayPtr;
XclImpCachedMatrixPtr mxDdeMatrix; /// Cached results of the DDE link.
+ MOper* mpMOper; /// Cached values for OLE link
TokenArrayPtr mxArray; /// Formula tokens for external name.
String maName; /// The name of the external name.
sal_uInt32 mnStorageId; /// Storage ID for OLE object storages.
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index 133cb368e117..6fabe3684d6c 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -2084,13 +2084,16 @@ ScFormatFilterPlugin &ScFormatFilter::Get()
if (plugin != NULL)
return *plugin;
+ ::rtl::OUString sFilterLib(RTL_CONSTASCII_USTRINGPARAM(SVLIBRARY("scfilt")));
static ::osl::Module aModule;
- if ( aModule.loadRelative( &thisModule,
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SVLIBRARY( "scfilt" ) ) ) ) )
+ bool bLoaded = aModule.loadRelative(&thisModule, sFilterLib);
+ if (!bLoaded)
+ bLoaded = aModule.load(sFilterLib);
+ if (bLoaded)
{
- oslGenericFunction fn = aModule.getFunctionSymbol( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ScFilterCreate" )) );
- if (fn != NULL)
- plugin = reinterpret_cast<FilterFn>(fn)();
+ oslGenericFunction fn = aModule.getFunctionSymbol( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ScFilterCreate" )) );
+ if (fn != NULL)
+ plugin = reinterpret_cast<FilterFn>(fn)();
}
if (plugin == NULL)
plugin = new ScFormatFilterMissing();
diff --git a/sc/source/ui/vba/vbaworkbook.hxx b/sc/source/ui/vba/vbaworkbook.hxx
index 0ec3604da2a6..f51ce051d1a7 100644
--- a/sc/source/ui/vba/vbaworkbook.hxx
+++ b/sc/source/ui/vba/vbaworkbook.hxx
@@ -86,7 +86,7 @@ public:
virtual css::uno::Reference< css::frame::XModel > getDocModel() { return mxModel; }
// XUnoTunnel
- virtual ::sal_Int64 getSomething(const css::uno::Sequence<sal_Int8 >& rId ) throw(css::uno::RuntimeException);
+ virtual ::sal_Int64 SAL_CALL getSomething(const css::uno::Sequence<sal_Int8 >& rId ) throw(css::uno::RuntimeException);
};
#endif /* SC_VBA_WORKBOOK_HXX */
diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx
index 9348f928f13f..f3c5bb18efe2 100644
--- a/sc/source/ui/vba/vbaworksheet.cxx
+++ b/sc/source/ui/vba/vbaworksheet.cxx
@@ -229,6 +229,72 @@ const uno::Sequence<sal_Int8>& ScVbaWorksheet::getUnoTunnelId()
return aSeq;
}
+uno::Reference< ov::excel::XWorksheet >
+ScVbaWorksheet::createSheetCopyInNewDoc(rtl::OUString aCurrSheetName)
+{
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
+ uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
+ uno::Reference< table::XCellRange > xRange1( xSheetCellCursor, uno::UNO_QUERY);
+ uno::Reference<excel::XRange> xRange = new ScVbaRange( this, mxContext, xRange1);
+ if (xRange.is())
+ xRange->Select();
+ excel::implnCopy(mxModel);
+ uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
+ if (xModel.is())
+ {
+ excel::implnPaste(xModel);
+ }
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
+ //#TODO #FIXME
+ //get proper parent for Worksheet
+ return new ScVbaWorksheet( NULL, mxContext, xSheet, xModel );
+}
+
+css::uno::Reference< ov::excel::XWorksheet >
+ScVbaWorksheet::createSheetCopy(uno::Reference<excel::XWorksheet> xSheet, bool bAfter)
+{
+ rtl::OUString aCurrSheetName = getName();
+ ScVbaWorksheet* pDestSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
+
+ uno::Reference <sheet::XSpreadsheetDocument> xDestDoc( pDestSheet->getModel(), uno::UNO_QUERY );
+ uno::Reference <sheet::XSpreadsheetDocument> xSrcDoc( getModel(), uno::UNO_QUERY );
+
+ SCTAB nDest = 0;
+ SCTAB nSrc = 0;
+ rtl::OUString aSheetName = xSheet->getName();
+ bool bSameDoc = ( pDestSheet->getModel() == getModel() );
+ bool bDestSheetExists = ScVbaWorksheets::nameExists (xDestDoc, aSheetName, nDest );
+ bool bSheetExists = ScVbaWorksheets::nameExists (xSrcDoc, aCurrSheetName, nSrc );
+
+ // set sheet name to be newSheet name
+ aSheetName = aCurrSheetName;
+ if ( bSheetExists && bDestSheetExists )
+ {
+ SCTAB nDummy=0;
+ if(bAfter)
+ nDest++;
+ uno::Reference<sheet::XSpreadsheets> xSheets = xDestDoc->getSheets();
+ if ( bSameDoc || ScVbaWorksheets::nameExists( xDestDoc, aCurrSheetName, nDummy ) )
+ getNewSpreadsheetName(aSheetName,aCurrSheetName,xDestDoc);
+ if ( bSameDoc )
+ xSheets->copyByName(aCurrSheetName,aSheetName,nDest);
+ else
+ {
+ ScDocShell* pDestDocShell = excel::getDocShell( pDestSheet->getModel() );
+ ScDocShell* pSrcDocShell = excel::getDocShell( getModel() );
+ if ( pDestDocShell && pSrcDocShell )
+ pDestDocShell->TransferTab( *pSrcDocShell, static_cast<SCTAB>(nSrc), static_cast<SCTAB>(nDest), true, true );
+ }
+ }
+ // return new sheet
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XWorksheet > xNewSheet( xApplication->Worksheets( uno::makeAny( aSheetName ) ), uno::UNO_QUERY_THROW );
+ return xNewSheet;
+}
+
::rtl::OUString
ScVbaWorksheet::getName() throw (uno::RuntimeException)
{
@@ -571,60 +637,13 @@ void
ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException)
{
uno::Reference<excel::XWorksheet> xSheet;
- rtl::OUString aCurrSheetName =getName();
if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()))
{
- uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
- uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
- uno::Reference< table::XCellRange > xRange1( xSheetCellCursor, uno::UNO_QUERY);
- uno::Reference<excel::XRange> xRange = new ScVbaRange( this, mxContext, xRange1);
- if (xRange.is())
- xRange->Select();
- excel::implnCopy(mxModel);
- uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
- if (xModel.is())
- {
- excel::implnPaste(xModel);
- }
+ createSheetCopyInNewDoc(getName());
return;
}
- ScVbaWorksheet* pDestSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
-
- uno::Reference <sheet::XSpreadsheetDocument> xDestDoc( pDestSheet->getModel(), uno::UNO_QUERY );
- uno::Reference <sheet::XSpreadsheetDocument> xSrcDoc( getModel(), uno::UNO_QUERY );
-
- SCTAB nDest = 0;
- SCTAB nSrc = 0;
- rtl::OUString aSheetName = xSheet->getName();
- bool bSameDoc = ( pDestSheet->getModel() == getModel() );
- bool bDestSheetExists = ScVbaWorksheets::nameExists (xDestDoc, aSheetName, nDest );
- bool bSheetExists = ScVbaWorksheets::nameExists (xSrcDoc, aCurrSheetName, nSrc );
-
- // set sheet name to be newSheet name
- aSheetName = aCurrSheetName;
- if ( bSheetExists && bDestSheetExists )
- {
- SCTAB nDummy=0;
- sal_Bool bAfter = After.hasValue();
- if(bAfter)
- nDest++;
- uno::Reference<sheet::XSpreadsheets> xSheets = xDestDoc->getSheets();
- if ( bSameDoc || ScVbaWorksheets::nameExists( xDestDoc, aCurrSheetName, nDummy ) )
- getNewSpreadsheetName(aSheetName,aCurrSheetName,xDestDoc);
- if ( bSameDoc )
- xSheets->copyByName(aCurrSheetName,aSheetName,nDest);
- else
- {
- ScDocShell* pDestDocShell = excel::getDocShell( pDestSheet->getModel() );
- ScDocShell* pSrcDocShell = excel::getDocShell( getModel() );
- if ( pDestDocShell && pSrcDocShell )
- pDestDocShell->TransferTab( *pSrcDocShell, static_cast<SCTAB>(nSrc), static_cast<SCTAB>(nDest), true, true );
- }
- }
- // active the new sheet
- uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
- uno::Reference< excel::XWorksheet > xNewSheet( xApplication->Worksheets( uno::makeAny( aSheetName ) ), uno::UNO_QUERY_THROW );
+ uno::Reference<excel::XWorksheet> xNewSheet = createSheetCopy(xSheet, After.hasValue());
xNewSheet->Activate();
}
diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx
index 1affb7f4cbdc..2736083a8561 100644
--- a/sc/source/ui/vba/vbaworksheet.hxx
+++ b/sc/source/ui/vba/vbaworksheet.hxx
@@ -91,6 +91,8 @@ public:
virtual css::uno::Reference< css::sheet::XSpreadsheet > getSheet()
{ return mxSheet; }
static const com::sun::star::uno::Sequence<sal_Int8>& getUnoTunnelId();
+ css::uno::Reference< ov::excel::XWorksheet > createSheetCopyInNewDoc( rtl::OUString);
+ css::uno::Reference< ov::excel::XWorksheet > createSheetCopy(css::uno::Reference< ov::excel::XWorksheet> xSheet, bool bAfter);
// Attributes
virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
@@ -173,7 +175,7 @@ public:
virtual rtl::OUString& getServiceImplName();
virtual css::uno::Sequence<rtl::OUString> getServiceNames();
// XUnoTunnel
- virtual ::sal_Int64 getSomething(const css::uno::Sequence<sal_Int8 >& rId ) throw(css::uno::RuntimeException);
+ virtual ::sal_Int64 SAL_CALL getSomething(const css::uno::Sequence<sal_Int8 >& rId ) throw(css::uno::RuntimeException);
};
#endif /* SC_VBA_WORKSHEET_HXX */
diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx
index 6a2902a40810..80b6537d865c 100644
--- a/sc/source/ui/vba/vbaworksheets.cxx
+++ b/sc/source/ui/vba/vbaworksheets.cxx
@@ -55,6 +55,8 @@
#include "vbaworkbook.hxx"
#include "unonames.hxx"
+#include <vector>
+
using namespace ::ooo::vba;
using namespace ::com::sun::star;
@@ -420,6 +422,43 @@ ScVbaWorksheets::Select( const uno::Any& Replace ) throw (uno::RuntimeException)
}
+void SAL_CALL
+ScVbaWorksheets::Copy ( const uno::Any& Before, const uno::Any& After) throw (css::uno::RuntimeException)
+{
+ uno::Reference<excel::XWorksheet> xSheet;
+ sal_Int32 nElems = getCount();
+ bool bAfter = After.hasValue();
+ std::vector< uno::Reference< excel::XWorksheet > > Sheets;
+ sal_Int32 nItem = 0;
+
+ for ( nItem = 1; nItem <= nElems; ++nItem)
+ {
+ uno::Reference<excel::XWorksheet> xWorksheet(Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
+ Sheets.push_back(xWorksheet);
+ }
+ bool bNewDoc = (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()));
+
+ uno::Reference< excel::XWorksheet > xSrcSheet;
+ if ( bNewDoc )
+ {
+ bAfter = true;
+ xSrcSheet = Sheets.at(0);
+ ScVbaWorksheet* pSrcSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSrcSheet );
+ xSheet = pSrcSheet->createSheetCopyInNewDoc(xSrcSheet->getName());
+ nItem = 1;
+ }
+
+ for (nItem = 0; nItem < nElems; ++nItem )
+ {
+ xSrcSheet = Sheets[nItem];
+ ScVbaWorksheet* pSrcSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSrcSheet );
+ if ( bAfter )
+ xSheet = pSrcSheet->createSheetCopy(xSheet, bAfter);
+ else
+ pSrcSheet->createSheetCopy(xSheet, bAfter);
+ }
+}
+
//ScVbaCollectionBaseImpl
uno::Any SAL_CALL
ScVbaWorksheets::Item( const uno::Any& Index, const uno::Any& Index2 ) throw (uno::RuntimeException)
diff --git a/sc/source/ui/vba/vbaworksheets.hxx b/sc/source/ui/vba/vbaworksheets.hxx
index 9854c0447c1d..c15d713e1230 100644
--- a/sc/source/ui/vba/vbaworksheets.hxx
+++ b/sc/source/ui/vba/vbaworksheets.hxx
@@ -72,6 +72,7 @@ public:
virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::uno::RuntimeException);
virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
virtual void SAL_CALL Select( const css::uno::Any& Replace ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Copy ( const css::uno::Any& Before, const css::uno::Any& After) throw (css::uno::RuntimeException);
// ScVbaWorksheets_BASE
virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& Index2 ) throw
(css::uno::RuntimeException);
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
index 515b2fc514a9..5464a0f13f52 100644
--- a/sc/source/ui/view/editsh.cxx
+++ b/sc/source/ui/view/editsh.cxx
@@ -484,13 +484,14 @@ void ScEditShell::Execute( SfxRequest& rReq )
case SID_TOGGLE_REL:
{
- sal_Bool bOk = false;
+ bool bOk = false;
if (pEngine->GetParagraphCount() == 1)
{
String aText = pEngine->GetText();
ESelection aSel = pEditView->GetSelection(); // aktuelle View
- ScRefFinder aFinder( aText, pViewData->GetDocument() );
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScRefFinder aFinder(aText, pViewData->GetCurPos(), pDoc, pDoc->GetAddressConvention());
aFinder.ToggleRel( aSel.nStartPos, aSel.nEndPos );
if (aFinder.GetFound())
{
@@ -503,7 +504,7 @@ void ScEditShell::Execute( SfxRequest& rReq )
pTopView->GetEditEngine()->SetText( aNew );
pTopView->SetSelection( aNewSel );
}
- bOk = sal_True;
+ bOk = true;
// Referenz wird selektiert -> beim Tippen nicht ueberschreiben
bSetSelIsRef = sal_True;
diff --git a/sc/source/ui/view/viewfun4.cxx b/sc/source/ui/view/viewfun4.cxx
index a9d9364a7208..0ccabacf3e67 100644
--- a/sc/source/ui/view/viewfun4.cxx
+++ b/sc/source/ui/view/viewfun4.cxx
@@ -259,7 +259,7 @@ void ScViewFunc::DoRefConversion( sal_Bool bRecord )
String aOld;
((ScFormulaCell*)pCell)->GetFormula(aOld);
xub_StrLen nLen = aOld.Len();
- ScRefFinder aFinder( aOld, pDoc );
+ ScRefFinder aFinder( aOld, aIter.GetPos(), pDoc, pDoc->GetAddressConvention() );
aFinder.ToggleRel( 0, nLen );
if (aFinder.GetFound())
{