diff options
-rw-r--r-- | RepositoryExternal.mk | 27 | ||||
-rw-r--r-- | comphelper/inc/comphelper/mediadescriptor.hxx | 1 | ||||
-rw-r--r-- | comphelper/source/misc/mediadescriptor.cxx | 6 | ||||
-rw-r--r-- | config_host.mk.in | 3 | ||||
-rw-r--r-- | configure.in | 32 | ||||
-rw-r--r-- | framework/source/loadenv/loadenv.cxx | 50 | ||||
-rw-r--r-- | sc/CppunitTest_sc_ucalc.mk | 4 | ||||
-rw-r--r-- | sc/Library_sc.mk | 5 | ||||
-rw-r--r-- | sc/inc/orcushandler.hxx | 47 | ||||
-rw-r--r-- | sc/source/core/tool/orcushandler.cxx | 166 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh.cxx | 16 | ||||
-rw-r--r-- | sc/source/ui/inc/docsh.hxx | 1 | ||||
-rw-r--r-- | sfx2/inc/sfx2/objsh.hxx | 2 | ||||
-rw-r--r-- | sfx2/source/doc/objstor.cxx | 12 | ||||
-rw-r--r-- | sfx2/source/doc/sfxbasemodel.cxx | 31 | ||||
-rw-r--r-- | sfx2/source/view/frmload.cxx | 4 |
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 ); } |