[Libreoffice-commits] core.git: sc/Library_scfilt.mk sc/source sc/util

Eike Rathke erack at redhat.com
Mon Oct 28 23:04:29 CET 2013


 sc/Library_scfilt.mk                      |    1 
 sc/source/filter/inc/ooxformulaparser.hxx |  110 ++++++++++++++++
 sc/source/filter/oox/ooxformulaparser.cxx |  196 ++++++++++++++++++++++++++++++
 sc/source/filter/services.cxx             |   10 -
 sc/util/scfilt.component                  |    3 
 5 files changed, 316 insertions(+), 4 deletions(-)

New commits:
commit 20e0afa76087e20f95247406d265a122263a8c6f
Author: Eike Rathke <erack at redhat.com>
Date:   Mon Oct 28 22:46:01 2013 +0100

    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
    
    Change-Id: I445b11c95daff6f30b3654936d0f22a113158f97

diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk
index 279ffea..c23af3d 100644
--- a/sc/Library_scfilt.mk
+++ b/sc/Library_scfilt.mk
@@ -191,6 +191,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/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/source/filter/services.cxx b/sc/source/filter/services.cxx
index 2b35042..8818fa1 100644
--- a/sc/source/filter/services.cxx
+++ b/sc/source/filter/services.cxx
@@ -24,15 +24,17 @@
 #include "sal/types.h"
 
 #include "excelfilter.hxx"
+#include "ooxformulaparser.hxx"
+
+#define IMPLEMENTATION_ENTRY( className ) \
+    { &className##_create, &className##_getImplementationName, &className##_getSupportedServiceNames, ::cppu::createSingleComponentFactory, 0, 0 }
 
 extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL scfilt_component_getFactory(
     char const * pImplName, void * pServiceManager, void * pRegistryKey)
 {
     static cppu::ImplementationEntry const services[] = {
-        { oox::xls::ExcelFilter_create,
-          oox::xls::ExcelFilter_getImplementationName,
-          oox::xls::ExcelFilter_getSupportedServiceNames,
-          cppu::createSingleComponentFactory, 0, 0 },
+        IMPLEMENTATION_ENTRY( oox::xls::ExcelFilter ),
+        IMPLEMENTATION_ENTRY( oox::xls::OOXMLFormulaParser ),
         { 0, 0, 0, 0, 0, 0 }
     };
     return cppu::component_getFactoryHelper(
diff --git a/sc/util/scfilt.component b/sc/util/scfilt.component
index 1414435..c4b3728 100644
--- a/sc/util/scfilt.component
+++ b/sc/util/scfilt.component
@@ -23,4 +23,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>


More information about the Libreoffice-commits mailing list