summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2012-07-27 22:14:39 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2012-09-07 09:10:34 -0400
commita6639312005763d19e877bc61e6a844c09f5fb23 (patch)
treea955fe459e1eb82957100dd1c397ee3a31c32fdd
parent948350d60c031904c7daffc7be95ef9c146e700c (diff)
First cut on integrating liborcus into libreoffice tree....
It introduces the 'FilterProvider' property in the media descriptor to optionally bypass the normal loading process and let the external filter provider to handle the loading. For now I'm overwriting the csv import filter just to see how this could work just as an experiment. Orcus still needs a lot of work, and it crashes very often at the moment. Change-Id: I11b34572c71073144804a7d0dd5176c8067d8deb
-rw-r--r--RepositoryExternal.mk27
-rw-r--r--comphelper/inc/comphelper/mediadescriptor.hxx1
-rw-r--r--comphelper/source/misc/mediadescriptor.cxx6
-rw-r--r--config_host.mk.in3
-rw-r--r--configure.in32
-rw-r--r--framework/source/loadenv/loadenv.cxx50
-rw-r--r--sc/CppunitTest_sc_ucalc.mk4
-rw-r--r--sc/Library_sc.mk5
-rw-r--r--sc/inc/orcushandler.hxx47
-rw-r--r--sc/source/core/tool/orcushandler.cxx166
-rw-r--r--sc/source/ui/docshell/docsh.cxx16
-rw-r--r--sc/source/ui/inc/docsh.hxx1
-rw-r--r--sfx2/inc/sfx2/objsh.hxx2
-rw-r--r--sfx2/source/doc/objstor.cxx12
-rw-r--r--sfx2/source/doc/sfxbasemodel.cxx31
-rw-r--r--sfx2/source/view/frmload.cxx4
16 files changed, 394 insertions, 13 deletions
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 796eae534f91..6cecad6c665a 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -2,7 +2,7 @@
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
+#
# Copyright 2009 by Sun Microsystems, Inc.
#
# OpenOffice.org - a multi-platform office productivity suite
@@ -1856,6 +1856,31 @@ $(eval $(call gb_Helper_register_libraries,PLAINLIBS_OOO,\
endif # SYSTEM_PYTHON
+ifeq ($(SYSTEM_ORCUS),YES)
+
+define gb_LinkTarget__use_orcus
+$(call gb_LinkTarget_set_include,$(1),\
+ $$(INCLUDE) \
+ $(ORCUS_CFLAGS) \
+)
+$(call gb_LinkTarget_add_libs,$(1),$(ORCUS_LIBS))
+
+endef
+
+else # !SYSTEM_ORCUS
+
+$(eval $(call gb_Helper_register_static_libraries,PLAINLIBS, \
+ orcuslib \
+))
+
+define gb_LinkTarget__use_orcus
+$(call gb_LinkTarget_use_static_libraries,$(1),\
+ orcuslib \
+)
+
+endef
+
+endif # SYSTEM_ORCUS
# MacOSX-only frameworks ############################################
# (in alphabetical order)
diff --git a/comphelper/inc/comphelper/mediadescriptor.hxx b/comphelper/inc/comphelper/mediadescriptor.hxx
index e1b14a6ba243..53dcffc2e5a4 100644
--- a/comphelper/inc/comphelper/mediadescriptor.hxx
+++ b/comphelper/inc/comphelper/mediadescriptor.hxx
@@ -59,6 +59,7 @@ class COMPHELPER_DLLPUBLIC MediaDescriptor : public SequenceAsHashMap
static const ::rtl::OUString& PROP_ENCRYPTIONDATA();
static const ::rtl::OUString& PROP_FILENAME();
static const ::rtl::OUString& PROP_FILTERNAME();
+ static const ::rtl::OUString& PROP_FILTERPROVIDER();
static const ::rtl::OUString& PROP_FILTEROPTIONS();
static const ::rtl::OUString& PROP_FRAME();
static const ::rtl::OUString& PROP_FRAMENAME();
diff --git a/comphelper/source/misc/mediadescriptor.cxx b/comphelper/source/misc/mediadescriptor.cxx
index 095ba80e828d..311ff5e0dc76 100644
--- a/comphelper/source/misc/mediadescriptor.cxx
+++ b/comphelper/source/misc/mediadescriptor.cxx
@@ -95,6 +95,12 @@ const ::rtl::OUString& MediaDescriptor::PROP_FILTERNAME()
return sProp;
}
+const OUString& MediaDescriptor::PROP_FILTERPROVIDER()
+{
+ static const OUString aProp("FilterProvider");
+ return aProp;
+}
+
const ::rtl::OUString& MediaDescriptor::PROP_FILTEROPTIONS()
{
static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterOptions"));
diff --git a/config_host.mk.in b/config_host.mk.in
index f85e3cbbedae..c83ae449f015 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -415,6 +415,8 @@ export OOO_SHELL=@BASH@
export OOO_VENDOR=@OOO_VENDOR@
export OPENSSL_CFLAGS=@OPENSSL_CFLAGS@
export OPENSSL_LIBS=@OPENSSL_LIBS@
+export ORCUS_CFLAGS=@ORCUS_CFLAGS@
+export ORCUS_LIBS=@ORCUS_LIBS@
export OS=@OS@
export OSVERSION=@OSVERSION@
export OS_FOR_BUILD=@OS_FOR_BUILD@
@@ -551,6 +553,7 @@ export SYSTEM_NSS=@SYSTEM_NSS@
export SYSTEM_ODBC_HEADERS=@SYSTEM_ODBC_HEADERS@
export SYSTEM_OPENLDAP=@SYSTEM_OPENLDAP@
export SYSTEM_OPENSSL=@SYSTEM_OPENSSL@
+export SYSTEM_ORCUS=@SYSTEM_ORCUS@
export SYSTEM_PANGO=@SYSTEM_PANGO@
export SYSTEM_POPPLER=@SYSTEM_POPPLER@
export SYSTEM_POSTGRESQL=@SYSTEM_POSTGRESQL@
diff --git a/configure.in b/configure.in
index c5a9357de4a0..f22a493d0ef6 100644
--- a/configure.in
+++ b/configure.in
@@ -1637,6 +1637,11 @@ AC_ARG_WITH(system-redland,
[Use redland library already on system.]),,
[with_system_redland="$with_system_libs"])
+AC_ARG_WITH(system-orcus,
+ AS_HELP_STRING([--with-system-orcus],
+ [Use orcus library already on system.]),,
+ [with_system_orcus="$with_system_libs"])
+
AC_ARG_WITH(system-mozilla,
AS_HELP_STRING([--with-system-mozilla],
[Use Mozilla already on system. Note that some components cannot be built
@@ -4837,7 +4842,7 @@ _ACEOF
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <iostream>
using namespace std;
-]], [[ try { throw 42; } catch (int e) { cout << "Yep, " << e << endl; } ]])],[
+]], [[ try { throw 42; } catch (int e) { cout << "Yep, " << e << endl; } ]])],[
MINGW_GCCDLL=`$OBJDUMP -p conftest.exe | grep 'DLL Name: libgcc' | $SED -e 's@.*DLL Name: @@'`
if test -n "$MINGW_GCCDLL"; then
MINGW_SHARED_GCCLIB=YES
@@ -4847,14 +4852,14 @@ using namespace std;
AC_MSG_RESULT([no])
fi
],[ AC_MSG_RESULT([no])
-
+
])
AC_MSG_CHECKING([for dynamic libstdc++])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <iostream>
using namespace std;
-]], [[ cout << "Hello there." << endl; ]])],[
+]], [[ cout << "Hello there." << endl; ]])],[
MINGW_GXXDLL=`$OBJDUMP -p conftest.exe | grep 'DLL Name: libstdc++' | $SED -e 's@.*DLL Name: @@'`
if test -n "$MINGW_GXXDLL"; then
mingw_gxxdll_root=${MINGW_GXXDLL%.dll}
@@ -4871,7 +4876,7 @@ using namespace std;
AC_MSG_RESULT([no])
fi
],[ AC_MSG_RESULT([no])
-
+
])
AC_LANG_POP([C++])
@@ -8589,6 +8594,25 @@ AC_SUBST([MINGW_REDLAND_DLL])
AC_SUBST([MINGW_SQLITE3_DLL])
dnl ===================================================================
+dnl Check for system orcus
+dnl ===================================================================
+AC_MSG_CHECKING([which orcus library to use])
+if test "$with_system_orcus" = "yes"; then
+ AC_MSG_RESULT([external])
+ SYSTEM_ORCUS=YES
+ ORCUS_CFLAGS="`$PKG_CONFIG --cflags liborcus-0.2`"
+ ORCUS_LIBS="`$PKG_CONFIG --libs liborcus-0.2`"
+ PKG_CHECK_MODULES(ORCUS, orcus >= 0.1.0)
+else
+ AC_MSG_RESULT([internal])
+ BUILD_TYPE="$BUILD_TYPE ORCUS"
+ SYSTEM_ORCUS=NO
+fi
+AC_SUBST(SYSTEM_ORCUS)
+AC_SUBST(ORCUS_CFLAGS)
+AC_SUBST(ORCUS_LIBS)
+
+dnl ===================================================================
dnl Check for system hunspell
dnl ===================================================================
AC_MSG_CHECKING([which libhunspell to use])
diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx
index 02a8c7a3f487..a4c042a28869 100644
--- a/framework/source/loadenv/loadenv.cxx
+++ b/framework/source/loadenv/loadenv.cxx
@@ -91,13 +91,13 @@
const char PROP_TYPES[] = "Types";
const char PROP_NAME[] = "Name";
-
-namespace framework{
+namespace framework {
// may there exist already a define .-(
#ifndef css
namespace css = ::com::sun::star;
#endif
+using namespace com::sun::star;
class LoadEnvListener : private ThreadHelpBase
@@ -716,6 +716,37 @@ LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString&
return E_UNSUPPORTED_CONTENT;
}
+namespace {
+
+bool queryOrcusTypeAndFilter(const uno::Sequence<beans::PropertyValue>& rDescriptor, OUString& rType, OUString& rFilter)
+{
+ OUString aURL;
+ sal_Int32 nSize = rDescriptor.getLength();
+ for (sal_Int32 i = 0; i < nSize; ++i)
+ {
+ const beans::PropertyValue& rProp = rDescriptor[i];
+ if (rProp.Name == "URL")
+ {
+ rProp.Value >>= aURL;
+ break;
+ }
+ }
+
+ if (aURL.isEmpty() || aURL.copy(0,8).equalsIgnoreAsciiCase("private:"))
+ return false;
+
+ if (aURL.endsWith(".csv"))
+ {
+ // Use .csv as the first test file type.
+ rType = "generic_Text";
+ rFilter = "orcus-test-filter";
+ return true;
+ }
+
+ return false;
+}
+
+}
void LoadEnv::impl_detectTypeAndFilter()
throw(LoadEnvException, css::uno::RuntimeException)
@@ -736,7 +767,18 @@ void LoadEnv::impl_detectTypeAndFilter()
aReadLock.unlock();
// <- SAFE
- ::rtl::OUString sType;
+ rtl::OUString sType, sFilter;
+
+ if (queryOrcusTypeAndFilter(lDescriptor, sType, sFilter) && !sType.isEmpty() && !sFilter.isEmpty())
+ {
+ // Orcus type detected. Skip the normal type detection process.
+ m_lMediaDescriptor << lDescriptor;
+ m_lMediaDescriptor[comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
+ m_lMediaDescriptor[comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
+ m_lMediaDescriptor[comphelper::MediaDescriptor::PROP_FILTERPROVIDER()] <<= OUString("orcus");
+ return;
+ }
+
css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
if (xDetect.is())
sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */
@@ -753,7 +795,7 @@ void LoadEnv::impl_detectTypeAndFilter()
m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
// Is there an already detected (may be preselected) filter?
// see below ...
- ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());
+ sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());
aWriteLock.unlock();
// <- SAFE
diff --git a/sc/CppunitTest_sc_ucalc.mk b/sc/CppunitTest_sc_ucalc.mk
index 817bec0ec594..6710f8a523f7 100644
--- a/sc/CppunitTest_sc_ucalc.mk
+++ b/sc/CppunitTest_sc_ucalc.mk
@@ -43,6 +43,10 @@ ifeq ($(ENABLE_TELEPATHY),TRUE)
$(eval $(call gb_CppunitTest_use_libraries,sc_ucalc,tubes))
endif
+$(eval $(call gb_CppunitTest_use_externals,sc_ucalc,\
+ orcus \
+))
+
$(eval $(call gb_CppunitTest_use_libraries,sc_ucalc, \
avmedia \
basegfx \
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 345c7b5a0303..f83ba546a5b1 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -90,6 +90,10 @@ $(eval $(call gb_Library_use_libraries,sc,\
$(gb_STDLIBS) \
))
+$(eval $(call gb_Library_use_externals,sc,\
+ orcus \
+))
+
$(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/attarray \
sc/source/core/data/attrib \
@@ -210,6 +214,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/tool/navicfg \
sc/source/core/tool/odffmap \
sc/source/core/tool/optutil \
+ sc/source/core/tool/orcushandler \
sc/source/core/tool/parclass \
sc/source/core/tool/printopt \
sc/source/core/tool/prnsave \
diff --git a/sc/inc/orcushandler.hxx b/sc/inc/orcushandler.hxx
new file mode 100644
index 000000000000..8ed04a4fc591
--- /dev/null
+++ b/sc/inc/orcushandler.hxx
@@ -0,0 +1,47 @@
+/* -*- 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 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.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Kohei Yoshida <kohei.yoshida@suse.com>
+ *
+ * All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef __SC_ORCUSHANDLER_HXX__
+#define __SC_ORCUSHANDLER_HXX__
+
+#include "rtl/ustring.hxx"
+
+class ScDocument;
+
+/**
+ * Collection of orcus filter wrappers.
+ */
+class ScOrcusFilters
+{
+public:
+ static bool importCSV(ScDocument& rDoc, const rtl::OUString& rPath);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/orcushandler.cxx b/sc/source/core/tool/orcushandler.cxx
new file mode 100644
index 000000000000..2fa5e890d180
--- /dev/null
+++ b/sc/source/core/tool/orcushandler.cxx
@@ -0,0 +1,166 @@
+/* -*- 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 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.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Kohei Yoshida <kohei.yoshida@suse.com>
+ *
+ * All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "orcushandler.hxx"
+#include "document.hxx"
+
+#include "tools/urlobj.hxx"
+
+#include <orcus/model/interface.hpp>
+#include <orcus/orcus_csv.hpp>
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+using orcus::model::row_t;
+using orcus::model::col_t;
+using orcus::model::formula_grammar_t;
+
+namespace {
+
+class ScOrcusSheet;
+
+class ScOrcusFactory : public orcus::model::iface::factory
+{
+ ScDocument& mrDoc;
+ boost::ptr_vector<ScOrcusSheet> maSheets;
+
+public:
+ ScOrcusFactory(ScDocument& rDoc);
+
+ virtual orcus::model::iface::sheet* append_sheet(const char *sheet_name, size_t sheet_name_length);
+ virtual orcus::model::iface::shared_strings* get_shared_strings();
+ virtual orcus::model::iface::styles* get_styles();
+};
+
+class ScOrcusSheet : public orcus::model::iface::sheet
+{
+ ScDocument& mrDoc;
+ SCTAB mnTab;
+public:
+ ScOrcusSheet(ScDocument& rDoc, SCTAB nTab);
+
+ virtual void set_auto(row_t row, col_t col, const char* p, size_t n);
+ virtual void set_format(row_t row, col_t col, size_t xf_index);
+ virtual void set_formula(row_t row, col_t col, formula_grammar_t grammar, const char* p, size_t n);
+ virtual void set_formula_result(row_t row, col_t col, const char* p, size_t n);
+ virtual void set_shared_formula(
+ row_t row, col_t col, formula_grammar_t grammar, size_t sindex,
+ const char* p_formula, size_t n_formula, const char* p_range, size_t n_range);
+ virtual void set_shared_formula(row_t row, col_t col, size_t sindex);
+ virtual void set_string(row_t row, col_t col, size_t sindex);
+ virtual void set_value(row_t row, col_t col, double value);
+};
+
+ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc) : mrDoc(rDoc) {}
+
+orcus::model::iface::sheet* ScOrcusFactory::append_sheet(const char* sheet_name, size_t sheet_name_length)
+{
+ OUString aTabName(sheet_name, sheet_name_length, RTL_TEXTENCODING_UTF8);
+ if (!mrDoc.InsertTab(SC_TAB_APPEND, aTabName))
+ return NULL;
+
+ SCTAB nTab = mrDoc.GetTableCount() - 1;
+ maSheets.push_back(new ScOrcusSheet(mrDoc, nTab));
+ return &maSheets.back();
+}
+
+orcus::model::iface::shared_strings* ScOrcusFactory::get_shared_strings()
+{
+ // We don't support it yet.
+ return NULL;
+}
+
+orcus::model::iface::styles* ScOrcusFactory::get_styles()
+{
+ // We don't support it yet.
+ return NULL;
+}
+
+ScOrcusSheet::ScOrcusSheet(ScDocument& rDoc, SCTAB nTab) :
+ mrDoc(rDoc), mnTab(nTab) {}
+
+void ScOrcusSheet::set_auto(row_t row, col_t col, const char* p, size_t n)
+{
+ OUString aVal(p, n, RTL_TEXTENCODING_UTF8);
+ mrDoc.SetString(col, row, mnTab, aVal);
+}
+
+void ScOrcusSheet::set_format(row_t /*row*/, col_t /*col*/, size_t /*xf_index*/)
+{
+}
+
+void ScOrcusSheet::set_formula(
+ row_t /*row*/, col_t /*col*/, formula_grammar_t /*grammar*/, const char* /*p*/, size_t /*n*/)
+{
+}
+
+void ScOrcusSheet::set_formula_result(row_t /*row*/, col_t /*col*/, const char* /*p*/, size_t /*n*/)
+{
+}
+
+void ScOrcusSheet::set_shared_formula(
+ row_t /*row*/, col_t /*col*/, formula_grammar_t /*grammar*/, size_t /*sindex*/,
+ const char* /*p_formula*/, size_t /*n_formula*/, const char* /*p_range*/, size_t /*n_range*/)
+{
+}
+
+void ScOrcusSheet::set_shared_formula(row_t /*row*/, col_t /*col*/, size_t /*sindex*/)
+{
+}
+
+void ScOrcusSheet::set_string(row_t /*row*/, col_t /*col*/, size_t /*sindex*/)
+{
+}
+
+void ScOrcusSheet::set_value(row_t /*row*/, col_t /*col*/, double /*value*/)
+{
+}
+
+} // anonymous namespace
+
+bool ScOrcusFilters::importCSV(ScDocument& rDoc, const OUString& rPath)
+{
+ ScOrcusFactory aFactory(rDoc);
+ INetURLObject aURL(rPath);
+ const char* path = rtl::OUStringToOString(aURL.getFSysPath(INetURLObject::FSYS_UNX), RTL_TEXTENCODING_UTF8).getStr();
+
+ try
+ {
+ orcus::orcus_csv filter(&aFactory);
+ filter.read_file(path);
+ }
+ catch (const std::exception&)
+ {
+ rDoc.InsertTab(SC_TAB_APPEND, OUString("Foo"));
+ rDoc.SetString(0, 0, 0, "Failed to load!!!");
+ return false;
+ }
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 184800397abf..94e51030b299 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -112,6 +112,8 @@
#include "cellsuno.hxx"
#include "dpobject.hxx"
#include "markdata.hxx"
+#include "orcushandler.hxx"
+
#ifdef ENABLE_TELEPATHY
#include "sccollaboration.hxx"
#endif
@@ -1497,6 +1499,20 @@ sal_Bool ScDocShell::ConvertFrom( SfxMedium& rMedium )
return bRet;
}
+bool ScDocShell::LoadExternal(SfxMedium& rMed, const OUString& rProvider)
+{
+ if (rProvider == "orcus")
+ {
+ if (!ScOrcusFilters::importCSV(aDocument, rMed.GetName()))
+ return false;
+
+ FinishedLoading(SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES);
+ return true;
+ }
+
+ return false;
+}
+
ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell& rDocShell )
: mrDocShell( rDocShell)
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 6b0f926403be..1efff933c57f 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -212,6 +212,7 @@ public:
virtual sal_Bool Load( SfxMedium& rMedium );
virtual sal_Bool LoadFrom( SfxMedium& rMedium );
virtual sal_Bool ConvertFrom( SfxMedium &rMedium );
+ virtual bool LoadExternal(SfxMedium& rMedium, const rtl::OUString& rProvider);
virtual sal_Bool Save();
virtual sal_Bool SaveAs( SfxMedium& rMedium );
virtual sal_Bool ConvertTo( SfxMedium &rMedium );
diff --git a/sfx2/inc/sfx2/objsh.hxx b/sfx2/inc/sfx2/objsh.hxx
index 4b1c16bc2970..331553db46a4 100644
--- a/sfx2/inc/sfx2/objsh.hxx
+++ b/sfx2/inc/sfx2/objsh.hxx
@@ -294,6 +294,7 @@ public:
sal_Bool DoInitNew( SfxMedium* pMedium=0 );
sal_Bool DoLoad( SfxMedium* pMedium );
+ bool DoLoadExternal(SfxMedium* pMed, const rtl::OUString& rProvider);
sal_Bool DoSave();
sal_Bool DoSaveAs( SfxMedium &rNewStor );
sal_Bool DoSaveObjectAs( SfxMedium &rNewStor, sal_Bool bCommit );
@@ -314,6 +315,7 @@ public:
virtual sal_Bool SwitchPersistance(
const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );
virtual void UpdateLinks();
+ virtual bool LoadExternal(SfxMedium& rMedium, const rtl::OUString& rProvider);
/**
* Called when the Options dialog is dismissed with the OK button, to
* handle potentially conflicting option settings.
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index e3ffae4bca9f..bebe6b0bb823 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -821,6 +821,12 @@ sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed )
return bOk;
}
+bool SfxObjectShell::DoLoadExternal(SfxMedium *pMed, const OUString& rProvider)
+{
+ pMedium = pMed;
+ return LoadExternal(*pMedium, rProvider);
+}
+
sal_uInt32 SfxObjectShell::HandleFilter( SfxMedium* pMedium, SfxObjectShell* pDoc )
{
sal_uInt32 nError = ERRCODE_NONE;
@@ -3511,6 +3517,12 @@ void SfxObjectShell::UpdateLinks()
{
}
+bool SfxObjectShell::LoadExternal(SfxMedium&, const OUString&)
+{
+ // Not implemented. It's an error if the code path ever comes here.
+ return false;
+}
+
void SfxObjectShell::CheckConfigOptions()
{
// not handled. Each app's shell needs to overwrite this method to add handler.
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index 75bf08b627c1..b2b6e20439e6 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -1831,9 +1831,23 @@ void SAL_CALL SfxBaseModel::initNew()
}
}
-//________________________________________________________________________________________________________
-// XLoadable
-//________________________________________________________________________________________________________
+namespace {
+
+OUString getFilterProvider(const uno::Sequence<beans::PropertyValue>& rArgs)
+{
+ OUString aStr;
+ for (sal_Int32 i = 0, n = rArgs.getLength(); i < n; ++i)
+ {
+ if (rArgs[i].Name == "FilterProvider")
+ {
+ rArgs[i].Value >>= aStr;
+ return aStr;
+ }
+ }
+ return aStr;
+}
+
+}
void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >& seqArguments )
throw (::com::sun::star::frame::DoubleInitializationException,
@@ -1855,6 +1869,17 @@ void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >&
throw frame::DoubleInitializationException();
SfxMedium* pMedium = new SfxMedium( seqArguments );
+
+ OUString aFilterProvider = getFilterProvider(seqArguments);
+ if (!aFilterProvider.isEmpty())
+ {
+ if (!m_pData->m_pObjectShell->DoLoadExternal(pMedium, aFilterProvider))
+ delete pMedium;
+
+ pMedium->SetUpdatePickList(false);
+ return;
+ }
+
String aFilterName;
SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False );
if( pFilterNameItem )
diff --git a/sfx2/source/view/frmload.cxx b/sfx2/source/view/frmload.cxx
index 61ab9f35a113..e213986706dd 100644
--- a/sfx2/source/view/frmload.cxx
+++ b/sfx2/source/view/frmload.cxx
@@ -519,6 +519,8 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA
::comphelper::NamedValueCollection aDescriptor( rArgs );
+ bool bLoadWithOrcus = aDescriptor.getOrDefault<OUString>("FilterProvider", OUString()) == "orcus";
+
// ensure the descriptor contains a referrer
if ( !aDescriptor.has( "Referer" ) )
aDescriptor.put( "Referer", ::rtl::OUString() );
@@ -577,7 +579,7 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA
if ( !xModel.is() )
{
// beforehand, determine the filter to use, and update the descriptor with its information
- if ( !bInitNewModel )
+ if ( !bInitNewModel && !bLoadWithOrcus )
{
impl_determineFilter( aDescriptor );
}