You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
406 lines
16 KiB
406 lines
16 KiB
From 4a7096b9c8c0e6451fa0ced06143cb8a65ec10fc Mon Sep 17 00:00:00 2001
|
|
From: Eike Rathke <erack@redhat.com>
|
|
Date: Mon, 28 Oct 2013 22:46:01 +0100
|
|
Subject: [PATCH] resolved fdo#56209 reviving FilterFormulaParser
|
|
|
|
First it was moved from oox to sc without carrying over the component
|
|
factory bits, then subsequent commits removed the remaining bits in
|
|
steps as it appeared to be unused:
|
|
|
|
8ada1cd2846e5e60ad63250c68ddea3a9356546f
|
|
887d7945addeb823e0d3f783609c4e79d92ad4a7
|
|
effda59a12cedd3cf200d2e9f5186a623b0855bb
|
|
f2fd2a66ee827024b31a310d67804cb7cb18d2da
|
|
|
|
(cherry picked from commit 20e0afa76087e20f95247406d265a122263a8c6f)
|
|
|
|
Backported.
|
|
|
|
Change-Id: I445b11c95daff6f30b3654936d0f22a113158f97
|
|
Reviewed-on: https://gerrit.libreoffice.org/6469
|
|
Reviewed-by: David Tardon <dtardon@redhat.com>
|
|
Tested-by: David Tardon <dtardon@redhat.com>
|
|
---
|
|
sc/Library_scfilt.mk | 1 +
|
|
sc/source/filter/excel/xestream.cxx | 10 ++
|
|
sc/source/filter/inc/ooxformulaparser.hxx | 110 +++++++++++++++++
|
|
sc/source/filter/oox/ooxformulaparser.cxx | 196 ++++++++++++++++++++++++++++++
|
|
sc/util/scfilt.component | 3 +
|
|
5 files changed, 320 insertions(+)
|
|
create mode 100644 sc/source/filter/inc/ooxformulaparser.hxx
|
|
create mode 100644 sc/source/filter/oox/ooxformulaparser.cxx
|
|
|
|
diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk
|
|
index 5b383c4..3cc4b1a 100644
|
|
--- a/sc/Library_scfilt.mk
|
|
+++ b/sc/Library_scfilt.mk
|
|
@@ -188,6 +188,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\
|
|
sc/source/filter/oox/formulabuffer \
|
|
sc/source/filter/oox/formulaparser \
|
|
sc/source/filter/oox/numberformatsbuffer \
|
|
+ sc/source/filter/oox/ooxformulaparser \
|
|
sc/source/filter/oox/pagesettings \
|
|
sc/source/filter/oox/pivotcachebuffer \
|
|
sc/source/filter/oox/pivotcachefragment \
|
|
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
|
|
index bf9c1d8..8421006 100644
|
|
--- a/sc/source/filter/excel/xestream.cxx
|
|
+++ b/sc/source/filter/excel/xestream.cxx
|
|
@@ -1179,6 +1179,11 @@ namespace oox { namespace xls {
|
|
Sequence< OUString > SAL_CALL ExcelFilter_getSupportedServiceNames() throw();
|
|
Reference< XInterface > SAL_CALL ExcelFilter_createInstance(
|
|
const Reference< XComponentContext >& rxContext ) throw( Exception );
|
|
+
|
|
+ OUString SAL_CALL OOXMLFormulaParser_getImplementationName() throw();
|
|
+ Sequence< OUString > SAL_CALL OOXMLFormulaParser_getSupportedServiceNames() throw();
|
|
+ Reference< XInterface > SAL_CALL OOXMLFormulaParser_create(
|
|
+ const Reference< XComponentContext >& rxContext ) throw();
|
|
} }
|
|
|
|
#ifdef __cplusplus
|
|
@@ -1201,6 +1206,11 @@ extern "C"
|
|
oox::xls::ExcelFilter_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
|
|
0, 0
|
|
},
|
|
+ {
|
|
+ oox::xls::OOXMLFormulaParser_create, oox::xls::OOXMLFormulaParser_getImplementationName,
|
|
+ oox::xls::OOXMLFormulaParser_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
|
|
+ 0, 0
|
|
+ },
|
|
{ 0, 0, 0, 0, 0, 0 }
|
|
};
|
|
|
|
diff --git a/sc/source/filter/inc/ooxformulaparser.hxx b/sc/source/filter/inc/ooxformulaparser.hxx
|
|
new file mode 100644
|
|
index 0000000..e6c5797
|
|
--- /dev/null
|
|
+++ b/sc/source/filter/inc/ooxformulaparser.hxx
|
|
@@ -0,0 +1,110 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
+/*
|
|
+ * This file is part of the LibreOffice project.
|
|
+ *
|
|
+ * This Source Code Form is subject to the terms of the Mozilla Public
|
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
+ *
|
|
+ * This file incorporates work covered by the following license notice:
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed
|
|
+ * with this work for additional information regarding copyright
|
|
+ * ownership. The ASF licenses this file to you under the Apache
|
|
+ * License, Version 2.0 (the "License"); you may not use this file
|
|
+ * except in compliance with the License. You may obtain a copy of
|
|
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
+ */
|
|
+
|
|
+#ifndef OOX_XLS_OOXFORMULAPARSER_HXX
|
|
+#define OOX_XLS_OOXFORMULAPARSER_HXX
|
|
+
|
|
+#include <boost/shared_ptr.hpp>
|
|
+#include <com/sun/star/lang/XComponent.hpp>
|
|
+#include <com/sun/star/uno/XComponentContext.hpp>
|
|
+#include <com/sun/star/lang/XInitialization.hpp>
|
|
+#include <com/sun/star/lang/XServiceInfo.hpp>
|
|
+#include <com/sun/star/sheet/XFilterFormulaParser.hpp>
|
|
+#include <cppuhelper/implbase3.hxx>
|
|
+
|
|
+namespace oox {
|
|
+namespace xls {
|
|
+
|
|
+class OOXMLFormulaParserImpl;
|
|
+
|
|
+// ============================================================================
|
|
+
|
|
+typedef ::cppu::WeakImplHelper3<
|
|
+ ::com::sun::star::lang::XServiceInfo,
|
|
+ ::com::sun::star::lang::XInitialization,
|
|
+ ::com::sun::star::sheet::XFilterFormulaParser > OOXMLFormulaParser_BASE;
|
|
+
|
|
+/** OOXML formula parser/compiler service for usage in ODF filters. */
|
|
+class OOXMLFormulaParser : public OOXMLFormulaParser_BASE
|
|
+{
|
|
+public:
|
|
+ explicit OOXMLFormulaParser();
|
|
+ virtual ~OOXMLFormulaParser();
|
|
+
|
|
+ // com.sun.star.lang.XServiceInfo interface -------------------------------
|
|
+
|
|
+ virtual ::rtl::OUString SAL_CALL
|
|
+ getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
|
|
+
|
|
+ virtual sal_Bool SAL_CALL
|
|
+ supportsService( const ::rtl::OUString& rService )
|
|
+ throw( ::com::sun::star::uno::RuntimeException );
|
|
+
|
|
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
|
|
+ getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
|
|
+
|
|
+ // com.sun.star.lang.XInitialization interface ----------------------------
|
|
+
|
|
+ virtual void SAL_CALL initialize(
|
|
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rArgs )
|
|
+ throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException );
|
|
+
|
|
+ // com.sun.star.sheet.XFilterFormulaParser interface ----------------------
|
|
+
|
|
+ virtual ::rtl::OUString SAL_CALL
|
|
+ getSupportedNamespace()
|
|
+ throw( ::com::sun::star::uno::RuntimeException );
|
|
+
|
|
+ // com.sun.star.sheet.XFormulaParser interface ----------------------------
|
|
+
|
|
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL
|
|
+ parseFormula(
|
|
+ const ::rtl::OUString& rFormula,
|
|
+ const ::com::sun::star::table::CellAddress& rReferencePos )
|
|
+ throw( ::com::sun::star::uno::RuntimeException );
|
|
+
|
|
+ virtual ::rtl::OUString SAL_CALL
|
|
+ printFormula(
|
|
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >& rTokens,
|
|
+ const ::com::sun::star::table::CellAddress& rReferencePos )
|
|
+ throw( ::com::sun::star::uno::RuntimeException );
|
|
+
|
|
+private:
|
|
+ typedef ::boost::shared_ptr< OOXMLFormulaParserImpl > ParserImplRef;
|
|
+
|
|
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
|
|
+ mxComponent;
|
|
+ ParserImplRef mxParserImpl; /// Implementation of import parser.
|
|
+};
|
|
+
|
|
+css::uno::Reference< css::uno::XInterface > SAL_CALL OOXMLFormulaParser_create(
|
|
+ css::uno::Reference< css::uno::XComponentContext > const & context);
|
|
+
|
|
+OUString SAL_CALL OOXMLFormulaParser_getImplementationName();
|
|
+
|
|
+css::uno::Sequence< OUString > SAL_CALL OOXMLFormulaParser_getSupportedServiceNames();
|
|
+
|
|
+// ============================================================================
|
|
+
|
|
+} // namespace xls
|
|
+} // namespace oox
|
|
+
|
|
+#endif
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
diff --git a/sc/source/filter/oox/ooxformulaparser.cxx b/sc/source/filter/oox/ooxformulaparser.cxx
|
|
new file mode 100644
|
|
index 0000000..9b91c79
|
|
--- /dev/null
|
|
+++ b/sc/source/filter/oox/ooxformulaparser.cxx
|
|
@@ -0,0 +1,196 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
+/*
|
|
+ * This file is part of the LibreOffice project.
|
|
+ *
|
|
+ * This Source Code Form is subject to the terms of the Mozilla Public
|
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
+ *
|
|
+ * This file incorporates work covered by the following license notice:
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed
|
|
+ * with this work for additional information regarding copyright
|
|
+ * ownership. The ASF licenses this file to you under the Apache
|
|
+ * License, Version 2.0 (the "License"); you may not use this file
|
|
+ * except in compliance with the License. You may obtain a copy of
|
|
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
+ */
|
|
+
|
|
+#include "ooxformulaparser.hxx"
|
|
+
|
|
+#include <com/sun/star/uno/XComponentContext.hpp>
|
|
+#include "formulaparser.hxx"
|
|
+
|
|
+namespace oox {
|
|
+namespace xls {
|
|
+
|
|
+// ============================================================================
|
|
+
|
|
+using namespace ::com::sun::star::lang;
|
|
+using namespace ::com::sun::star::sheet;
|
|
+using namespace ::com::sun::star::table;
|
|
+using namespace ::com::sun::star::uno;
|
|
+
|
|
+using ::rtl::OUString;
|
|
+
|
|
+// ============================================================================
|
|
+
|
|
+class OOXMLFormulaParserImpl : private FormulaFinalizer
|
|
+{
|
|
+public:
|
|
+ explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory );
|
|
+
|
|
+ Sequence< FormulaToken > parseFormula( const OUString& rFormula, const CellAddress& rReferencePos );
|
|
+
|
|
+protected:
|
|
+ virtual const FunctionInfo* resolveBadFuncName( const OUString& rTokenData ) const;
|
|
+
|
|
+private:
|
|
+ ApiParserWrapper maApiParser;
|
|
+};
|
|
+
|
|
+// ----------------------------------------------------------------------------
|
|
+
|
|
+OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) :
|
|
+ FormulaFinalizer( OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ),
|
|
+ maApiParser( rxModelFactory, *this )
|
|
+{
|
|
+}
|
|
+
|
|
+Sequence< FormulaToken > OOXMLFormulaParserImpl::parseFormula( const OUString& rFormula, const CellAddress& rReferencePos )
|
|
+{
|
|
+ return finalizeTokenArray( maApiParser.parseFormula( rFormula, rReferencePos ) );
|
|
+}
|
|
+
|
|
+const FunctionInfo* OOXMLFormulaParserImpl::resolveBadFuncName( const OUString& rTokenData ) const
|
|
+{
|
|
+ /* Try to parse calls to library functions. The format of such a function
|
|
+ call is assumed to be
|
|
+ "'<path-to-office-install>\Library\<libname>'!<funcname>". */
|
|
+
|
|
+ // the string has to start with an apostroph (followed by the library URL)
|
|
+ if( (rTokenData.getLength() >= 6) && (rTokenData[ 0 ] == '\'') )
|
|
+ {
|
|
+ // library URL and function name are separated by an exclamation mark
|
|
+ sal_Int32 nExclamPos = rTokenData.lastIndexOf( '!' );
|
|
+ if( (1 < nExclamPos) && (nExclamPos + 1 < rTokenData.getLength()) && (rTokenData[ nExclamPos - 1 ] == '\'') )
|
|
+ {
|
|
+ // find the last backslash that separates library path and name
|
|
+ sal_Int32 nFileSep = rTokenData.lastIndexOf( '\\', nExclamPos - 2 );
|
|
+ if( nFileSep > 1 )
|
|
+ {
|
|
+ // find preceding backslash that separates the last directory name
|
|
+ sal_Int32 nDirSep = rTokenData.lastIndexOf( '\\', nFileSep - 1 );
|
|
+ // function library is located in a directory called 'library'
|
|
+ if( (nDirSep > 0) && rTokenData.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "\\LIBRARY\\" ), nDirSep ) )
|
|
+ {
|
|
+ // try to find a function info for the function name
|
|
+ OUString aFuncName = rTokenData.copy( nExclamPos + 1 ).toAsciiUpperCase();
|
|
+ const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( aFuncName );
|
|
+ if( pFuncInfo && (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) )
|
|
+ {
|
|
+ // check that the name of the library matches
|
|
+ OUString aLibName = rTokenData.copy( nFileSep + 1, nExclamPos - nFileSep - 2 );
|
|
+ if( pFuncInfo->meFuncLibType == getFuncLibTypeFromLibraryName( aLibName ) )
|
|
+ return pFuncInfo;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+// ============================================================================
|
|
+
|
|
+Sequence< OUString > OOXMLFormulaParser_getSupportedServiceNames()
|
|
+{
|
|
+ Sequence< OUString > aServiceNames( 1 );
|
|
+ aServiceNames[ 0 ] = "com.sun.star.sheet.FilterFormulaParser";
|
|
+ return aServiceNames;
|
|
+}
|
|
+
|
|
+OUString OOXMLFormulaParser_getImplementationName()
|
|
+{
|
|
+ return OUString( "com.sun.star.comp.oox.xls.FormulaParser");
|
|
+}
|
|
+
|
|
+Reference< XInterface > OOXMLFormulaParser_create( const Reference< XComponentContext >& )
|
|
+{
|
|
+ return static_cast< ::cppu::OWeakObject* >( new OOXMLFormulaParser );
|
|
+}
|
|
+
|
|
+// ============================================================================
|
|
+
|
|
+OOXMLFormulaParser::OOXMLFormulaParser()
|
|
+{
|
|
+}
|
|
+
|
|
+OOXMLFormulaParser::~OOXMLFormulaParser()
|
|
+{
|
|
+}
|
|
+
|
|
+// com.sun.star.lang.XServiceInfo interface -----------------------------------
|
|
+
|
|
+OUString SAL_CALL OOXMLFormulaParser::getImplementationName() throw( RuntimeException )
|
|
+{
|
|
+ return OOXMLFormulaParser_getImplementationName();
|
|
+}
|
|
+
|
|
+sal_Bool SAL_CALL OOXMLFormulaParser::supportsService( const OUString& rService ) throw( RuntimeException )
|
|
+{
|
|
+ const Sequence< OUString > aServices( OOXMLFormulaParser_getSupportedServiceNames() );
|
|
+ const OUString* pArray = aServices.getConstArray();
|
|
+ const OUString* pArrayEnd = pArray + aServices.getLength();
|
|
+ return ::std::find( pArray, pArrayEnd, rService ) != pArrayEnd;
|
|
+}
|
|
+
|
|
+Sequence< OUString > SAL_CALL OOXMLFormulaParser::getSupportedServiceNames() throw( RuntimeException )
|
|
+{
|
|
+ return OOXMLFormulaParser_getSupportedServiceNames();
|
|
+}
|
|
+
|
|
+// com.sun.star.lang.XInitialization interface --------------------------------
|
|
+
|
|
+void SAL_CALL OOXMLFormulaParser::initialize( const Sequence< Any >& rArgs ) throw( Exception, RuntimeException )
|
|
+{
|
|
+ OSL_ENSURE( rArgs.hasElements(), "OOXMLFormulaParser::initialize - missing arguments" );
|
|
+ if( !rArgs.hasElements() )
|
|
+ throw RuntimeException();
|
|
+ mxComponent.set( rArgs[ 0 ], UNO_QUERY_THROW );
|
|
+}
|
|
+
|
|
+// com.sun.star.sheet.XFilterFormulaParser interface --------------------------
|
|
+
|
|
+OUString SAL_CALL OOXMLFormulaParser::getSupportedNamespace() throw( RuntimeException )
|
|
+{
|
|
+ return OUString( "http://schemas.microsoft.com/office/excel/formula");
|
|
+}
|
|
+
|
|
+// com.sun.star.sheet.XFormulaParser interface --------------------------------
|
|
+
|
|
+Sequence< FormulaToken > SAL_CALL OOXMLFormulaParser::parseFormula(
|
|
+ const OUString& rFormula, const CellAddress& rReferencePos ) throw( RuntimeException )
|
|
+{
|
|
+ if( !mxParserImpl )
|
|
+ {
|
|
+ Reference< XMultiServiceFactory > xModelFactory( mxComponent, UNO_QUERY_THROW );
|
|
+ mxParserImpl.reset( new OOXMLFormulaParserImpl( xModelFactory ) );
|
|
+ }
|
|
+ return mxParserImpl->parseFormula( rFormula, rReferencePos );
|
|
+}
|
|
+
|
|
+OUString SAL_CALL OOXMLFormulaParser::printFormula(
|
|
+ const Sequence< FormulaToken >& /*rTokens*/, const CellAddress& /*rReferencePos*/ ) throw( RuntimeException )
|
|
+{
|
|
+ // not implemented
|
|
+ throw RuntimeException();
|
|
+}
|
|
+
|
|
+// ============================================================================
|
|
+
|
|
+} // namespace xls
|
|
+} // namespace oox
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
diff --git a/sc/util/scfilt.component b/sc/util/scfilt.component
|
|
index 13b884b..292fbd4 100644
|
|
--- a/sc/util/scfilt.component
|
|
+++ b/sc/util/scfilt.component
|
|
@@ -26,4 +26,7 @@
|
|
<service name="com.sun.star.document.ImportFilter"/>
|
|
<service name="com.sun.star.document.ExportFilter"/>
|
|
</implementation>
|
|
+ <implementation name="com.sun.star.comp.oox.xls.FormulaParser">
|
|
+ <service name="com.sun.star.sheet.FilterFormulaParser"/>
|
|
+ </implementation>
|
|
</component>
|
|
--
|
|
1.8.3.1
|
|
|