From 9fa41b880dcfef94fa3b7b057f601d97f8a37763 Mon Sep 17 00:00:00 2001 From: Oliver Bolte Date: Mon, 7 Sep 2009 14:41:16 +0000 Subject: [PATCH 01/16] CWS-TOOLING: integrate CWS dr72 2009-08-26 10:24:00 +0200 dr r275402 : #i92645# CODEPAGE is encrypted... 2009-08-24 14:37:36 +0200 dr r275316 : #i10000# enable exceptions for xlroot.cxx 2009-08-24 14:33:15 +0200 dr r275313 : #i10000# link openssl under solaris correctly 2009-08-21 17:41:16 +0200 dr r275267 : #i10000# unxlngi6 warning 2009-08-21 15:35:56 +0200 dr r275265 : #i10000# remove files again, already deleted in previous milestone... 2009-08-21 11:24:57 +0200 dr r275227 : #160401# port to DEV300 2009-08-21 09:53:45 +0200 dr r275221 : #i92645# full support for encrypted Word2007 files 2009-08-21 09:50:52 +0200 dr r275219 : #i92645# final changes for decryption 2009-08-20 19:48:40 +0200 dr r275195 : #i104370# missing parentheses, patch from cmc 2009-08-20 18:28:22 +0200 dr r275193 : #i92645# rework package decryption to repair 'Reload Document' functionality 2009-08-20 13:55:14 +0200 dr r275179 : #i92645# add new property names 2009-08-19 19:24:21 +0200 dr r275159 : #160401# open writeprotected files read-only, merged to DEV300 2009-08-18 14:41:47 +0200 dr r275109 : #i92645# add 'Aborted' property 2009-08-18 11:20:34 +0200 dr r275084 : #i92645# write back password to medium 2009-08-17 17:52:51 +0200 dr r275066 : #i92645# detect Word2007 docs with oox detection impl, this adds support of encryped Word2007; correct detection of templates and macro-enabled docs 2009-08-17 17:51:31 +0200 dr r275065 : #i92645# detect Word2007 docs with oox detection impl, this adds support of encryped Word2007; correct detection of templates and macro-enabled docs 2009-08-17 11:06:39 +0200 dr r275035 : #i92645# more password handling 2009-08-17 11:05:21 +0200 dr r275034 : #i92645# use new password input mechanism for BIFF filter and dumper in oox 2009-08-14 16:33:53 +0200 nn r274996 : #i104228# DelBroadcastAreasInRange: remove area from hash_set before deleting 2009-08-14 16:27:12 +0200 nn r274995 : #i104059# restore a change lost in the integration of fhawfixes1 2009-08-14 16:24:00 +0200 dr r274994 : #i92645# adapt BIFF import to latest changes 2009-08-14 16:21:30 +0200 dr r274993 : #i92645# adapt BIFF import to latest changes 2009-08-14 16:20:43 +0200 dr r274992 : #i92645# do not add default passwords to media descriptor 2009-08-13 19:20:45 +0200 dr r274965 : #i92645# add a helper to request a document password 2009-08-13 19:09:35 +0200 dr r274964 : #i92645# add a helper to request a document password 2009-08-13 19:09:03 +0200 dr r274963 : #i92645# add a helper to request a document password 2009-08-13 14:35:01 +0200 dr r274946 : #i92645# comment typo 2009-08-13 14:33:47 +0200 dr r274945 : #i92645# add a helper to request a document password 2009-08-13 14:04:47 +0200 dr r274941 : #i92645# add a helper to request a document password 2009-08-13 14:04:22 +0200 dr r274940 : #i92645# add a helper to request a document password 2009-08-13 11:16:27 +0200 dr r274927 : #i42303# show quick help if field name too long for button 2009-08-13 10:55:48 +0200 dr r274925 : #i31600# cut field name and add ellipsis, if too long for button 2009-08-12 18:47:26 +0200 dr r274914 : #i92645# ask user for a password 2009-08-12 18:02:39 +0200 dr r274909 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox 2009-08-12 16:59:11 +0200 dr r274906 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox 2009-08-12 16:41:18 +0200 dr r274905 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox 2009-08-12 16:40:33 +0200 dr r274904 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox 2009-08-12 16:40:08 +0200 dr r274903 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox 2009-08-12 16:39:30 +0200 dr r274902 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox 2009-08-12 16:15:28 +0200 dr r274899 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox 2009-08-11 19:51:12 +0200 dr r274877 : #i92645# open encrypted MSOOXML package protected with standard XL password 'VelvetSweatshop' --- .../types/writer_MS_Word_2007_XML.xcu | 2 +- .../writer_MS_Word_2007_XML_Template.xcu | 2 +- oox/inc/oox/core/binarycodec.hxx | 33 +- oox/inc/oox/core/binaryfilterbase.hxx | 5 +- oox/inc/oox/core/filterbase.hxx | 30 +- oox/inc/oox/core/filterdetect.hxx | 168 ++++++ oox/inc/oox/core/xmlfilterbase.hxx | 9 +- oox/inc/oox/dump/dumperbase.hxx | 50 +- oox/inc/oox/xls/biffcodec.hxx | 111 ++-- oox/inc/oox/xls/biffhelper.hxx | 3 + oox/inc/oox/xls/workbooksettings.hxx | 19 + oox/prj/build.lst | 2 +- oox/prj/d.lst | 23 +- oox/source/core/binarycodec.cxx | 23 +- oox/source/core/binaryfilterbase.cxx | 17 +- oox/source/core/filterbase.cxx | 178 ++++-- oox/source/core/filterdetect.cxx | 535 +++++++++++++----- oox/source/core/makefile.mk | 4 + oox/source/core/xmlfilterbase.cxx | 51 +- oox/source/dump/biffdumper.cxx | 84 ++- oox/source/dump/biffdumper.ini | 5 + oox/source/dump/dumperbase.cxx | 55 +- oox/source/dump/pptxdumper.cxx | 4 +- oox/source/dump/xlsbdumper.cxx | 10 +- oox/source/vml/vmlshape.cxx | 2 +- oox/source/xls/biffcodec.cxx | 343 ++++++----- oox/source/xls/workbookfragment.cxx | 64 ++- oox/source/xls/workbooksettings.cxx | 45 ++ oox/source/xls/worksheetsettings.cxx | 15 +- oox/util/makefile.mk | 14 + writerfilter/source/filter/ImportFilter.cxx | 40 +- writerfilter/util/makefile.mk | 5 +- 32 files changed, 1354 insertions(+), 597 deletions(-) create mode 100644 oox/inc/oox/core/filterdetect.hxx diff --git a/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu b/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu index 9efffbea65c5..53a7f5b74ead 100644 --- a/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu +++ b/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu @@ -1,5 +1,5 @@ - com.sun.star.comp.Writer.WriterFilterDetector + com.sun.star.comp.oox.FormatDetector docx docm application/msword diff --git a/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu b/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu index 84e652587920..c0ec68200f22 100644 --- a/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu +++ b/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu @@ -1,5 +1,5 @@ - com.sun.star.comp.Writer.WriterFilterDetector + com.sun.star.comp.oox.FormatDetector dotx dotm application/msword diff --git a/oox/inc/oox/core/binarycodec.hxx b/oox/inc/oox/core/binarycodec.hxx index bb33c214f42d..767b9c2be936 100644 --- a/oox/inc/oox/core/binarycodec.hxx +++ b/oox/inc/oox/core/binarycodec.hxx @@ -34,11 +34,26 @@ #include #include +namespace oox { class AttributeList; } + namespace oox { namespace core { // ============================================================================ +class CodecHelper +{ +public: + /** Returns the password hash if it is in the required 16-bit limit. */ + static sal_uInt16 getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement ); + +private: + CodecHelper(); + ~CodecHelper(); +}; + +// ============================================================================ + /** Encodes and decodes data from/to protected MS Office documents. Implements a simple XOR encoding/decoding algorithm used in MS Office @@ -182,12 +197,12 @@ public: @param pnPassData Unicode character array containing the password. Must be zero terminated, which results in a maximum length of 15 characters. - @param pnUnique - Unique document identifier read from or written to the file. + @param pnSalt + Random salt data block read from or written to the file. */ void initKey( const sal_uInt16 pnPassData[ 16 ], - const sal_uInt8 pnUnique[ 16 ] ); + const sal_uInt8 pnSalt[ 16 ] ); /** Verifies the validity of the password using the passed salt data. @@ -195,17 +210,17 @@ public: The codec must be initialized with the initKey() function before this function can be used. - @param pnSaltData - Salt data block read from the file. - @param pnSaltDigest - Salt digest read from the file. + @param pnVerifier + Verifier block read from the file. + @param pnVerifierHash + Verifier hash read from the file. @return True = test was successful. */ bool verifyKey( - const sal_uInt8 pnSaltData[ 16 ], - const sal_uInt8 pnSaltDigest[ 16 ] ); + const sal_uInt8 pnVerifier[ 16 ], + const sal_uInt8 pnVerifierHash[ 16 ] ); /** Rekeys the codec using the specified counter. diff --git a/oox/inc/oox/core/binaryfilterbase.hxx b/oox/inc/oox/core/binaryfilterbase.hxx index ce2c4f2c31d7..c051934f550c 100644 --- a/oox/inc/oox/core/binaryfilterbase.hxx +++ b/oox/inc/oox/core/binaryfilterbase.hxx @@ -49,8 +49,9 @@ public: private: virtual StorageRef implCreateStorage( - ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream, - ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const; + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const; + virtual StorageRef implCreateStorage( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const; }; typedef ::rtl::Reference< BinaryFilterBase > BinaryFilterRef; diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx index 001b537444c1..9115c88be4e7 100644 --- a/oox/inc/oox/core/filterbase.hxx +++ b/oox/inc/oox/core/filterbase.hxx @@ -44,7 +44,7 @@ #include #include "oox/helper/binarystreambase.hxx" #include "oox/helper/storagebase.hxx" -#include +#include "oox/dllapi.h" namespace com { namespace sun { namespace star { namespace lang { class XMultiServiceFactory; } @@ -58,6 +58,11 @@ namespace com { namespace sun { namespace star { namespace graphic { class XGraphic; } } } } +namespace comphelper { + class IDocPasswordVerifier; + class MediaDescriptor; +} + namespace oox { class GraphicHelper; class ModelObjectHelper; @@ -110,6 +115,9 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& getGlobalFactory() const; + /** Returns the media descriptor. */ + ::comphelper::MediaDescriptor& getMediaDescriptor() const; + /** Returns the document model (always existing). */ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& getModel() const; @@ -193,6 +201,10 @@ public: /** Returns a system color specified by the passed XML token identifier. */ sal_Int32 getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb = -1 ) const; + /** Requests a password from the media descriptor or from the user. On + success, the password will be inserted into the media descriptor. */ + ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const; + /** Imports the raw binary data from the specified stream. @return True, if the data could be imported from the stream. */ bool importBinaryData( StreamDataSequence& orDataSeq, const ::rtl::OUString& rStreamName ); @@ -251,19 +263,29 @@ public: // com.sun.star.document.XFilter interface -------------------------------- virtual sal_Bool SAL_CALL filter( - const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rDescriptor ) + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq ) throw( ::com::sun::star::uno::RuntimeException ); virtual void SAL_CALL cancel() throw( ::com::sun::star::uno::RuntimeException ); // ------------------------------------------------------------------------ +protected: + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > + implGetInputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > + implGetOutputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const; + private: + void setMediaDescriptor( + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq ); + virtual ::rtl::OUString implGetImplementationName() const = 0; virtual StorageRef implCreateStorage( - ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream, - ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const = 0; + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const = 0; + virtual StorageRef implCreateStorage( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const = 0; private: ::std::auto_ptr< FilterBaseImpl > mxImpl; diff --git a/oox/inc/oox/core/filterdetect.hxx b/oox/inc/oox/core/filterdetect.hxx new file mode 100644 index 000000000000..bd9e3a84ff3a --- /dev/null +++ b/oox/inc/oox/core/filterdetect.hxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: filterdetect.hxx,v $ + * $Revision: 1.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_CORE_FILTERDETECT_HXX +#define OOX_CORE_FILTERDETECT_HXX + +#include +#include +#include +#include +#include +#include +#include "oox/dllapi.h" + +namespace com { namespace sun { namespace star { + namespace io { class XInputStream; } +} } } + +namespace comphelper { class MediaDescriptor; } +namespace oox { class AttributeList; } + +namespace oox { +namespace core { + +// ============================================================================ + +/** Document handler specifically designed for detecting OOXML file formats. + + It takes a reference to the filter string object via its constructor, and + puts the name of the detected filter to it, if it successfully finds one. + */ +class FilterDetectDocHandler : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastDocumentHandler > +{ +public: + explicit FilterDetectDocHandler( ::rtl::OUString& rFilter ); + virtual ~FilterDetectDocHandler(); + + // XFastDocumentHandler + virtual void SAL_CALL startDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + + // XFastContextHandler + virtual void SAL_CALL startFastElement( sal_Int32 nElement, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endFastElement( sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + +private: + void parseRelationship( const AttributeList& rAttribs ); + + ::rtl::OUString getFilterNameFromContentType( const ::rtl::OUString& rContentType ) const; + void parseContentTypesDefault( const AttributeList& rAttribs ); + void parseContentTypesOverride( const AttributeList& rAttribs ); + +private: + typedef ::std::vector< sal_Int32 > ContextVector; + + ::rtl::OUString& mrFilterName; + ContextVector maContextStack; + ::rtl::OUString maTargetPath; +}; + +// ============================================================================ + +class OOX_DLLPUBLIC FilterDetect : public ::cppu::WeakImplHelper2< ::com::sun::star::document::XExtendedFilterDetection, ::com::sun::star::lang::XServiceInfo > +{ +public: + explicit FilterDetect( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory ); + virtual ~FilterDetect(); + + /** Tries to extract an unencrypted ZIP package from the passed media + descriptor. + + First, this function checks if the input stream provided by the media + descriptor property 'InputStream' contains a ZIP package. If yes, this + stream is returned. + + Second, this function checks if the 'ComponentData' property exists and + contains a sequence of com.sun.star.beans.NamedValue. If yes, a named + value is searched with the name 'DecryptedPackage' and a value of type + com.sun.star.io.XStream. If the input stream provided by this XStream + contains a ZIP package, this input stream is returned. + + Third, this function checks if the input stream of the media descriptor + contains an OLE package. If yes, it checks the existence of the streams + 'EncryptionInfo' and 'EncyptedPackage' and tries to decrypt the package + into a temporary file. This may include requesting a password from the + media descriptor property 'Password' or from the user, using the + interaction handler provided by the descriptor. On success, and if the + decrypted package is a ZIP package, the XStream of the temporary file + is stored in the property 'ComponentData' of the media descriptor and + its input stream is returned. + */ + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > + extractUnencryptedPackage( ::comphelper::MediaDescriptor& rMediaDesc ) const; + + // 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& rServiceName ) 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.document.XExtendedFilterDetection interface --------------- + + /** Detects MS Office 2007 file types and supports package decryption. + + The following file types are detected: + - MS Word 2007 XML Document (*.docx, *.docm) + - MS Word 2007 XML Template (*.dotx, *.dotm) + - MS Excel 2007 XML Document (*.xlsx, *.xlsm) + - MS Excel 2007 BIFF12 Document (*.xlsb) + - MS Excel 2007 XML Template (*.xltx, *.xltm) + - MS Powerpoint 2007 XML Document (*.pptx, *.pptm) + - MS Powerpoint 2007 XML Template (*.potx, *.potm) + + If the package is encrypted, the detection tries to decrypt it into a + temporary file. The user may be asked for a password. The XStream + interface of the temporary file will be stored in the 'ComponentData' + property of the passed media descriptor. + */ + virtual ::rtl::OUString SAL_CALL detect( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq ) + throw( ::com::sun::star::uno::RuntimeException ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxFactory; +}; + +// ============================================================================ + +} // namespace core +} // namespace oox + +#endif + diff --git a/oox/inc/oox/core/xmlfilterbase.hxx b/oox/inc/oox/core/xmlfilterbase.hxx index f88554457e36..d1b79dc116d8 100644 --- a/oox/inc/oox/core/xmlfilterbase.hxx +++ b/oox/inc/oox/core/xmlfilterbase.hxx @@ -204,10 +204,15 @@ public: */ XmlFilterBase& exportDocumentProperties( ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties > xProperties ); +protected: + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > + implGetInputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const; + private: virtual StorageRef implCreateStorage( - ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream, - ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const; + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const; + virtual StorageRef implCreateStorage( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const; private: ::std::auto_ptr< XmlFilterBaseImpl > mxImpl; diff --git a/oox/inc/oox/dump/dumperbase.hxx b/oox/inc/oox/dump/dumperbase.hxx index 0c5314c4adc7..9a791942ce4e 100644 --- a/oox/inc/oox/dump/dumperbase.hxx +++ b/oox/inc/oox/dump/dumperbase.hxx @@ -41,6 +41,7 @@ #include #include #include +#include #include "oox/helper/helper.hxx" #include "oox/helper/storagebase.hxx" #include "oox/helper/binaryinputstream.hxx" @@ -57,6 +58,10 @@ namespace com { namespace sun { namespace star { namespace lang { class XMultiServiceFactory; } } } } +namespace comphelper { + class IDocPasswordVerifier; +} + namespace oox { class BinaryOutputStream; } @@ -866,7 +871,8 @@ public: const ::rtl::OUString& rFileName, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, - const ::rtl::OUString& rSysFileName ); + const ::rtl::OUString& rSysFileName, + ::comphelper::MediaDescriptor& rMediaDesc ); virtual ~SharedConfigData(); @@ -883,6 +889,9 @@ public: void eraseNameList( const ::rtl::OUString& rListName ); NameListRef getNameList( const ::rtl::OUString& rListName ) const; + ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ); + inline bool isPasswordCancelled() const { return mbPwCancelled; } + protected: virtual bool implIsValid() const; virtual void implProcessConfigItemStr( @@ -905,11 +914,13 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxFactory; StorageRef mxRootStrg; ::rtl::OUString maSysFileName; + ::comphelper::MediaDescriptor& mrMediaDesc; ConfigFileSet maConfigFiles; ConfigDataMap maConfigData; NameListMap maNameLists; ::rtl::OUString maConfigPath; bool mbLoaded; + bool mbPwCancelled; }; // ---------------------------------------------------------------------------- @@ -947,7 +958,8 @@ public: const sal_Char* pcEnvVar, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, - const ::rtl::OUString& rSysFileName ); + const ::rtl::OUString& rSysFileName, + ::comphelper::MediaDescriptor& rMediaDesc ); virtual ~Config(); @@ -978,6 +990,9 @@ public: template< typename Type > bool hasName( const NameListWrapper& rListWrp, Type nKey ) const; + ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ); + bool isPasswordCancelled() const; + protected: inline explicit Config() {} void construct( const Config& rParent ); @@ -988,7 +1003,8 @@ protected: const sal_Char* pcEnvVar, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, - const ::rtl::OUString& rSysFileName ); + const ::rtl::OUString& rSysFileName, + ::comphelper::MediaDescriptor& rMediaDesc ); virtual bool implIsValid() const; virtual const ::rtl::OUString* implGetOption( const ::rtl::OUString& rKey ) const; @@ -1822,11 +1838,6 @@ class RecordObjectBase : public InputObjectBase protected: inline explicit RecordObjectBase() {} - inline sal_Int64 getRecPos() const { return mnRecPos; } - inline sal_Int64 getRecId() const { return mnRecId; } - inline sal_Int64 getRecSize() const { return mnRecSize; } - inline NameListRef getRecNames() const { return maRecNames.getNameList( cfg() ); } - using InputObjectBase::construct; void construct( const ObjectBase& rParent, @@ -1842,6 +1853,14 @@ protected: const String& rRecNames, const String& rSimpleRecs = EMPTY_STRING ); + inline sal_Int64 getRecPos() const { return mnRecPos; } + inline sal_Int64 getRecId() const { return mnRecId; } + inline sal_Int64 getRecSize() const { return mnRecSize; } + inline NameListRef getRecNames() const { return maRecNames.getNameList( cfg() ); } + + inline void setBinaryOnlyMode( bool bBinaryOnly ) { mbBinaryOnly = bBinaryOnly; } + inline bool isBinaryOnlyMode() const { return mbBinaryOnly; } + virtual bool implIsValid() const; virtual void implDump(); @@ -1865,6 +1884,7 @@ private: sal_Int64 mnRecId; sal_Int64 mnRecSize; bool mbShowRecPos; + bool mbBinaryOnly; }; // ============================================================================ @@ -1922,6 +1942,7 @@ public: virtual ~DumperBase(); bool isImportEnabled() const; + bool isImportCancelled() const; protected: inline explicit DumperBase() {} @@ -1936,12 +1957,13 @@ protected: } // namespace dump } // namespace oox -#define OOX_DUMP_FILE( DumperClassName ) \ -do { \ - DumperClassName aDumper( *this ); \ - aDumper.dump(); \ - if( !aDumper.isImportEnabled() ) \ - return aDumper.isValid(); \ +#define OOX_DUMP_FILE( DumperClassName ) \ +do { \ + DumperClassName aDumper( *this ); \ + aDumper.dump(); \ + bool bCancelled = aDumper.isImportCancelled(); \ + if( !aDumper.isImportEnabled() || bCancelled ) \ + return aDumper.isValid() && !bCancelled; \ } while( false ) #else // OOX_INCLUDE_DUMPER diff --git a/oox/inc/oox/xls/biffcodec.hxx b/oox/inc/oox/xls/biffcodec.hxx index 165a608d46fd..3fc5d77b474e 100644 --- a/oox/inc/oox/xls/biffcodec.hxx +++ b/oox/inc/oox/xls/biffcodec.hxx @@ -32,6 +32,7 @@ #define OOX_XLS_BIFFCODEC_HXX #include +#include #include "oox/core/binarycodec.hxx" #include "oox/xls/workbookhelper.hxx" @@ -40,29 +41,27 @@ namespace xls { // ============================================================================ -const sal_Int32 CODEC_OK = 0; -const sal_Int32 CODEC_ERROR_WRONG_PASS = 1; -const sal_Int32 CODEC_ERROR_UNSUPP_CRYPT = 2; - const sal_Int64 BIFF_RCF_BLOCKSIZE = 1024; // ============================================================================ /** Base class for BIFF stream decoders. */ -class BiffDecoderBase : public WorkbookHelper +class BiffDecoderBase : public ::comphelper::IDocPasswordVerifier { public: - explicit BiffDecoderBase( const WorkbookHelper& rHelper ); + explicit BiffDecoderBase(); virtual ~BiffDecoderBase(); /** Derived classes return a clone of the decoder for usage in new streams. */ inline BiffDecoderBase* clone() { return implClone(); } - /** Returns the current error code of the decoder. */ - inline sal_Int32 getErrorCode() const { return mnError; } - /** Returns true, if the decoder has been constructed successfully. - This means especially that construction happened with a valid password. */ - inline bool isValid() const { return mnError == CODEC_OK; } + /** Implementation of the ::comphelper::IDocPasswordVerifier interface, + calls the new virtual function implVerify(). */ + virtual ::comphelper::DocPasswordVerifierResult + verifyPassword( const ::rtl::OUString& rPassword ); + + /** Returns true, if the decoder has been initialized correctly. */ + inline bool isValid() const { return mbValid; } /** Decodes nBytes bytes and writes encrypted data into the buffer pnDestData. */ void decode( @@ -71,17 +70,14 @@ public: sal_Int64 nStreamPos, sal_uInt16 nBytes ); -protected: - /** Copy constructor for cloning. */ - BiffDecoderBase( const BiffDecoderBase& rDecoder ); - - /** Sets the decoder to a state showing whether the password was correct. */ - void setHasValidPassword( bool bValid ); - private: /** Derived classes return a clone of the decoder for usage in new streams. */ virtual BiffDecoderBase* implClone() = 0; + /** Derived classes implement password verification and initialization of + the decoder. */ + virtual bool implVerify( const ::rtl::OUString& rPassword ) = 0; + /** Implementation of decryption of a memory block. */ virtual void implDecode( sal_uInt8* pnDestData, @@ -90,7 +86,7 @@ private: sal_uInt16 nBytes ) = 0; private: - sal_Int32 mnError; /// Decoder error code. + bool mbValid; /// True = decoder is correctly initialized. }; typedef ::boost::shared_ptr< BiffDecoderBase > BiffDecoderRef; @@ -101,31 +97,18 @@ typedef ::boost::shared_ptr< BiffDecoderBase > BiffDecoderRef; class BiffDecoder_XOR : public BiffDecoderBase { public: - /** Constructs the decoder. - - Checks if the passed key and hash specify workbook protection. Asks for - a password otherwise. - - @param nKey - Password key from FILEPASS record to verify password. - @param nHash - Password hash value from FILEPASS record to verify password. - */ - explicit BiffDecoder_XOR( - const WorkbookHelper& rHelper, - sal_uInt16 nKey, sal_uInt16 nHash ); + explicit BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ); private: /** Copy constructor for cloning. */ BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ); - /** Initializes the wrapped codec object. After that, internal status can - be querried with isValid(). */ - void init( const ::rtl::OString& rPass ); - /** Returns a clone of the decoder for usage in new streams. */ virtual BiffDecoder_XOR* implClone(); + /** Implements password verification and initialization of the decoder. */ + virtual bool implVerify( const ::rtl::OUString& rPassword ); + /** Implementation of decryption of a memory block. */ virtual void implDecode( sal_uInt8* pnDestData, @@ -135,7 +118,7 @@ private: private: ::oox::core::BinaryCodec_XOR maCodec; /// Cipher algorithm implementation. - ::rtl::OString maPass; + ::std::vector< sal_uInt8 > maPassword; sal_uInt16 mnKey; sal_uInt16 mnHash; }; @@ -146,35 +129,21 @@ private: class BiffDecoder_RCF : public BiffDecoderBase { public: - /** Constructs the decoder. - - Checks if the passed salt data specifies workbook protection. Asks for - a password otherwise. - - @param pnDocId - Unique document identifier from FILEPASS record. - @param pnSaltData - Salt data from FILEPASS record. - @param pnSaltHash - Salt hash value from FILEPASS record. - */ explicit BiffDecoder_RCF( - const WorkbookHelper& rHelper, - sal_uInt8 pnDocId[ 16 ], - sal_uInt8 pnSaltData[ 16 ], - sal_uInt8 pnSaltHash[ 16 ] ); + sal_uInt8 pnSalt[ 16 ], + sal_uInt8 pnVerifier[ 16 ], + sal_uInt8 pnVerifierHash[ 16 ] ); private: /** Copy constructor for cloning. */ BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ); - /** Initializes the wrapped codec object. After that, internal status can - be querried with isValid(). */ - void init( const ::rtl::OUString& rPass ); - /** Returns a clone of the decoder for usage in new streams. */ virtual BiffDecoder_RCF* implClone(); + /** Implements password verification and initialization of the decoder. */ + virtual bool implVerify( const ::rtl::OUString& rPassword ); + /** Implementation of decryption of a memory block. */ virtual void implDecode( sal_uInt8* pnDestData, @@ -184,10 +153,10 @@ private: private: ::oox::core::BinaryCodec_RCF maCodec; /// Cipher algorithm implementation. - ::rtl::OUString maPass; - ::std::vector< sal_uInt8 > maDocId; - ::std::vector< sal_uInt8 > maSaltData; - ::std::vector< sal_uInt8 > maSaltHash; + ::std::vector< sal_uInt16 > maPassword; + ::std::vector< sal_uInt8 > maSalt; + ::std::vector< sal_uInt8 > maVerifier; + ::std::vector< sal_uInt8 > maVerifierHash; }; // ============================================================================ @@ -198,30 +167,16 @@ class BiffCodecHelper : public WorkbookHelper public: explicit BiffCodecHelper( const WorkbookHelper& rHelper ); - /** Returns the fixed password for workbook protection. */ - static const ::rtl::OString& getBiff5WbProtPassword(); - /** Returns the fixed password for workbook protection. */ - static const ::rtl::OUString& getBiff8WbProtPassword(); + /** Implementation helper, reads the FILEPASS and returns a decoder object. */ + static BiffDecoderRef implReadFilePass( BiffInputStream& rStrm, BiffType eBiff ); - /** Looks for a password provided via API, or queries it via GUI. */ - ::rtl::OUString queryPassword(); - - /** Imports the FILEPASS record and sets a decoder at the stream. */ + /** Imports the FILEPASS record, asks for a password and sets a decoder at the stream. */ bool importFilePass( BiffInputStream& rStrm ); /** Clones the contained decoder object if existing and sets it at the passed stream. */ void cloneDecoder( BiffInputStream& rStrm ); -private: - void importFilePass_XOR( BiffInputStream& rStrm ); - void importFilePass_RCF( BiffInputStream& rStrm ); - void importFilePass_Strong( BiffInputStream& rStrm ); - void importFilePass2( BiffInputStream& rStrm ); - void importFilePass8( BiffInputStream& rStrm ); - private: BiffDecoderRef mxDecoder; /// The decoder for import filter. - ::rtl::OUString maPassword; /// Password for stream encoder/decoder. - bool mbHasPassword; /// True = password already querried. }; // ============================================================================ diff --git a/oox/inc/oox/xls/biffhelper.hxx b/oox/inc/oox/xls/biffhelper.hxx index 8d9aac767bba..1da2c362170f 100644 --- a/oox/inc/oox/xls/biffhelper.hxx +++ b/oox/inc/oox/xls/biffhelper.hxx @@ -120,6 +120,7 @@ const sal_Int32 OOBIN_ID_EXTROW = 0x016E; const sal_Int32 OOBIN_ID_EXTSHEETDATA = 0x016B; const sal_Int32 OOBIN_ID_EXTERNALNAMEFLAGS = 0x024A; const sal_Int32 OOBIN_ID_EXTSHEETNAMES = 0x0167; +const sal_Int32 OOBIN_ID_FILESHARING = 0x0224; const sal_Int32 OOBIN_ID_FILEVERSION = 0x0080; const sal_Int32 OOBIN_ID_FILL = 0x002D; const sal_Int32 OOBIN_ID_FILLS = 0x025B; @@ -369,6 +370,7 @@ const sal_uInt16 BIFF5_ID_EXTERNALNAME = 0x0023; const sal_uInt16 BIFF_ID_EXTERNSHEET = 0x0017; const sal_uInt16 BIFF_ID_EXTSST = 0x00FF; const sal_uInt16 BIFF_ID_FILEPASS = 0x002F; +const sal_uInt16 BIFF_ID_FILESHARING = 0x005B; const sal_uInt16 BIFF2_ID_FONT = 0x0031; const sal_uInt16 BIFF3_ID_FONT = 0x0231; const sal_uInt16 BIFF5_ID_FONT = 0x0031; @@ -388,6 +390,7 @@ const sal_uInt16 BIFF_ID_HYPERLINK = 0x01B8; const sal_uInt16 BIFF3_ID_IMGDATA = 0x007F; const sal_uInt16 BIFF8_ID_IMGDATA = 0x00E9; const sal_uInt16 BIFF2_ID_INTEGER = 0x0002; +const sal_uInt16 BIFF_ID_INTERFACEHDR = 0x00E1; const sal_uInt16 BIFF_ID_ITERATION = 0x0011; const sal_uInt16 BIFF_ID_IXFE = 0x0044; const sal_uInt16 BIFF2_ID_LABEL = 0x0004; diff --git a/oox/inc/oox/xls/workbooksettings.hxx b/oox/inc/oox/xls/workbooksettings.hxx index 683747c03ed6..81712bd5c5a1 100644 --- a/oox/inc/oox/xls/workbooksettings.hxx +++ b/oox/inc/oox/xls/workbooksettings.hxx @@ -40,6 +40,18 @@ namespace xls { // ============================================================================ +/** Settings for workbook write protection. */ +struct FileSharingModel +{ + ::rtl::OUString maUserName; /// User who added the write protection password. + sal_uInt16 mnPasswordHash; /// Hash value of the write protection password. + bool mbRecommendReadOnly; /// True = recommend read-only mode on opening. + + explicit FileSharingModel(); +}; + +// ============================================================================ + /** Global workbook settings. */ struct WorkbookSettingsModel { @@ -84,11 +96,15 @@ class WorkbookSettings : public WorkbookHelper public: explicit WorkbookSettings( const WorkbookHelper& rHelper ); + /** Imports the fileSharing element containing write protection settings. */ + void importFileSharing( const AttributeList& rAttribs ); /** Imports the workbookPr element containing global workbook settings. */ void importWorkbookPr( const AttributeList& rAttribs ); /** Imports the calcPr element containing workbook calculation settings. */ void importCalcPr( const AttributeList& rAttribs ); + /** Imports the FILESHARING record containing write protection settings. */ + void importFileSharing( RecordInputStream& rStrm ); /** Imports the WORKBOOKPR record containing global workbook settings. */ void importWorkbookPr( RecordInputStream& rStrm ); /** Imports the CALCPR record containing workbook calculation settings. */ @@ -96,6 +112,8 @@ public: /** Sets the save external linked values flag, e.g. from the WSBOOL record. */ void setSaveExtLinkValues( bool bSaveExtLinks ); + /** Imports the FILESHARING record. */ + void importFileSharing( BiffInputStream& rStrm ); /** Imports the BOOKBOOL record. */ void importBookBool( BiffInputStream& rStrm ); /** Imports the CALCCOUNT record. */ @@ -136,6 +154,7 @@ private: void setDateMode( bool bDateMode1904 ); private: + FileSharingModel maFileSharing; WorkbookSettingsModel maBookSettings; CalcSettingsModel maCalcSettings; }; diff --git a/oox/prj/build.lst b/oox/prj/build.lst index b95c5cba0164..a1dfa584543c 100644 --- a/oox/prj/build.lst +++ b/oox/prj/build.lst @@ -1,4 +1,4 @@ -oox oox : vos cppu cppuhelper comphelper sal offapi sax basegfx tools vcl BOOST:boost NULL +oox oox : vos cppu cppuhelper comphelper sal offapi sax basegfx tools vcl BOOST:boost OPENSSL:openssl NULL oox oox usr1 - all oox_mkout NULL oox oox\prj get - all oox_prj NULL oox oox\source\token nmake - all oox_token NULL diff --git a/oox/prj/d.lst b/oox/prj/d.lst index df4430bcd058..50ec05955ca6 100644 --- a/oox/prj/d.lst +++ b/oox/prj/d.lst @@ -1,10 +1,10 @@ mkdir: %_DEST%\inc%_EXT%\oox -mkdir: %_DEST%\inc%_EXT%\oox\core mkdir: %_DEST%\inc%_EXT%\oox\helper -mkdir: %_DEST%\inc%_EXT%\oox\vml +mkdir: %_DEST%\inc%_EXT%\oox\core mkdir: %_DEST%\inc%_EXT%\oox\drawingml mkdir: %_DEST%\inc%_EXT%\oox\drawingml\chart mkdir: %_DEST%\inc%_EXT%\oox\drawingml\table +mkdir: %_DEST%\inc%_EXT%\oox\vml ..\%__SRC%\misc\*.map %_DEST%\bin%_EXT%\*.map ..\%__SRC%\lib\ixo.lib %_DEST%\lib%_EXT%\ixo.lib @@ -13,23 +13,24 @@ mkdir: %_DEST%\inc%_EXT%\oox\drawingml\table ..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*.dll ..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%\lib*.so ..\%__SRC%\lib\i*.lib %_DEST%\lib%_EXT%\i*.lib +..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib -..\inc\oox\dllapi.h %_DEST%\inc%_EXT%\oox\dllapi.h -..\source\token\tokens.txt %_DEST%\inc%_EXT%\oox\token.txt -..\inc\oox\core\filterbase.hxx %_DEST%\inc%_EXT%\oox\core\filterbase.hxx -..\inc\oox\core\relations.hxx %_DEST%\inc%_EXT%\oox\core\relations.hxx ..\%__SRC%\inc\tokens.hxx %_DEST%\inc%_EXT%\oox\core\tokens.hxx -..\inc\oox\core\xmlfilterbase.hxx %_DEST%\inc%_EXT%\oox\core\xmlfilterbase.hxx + +..\source\token\tokens.txt %_DEST%\inc%_EXT%\oox\token.txt +..\inc\oox\dllapi.h %_DEST%\inc%_EXT%\oox\dllapi.h ..\inc\oox\helper\binarystreambase.hxx %_DEST%\inc%_EXT%\oox\helper\binarystreambase.hxx ..\inc\oox\helper\helper.hxx %_DEST%\inc%_EXT%\oox\helper\helper.hxx ..\inc\oox\helper\storagebase.hxx %_DEST%\inc%_EXT%\oox\helper\storagebase.hxx ..\inc\oox\helper\zipstorage.hxx %_DEST%\inc%_EXT%\oox\helper\zipstorage.hxx -..\inc\oox\vml\drawing.hxx %_DEST%\inc%_EXT%\oox\vml\drawing.hxx +..\inc\oox\core\filterbase.hxx %_DEST%\inc%_EXT%\oox\core\filterbase.hxx +..\inc\oox\core\filterdetect.hxx %_DEST%\inc%_EXT%\oox\core\filterdetect.hxx +..\inc\oox\core\relations.hxx %_DEST%\inc%_EXT%\oox\core\relations.hxx +..\inc\oox\core\xmlfilterbase.hxx %_DEST%\inc%_EXT%\oox\core\xmlfilterbase.hxx ..\inc\oox\drawingml\chart\chartconverter.hxx %_DEST%\inc%_EXT%\oox\drawingml\chart\chartconverter.hxx ..\inc\oox\drawingml\table\tablestylelist.hxx %_DEST%\inc%_EXT%\oox\drawingml\table\tablestylelist.hxx -..\inc\oox\vml\shape.hxx %_DEST%\inc%_EXT%\oox\vml\shape.hxx - -..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib +..\inc\oox\vml\vmldrawing.hxx %_DEST%\inc%_EXT%\oox\vml\vmldrawing.hxx +..\inc\oox\vml\vmlshape.hxx %_DEST%\inc%_EXT%\oox\vml\vmlshape.hxx dos: sh -c "if test %OS% = MACOSX; then create-bundle %_DEST%\lib%_EXT%\*.dylib; fi" diff --git a/oox/source/core/binarycodec.cxx b/oox/source/core/binarycodec.cxx index 78161b161aab..b6a7e92986b6 100644 --- a/oox/source/core/binarycodec.cxx +++ b/oox/source/core/binarycodec.cxx @@ -31,7 +31,7 @@ #include "oox/core/binarycodec.hxx" #include #include -#include +#include "oox/helper/attributelist.hxx" namespace oox { namespace core { @@ -113,6 +113,15 @@ sal_uInt16 lclGetHash( const sal_uInt8* pnPassData, sal_Int32 nBufferSize ) // ============================================================================ +/*static*/ sal_uInt16 CodecHelper::getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement ) +{ + sal_Int32 nPasswordHash = rAttribs.getIntegerHex( nElement, 0 ); + OSL_ENSURE( (0 <= nPasswordHash) && (nPasswordHash <= SAL_MAX_UINT16), "CodecHelper::getPasswordHash - invalid password hash" ); + return static_cast< sal_uInt16 >( ((0 <= nPasswordHash) && (nPasswordHash <= SAL_MAX_UINT16)) ? nPasswordHash : 0 ); +} + +// ============================================================================ + BinaryCodec_XOR::BinaryCodec_XOR( CodecType eCodecType ) : meCodecType( eCodecType ), mnOffset( 0 ), @@ -249,7 +258,7 @@ BinaryCodec_RCF::~BinaryCodec_RCF() rtl_cipher_destroy( mhCipher ); } -void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnUnique[ 16 ] ) +void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnSalt[ 16 ] ) { // create little-endian key data array from password data sal_uInt8 pnKeyData[ 64 ]; @@ -271,11 +280,11 @@ void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt (void)rtl_digest_updateMD5( mhDigest, pnKeyData, sizeof( pnKeyData ) ); (void)rtl_digest_rawMD5( mhDigest, pnKeyData, RTL_DIGEST_LENGTH_MD5 ); - // update digest with key data and passed unique data + // update digest with key data and passed salt data for( size_t nIndex = 0; nIndex < 16; ++nIndex ) { rtl_digest_updateMD5( mhDigest, pnKeyData, 5 ); - rtl_digest_updateMD5( mhDigest, pnUnique, 16 ); + rtl_digest_updateMD5( mhDigest, pnSalt, 16 ); } // update digest with padding @@ -292,7 +301,7 @@ void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt (void)memset( pnKeyData, 0, sizeof( pnKeyData ) ); } -bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnSaltData[ 16 ], const sal_uInt8 pnSaltDigest[ 16 ] ) +bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnVerifier[ 16 ], const sal_uInt8 pnVerifierHash[ 16 ] ) { if( !startBlock( 0 ) ) return false; @@ -301,7 +310,7 @@ bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnSaltData[ 16 ], const sal_uIn sal_uInt8 pnBuffer[ 64 ]; // decode salt data into buffer - rtl_cipher_decode( mhCipher, pnSaltData, 16, pnBuffer, sizeof( pnBuffer ) ); + rtl_cipher_decode( mhCipher, pnVerifier, 16, pnBuffer, sizeof( pnBuffer ) ); pnBuffer[ 16 ] = 0x80; (void)memset( pnBuffer + 17, 0, sizeof( pnBuffer ) - 17 ); @@ -312,7 +321,7 @@ bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnSaltData[ 16 ], const sal_uIn rtl_digest_rawMD5( mhDigest, pnDigest, sizeof( pnDigest ) ); // decode original salt digest into buffer - rtl_cipher_decode( mhCipher, pnSaltDigest, 16, pnBuffer, sizeof( pnBuffer ) ); + rtl_cipher_decode( mhCipher, pnVerifierHash, 16, pnBuffer, sizeof( pnBuffer ) ); // compare buffer with computed digest bool bResult = memcmp( pnBuffer, pnDigest, sizeof( pnDigest ) ) == 0; diff --git a/oox/source/core/binaryfilterbase.cxx b/oox/source/core/binaryfilterbase.cxx index 86e89318d476..c883284de664 100644 --- a/oox/source/core/binaryfilterbase.cxx +++ b/oox/source/core/binaryfilterbase.cxx @@ -51,15 +51,16 @@ BinaryFilterBase::~BinaryFilterBase() { } -StorageRef BinaryFilterBase::implCreateStorage( - Reference< XInputStream >& rxInStream, Reference< XStream >& rxOutStream ) const +// private -------------------------------------------------------------------- + +StorageRef BinaryFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const { - StorageRef xStorage; - if( rxInStream.is() ) - xStorage.reset( new OleStorage( getGlobalFactory(), rxInStream, true ) ); - else if( rxOutStream.is() ) - xStorage.reset( new OleStorage( getGlobalFactory(), rxOutStream, true ) ); - return xStorage; + return StorageRef( new OleStorage( getGlobalFactory(), rxInStream, true ) ); +} + +StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const +{ + return StorageRef( new OleStorage( getGlobalFactory(), rxOutStream, true ) ); } // ============================================================================ diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index 23363db46ed5..55793859fe2e 100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "tokens.hxx" #include "oox/helper/binaryinputstream.hxx" @@ -58,7 +59,6 @@ using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::lang::IllegalArgumentException; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::lang::XComponent; -using ::com::sun::star::beans::NamedValue; using ::com::sun::star::beans::PropertyValue; using ::com::sun::star::awt::DeviceInfo; using ::com::sun::star::awt::XDevice; @@ -72,6 +72,7 @@ using ::com::sun::star::task::XStatusIndicator; using ::com::sun::star::task::XInteractionHandler; using ::com::sun::star::graphic::XGraphic; using ::comphelper::MediaDescriptor; +using ::comphelper::SequenceAsHashMap; using ::oox::ole::OleObjectHelper; namespace oox { @@ -125,6 +126,16 @@ DocumentOpenedGuard::~DocumentOpenedGuard() // ============================================================================ +/** Specifies whether this filter is an import or export filter. */ +enum FilterDirection +{ + FILTERDIRECTION_UNKNOWN, + FILTERDIRECTION_IMPORT, + FILTERDIRECTION_EXPORT +}; + +// ---------------------------------------------------------------------------- + struct FilterBaseImpl { typedef ::boost::shared_ptr< GraphicHelper > GraphicHelperRef; @@ -132,9 +143,10 @@ struct FilterBaseImpl typedef ::boost::shared_ptr< OleObjectHelper > OleObjHelperRef; typedef ::std::map< OUString, Reference< XGraphic > > EmbeddedGraphicMap; typedef ::std::map< sal_Int32, sal_Int32 > SystemPalette; - typedef ::std::map< OUString, Any > ArgumentMap; - MediaDescriptor maDescriptor; + FilterDirection meDirection; + SequenceAsHashMap maArguments; + MediaDescriptor maMediaDesc; DeviceInfo maDeviceInfo; OUString maFileUrl; StorageRef mxStorage; @@ -145,7 +157,6 @@ struct FilterBaseImpl EmbeddedGraphicMap maEmbeddedGraphics; /// Maps all imported embedded graphics by their path. SystemPalette maSystemPalette; /// Maps system colors (XML tokens) to RGB color values. - ArgumentMap maArguments; Reference< XMultiServiceFactory > mxGlobalFactory; Reference< XModel > mxModel; Reference< XMultiServiceFactory > mxModelFactory; @@ -157,14 +168,16 @@ struct FilterBaseImpl explicit FilterBaseImpl( const Reference< XMultiServiceFactory >& rxGlobalFactory ); void setDocumentModel( const Reference< XComponent >& rxComponent ); - void setMediaDescriptor( const Sequence< PropertyValue >& rDescriptor ); - bool hasDocumentModel() const; + + void initializeFilter(); + void finalizeFilter(); }; // ---------------------------------------------------------------------------- FilterBaseImpl::FilterBaseImpl( const Reference< XMultiServiceFactory >& rxGlobalFactory ) : + meDirection( FILTERDIRECTION_UNKNOWN ), mxGlobalFactory( rxGlobalFactory ) { OSL_ENSURE( mxGlobalFactory.is(), "FilterBaseImpl::FilterBaseImpl - missing service factory" ); @@ -223,25 +236,41 @@ void FilterBaseImpl::setDocumentModel( const Reference< XComponent >& rxComponen mxModelFactory.set( rxComponent, UNO_QUERY ); } -void FilterBaseImpl::setMediaDescriptor( const Sequence< PropertyValue >& rDescriptor ) -{ - maDescriptor = rDescriptor; - - maFileUrl = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), maFileUrl ); - mxInStream = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_INPUTSTREAM(), mxInStream ); - mxOutStream = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_STREAMFOROUTPUT(), mxOutStream ); - mxStatusIndicator = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_STATUSINDICATOR(), mxStatusIndicator ); - mxInteractionHandler = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_INTERACTIONHANDLER(), mxInteractionHandler ); - - if( mxInStream.is() ) - maDescriptor.addInputStream(); -} - bool FilterBaseImpl::hasDocumentModel() const { return mxGlobalFactory.is() && mxModel.is() && mxModelFactory.is(); } +void FilterBaseImpl::initializeFilter() +{ + try + { + // lock the model controllers + mxModel->lockControllers(); + } + catch( Exception& ) + { + } +} + +void FilterBaseImpl::finalizeFilter() +{ + try + { + // clear the 'ComponentData' property in the descriptor + MediaDescriptor::iterator aIt = maMediaDesc.find( MediaDescriptor::PROP_COMPONENTDATA() ); + if( aIt != maMediaDesc.end() ) + aIt->second.clear(); + // write the descriptor back to the document model (adds the password) + mxModel->attachResource( maFileUrl, maMediaDesc.getAsConstPropertyValueList() ); + // unlock the model controllers + mxModel->unlockControllers(); + } + catch( Exception& ) + { + } +} + // ============================================================================ FilterBase::FilterBase( const Reference< XMultiServiceFactory >& rxGlobalFactory ) : @@ -255,19 +284,19 @@ FilterBase::~FilterBase() bool FilterBase::isImportFilter() const { - return mxImpl->mxInStream.is(); + return mxImpl->meDirection == FILTERDIRECTION_IMPORT; } bool FilterBase::isExportFilter() const { - return mxImpl->mxOutStream.is(); + return mxImpl->meDirection == FILTERDIRECTION_EXPORT; } // ---------------------------------------------------------------------------- Any FilterBase::getArgument( const OUString& rArgName ) const { - FilterBaseImpl::ArgumentMap::const_iterator aIt = mxImpl->maArguments.find( rArgName ); + SequenceAsHashMap::const_iterator aIt = mxImpl->maArguments.find( rArgName ); return (aIt == mxImpl->maArguments.end()) ? Any() : aIt->second; } @@ -276,6 +305,11 @@ const Reference< XMultiServiceFactory >& FilterBase::getGlobalFactory() const return mxImpl->mxGlobalFactory; } +MediaDescriptor& FilterBase::getMediaDescriptor() const +{ + return mxImpl->maMediaDesc; +} + const Reference< XModel >& FilterBase::getModel() const { return mxImpl->mxModel; @@ -440,6 +474,14 @@ sal_Int32 FilterBase::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) return (aIt == mxImpl->maSystemPalette.end()) ? ((nDefaultRgb < 0) ? API_RGB_WHITE : nDefaultRgb) : aIt->second; } +OUString FilterBase::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const +{ + ::std::vector< OUString > aDefaultPasswords; + aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); + return ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + rVerifier, mxImpl->maMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); +} + bool FilterBase::importBinaryData( StreamDataSequence& orDataSeq, const OUString& rStreamName ) { OSL_ENSURE( rStreamName.getLength() > 0, "FilterBase::importBinaryData - empty stream name" ); @@ -508,17 +550,12 @@ Sequence< OUString > SAL_CALL FilterBase::getSupportedServiceNames() throw( Runt void SAL_CALL FilterBase::initialize( const Sequence< Any >& rArgs ) throw( Exception, RuntimeException ) { - if( rArgs.getLength() >= 2 ) + if( rArgs.getLength() >= 2 ) try + { + mxImpl->maArguments << rArgs[ 1 ]; + } + catch( Exception& ) { - Sequence< NamedValue > aArgSeq; - if( (rArgs[ 1 ] >>= aArgSeq) && aArgSeq.hasElements() ) - { - const NamedValue* pArg = aArgSeq.getConstArray(); - const NamedValue* pEnd = pArg + aArgSeq.getLength(); - for( ; pArg < pEnd; ++pArg ) - if( pArg->Name.getLength() > 0 ) - mxImpl->maArguments[ pArg->Name ] = pArg->Value; - } } } @@ -529,6 +566,7 @@ void SAL_CALL FilterBase::setTargetDocument( const Reference< XComponent >& rxDo mxImpl->setDocumentModel( rxDocument ); if( !mxImpl->hasDocumentModel() ) throw IllegalArgumentException(); + mxImpl->meDirection = FILTERDIRECTION_IMPORT; } // com.sun.star.document.XExporter interface ---------------------------------- @@ -538,29 +576,41 @@ void SAL_CALL FilterBase::setSourceDocument( const Reference< XComponent >& rxDo mxImpl->setDocumentModel( rxDocument ); if( !mxImpl->hasDocumentModel() ) throw IllegalArgumentException(); + mxImpl->meDirection = FILTERDIRECTION_EXPORT; } // com.sun.star.document.XFilter interface ------------------------------------ -sal_Bool SAL_CALL FilterBase::filter( const Sequence< PropertyValue >& rDescriptor ) throw( RuntimeException ) +sal_Bool SAL_CALL FilterBase::filter( const Sequence< PropertyValue >& rMediaDescSeq ) throw( RuntimeException ) { sal_Bool bRet = sal_False; - if( mxImpl->hasDocumentModel() ) + if( mxImpl->hasDocumentModel() && (mxImpl->meDirection != FILTERDIRECTION_UNKNOWN) ) { - mxImpl->setMediaDescriptor( rDescriptor ); + setMediaDescriptor( rMediaDescSeq ); DocumentOpenedGuard aOpenedGuard( mxImpl->maFileUrl ); if( aOpenedGuard.isValid() ) { - mxImpl->mxStorage = implCreateStorage( mxImpl->mxInStream, mxImpl->mxOutStream ); - if( mxImpl->mxStorage.get() ) + mxImpl->initializeFilter(); + switch( mxImpl->meDirection ) { - mxImpl->mxModel->lockControllers(); - if( mxImpl->mxInStream.is() ) - bRet = importDocument(); - else if( mxImpl->mxOutStream.is() ) - bRet = exportDocument(); - mxImpl->mxModel->unlockControllers(); + case FILTERDIRECTION_UNKNOWN: + break; + case FILTERDIRECTION_IMPORT: + if( mxImpl->mxInStream.is() ) + { + mxImpl->mxStorage = implCreateStorage( mxImpl->mxInStream ); + bRet = mxImpl->mxStorage.get() && importDocument(); + } + break; + case FILTERDIRECTION_EXPORT: + if( mxImpl->mxOutStream.is() ) + { + mxImpl->mxStorage = implCreateStorage( mxImpl->mxOutStream ); + bRet = mxImpl->mxStorage.get() && exportDocument(); + } + break; } + mxImpl->finalizeFilter(); } } return bRet; @@ -570,6 +620,46 @@ void SAL_CALL FilterBase::cancel() throw( RuntimeException ) { } +// protected ------------------------------------------------------------------ + +Reference< XInputStream > FilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const +{ + return rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_INPUTSTREAM(), Reference< XInputStream >() ); +} + +Reference< XStream > FilterBase::implGetOutputStream( MediaDescriptor& rMediaDesc ) const +{ + return rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_STREAMFOROUTPUT(), Reference< XStream >() ); +} + +// private -------------------------------------------------------------------- + +void FilterBase::setMediaDescriptor( const Sequence< PropertyValue >& rMediaDescSeq ) +{ + mxImpl->maMediaDesc = rMediaDescSeq; + + switch( mxImpl->meDirection ) + { + case FILTERDIRECTION_UNKNOWN: + OSL_ENSURE( false, "FilterBase::setMediaDescriptor - invalid filter direction" ); + break; + case FILTERDIRECTION_IMPORT: + mxImpl->maMediaDesc.addInputStream(); + mxImpl->mxInStream = implGetInputStream( mxImpl->maMediaDesc ); + OSL_ENSURE( mxImpl->mxInStream.is(), "FilterBase::setMediaDescriptor - missing input stream" ); + break; + case FILTERDIRECTION_EXPORT: + mxImpl->mxOutStream = implGetOutputStream( mxImpl->maMediaDesc ); + OSL_ENSURE( mxImpl->mxOutStream.is(), "FilterBase::setMediaDescriptor - missing output stream" ); + break; + } + + mxImpl->maFileUrl = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), OUString() ); + mxImpl->mxStatusIndicator = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_STATUSINDICATOR(), Reference< XStatusIndicator >() ); + mxImpl->mxInteractionHandler = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_INTERACTIONHANDLER(), Reference< XInteractionHandler >() ); +} + + // ============================================================================ } // namespace core diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index b0496de26589..434adb9576dd 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -28,89 +28,52 @@ * ************************************************************************/ -#include -#include -#include -#include - -#include -#include +#include "oox/core/filterdetect.hxx" +#include #include - +#include +#include +#include #include -#include -#include - #include "oox/helper/attributelist.hxx" +#include "oox/helper/binaryinputstream.hxx" +#include "oox/helper/binaryoutputstream.hxx" +#include "oox/helper/olestorage.hxx" #include "oox/helper/zipstorage.hxx" #include "oox/core/fasttokenhandler.hxx" #include "oox/core/namespaces.hxx" -#include "tokens.hxx" - -#include using ::rtl::OUString; -using ::rtl::OString; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::beans::NamedValue; +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::io::XInputStream; +using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::io::XStream; +using ::com::sun::star::xml::sax::InputSource; +using ::com::sun::star::xml::sax::SAXException; +using ::com::sun::star::xml::sax::XFastAttributeList; +using ::com::sun::star::xml::sax::XFastContextHandler; +using ::com::sun::star::xml::sax::XFastParser; +using ::com::sun::star::xml::sax::XLocator; using ::comphelper::MediaDescriptor; -using namespace ::com::sun::star::document; -using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::beans; -using namespace ::com::sun::star::io; -using namespace ::com::sun::star::embed; -using namespace ::com::sun::star::xml::sax; +using ::comphelper::SequenceAsHashMap; namespace oox { namespace core { // ============================================================================ -/** Document handler specifically designed for detecting OOXML file formats. - - It takes a reference to the filter string object via its constructor, and - puts the name of the detected filter to it if it successfully finds one. - */ -class FilterDetectDocHandler : public ::cppu::WeakImplHelper1< XFastDocumentHandler > -{ -public: - explicit FilterDetectDocHandler( OUString& rFilter ); - virtual ~FilterDetectDocHandler(); - - // XFastDocumentHandler - virtual void SAL_CALL startDocument() throw (SAXException, RuntimeException); - virtual void SAL_CALL endDocument() throw (SAXException, RuntimeException); - virtual void SAL_CALL setDocumentLocator( const Reference< XLocator >& xLocator ) throw (SAXException, RuntimeException); - - // XFastContextHandler - virtual void SAL_CALL startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); - virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); - virtual void SAL_CALL endFastElement( sal_Int32 Element ) throw (SAXException, RuntimeException); - virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) throw (SAXException, RuntimeException); - virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); - virtual Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); - virtual void SAL_CALL characters( const OUString& aChars ) throw (SAXException, RuntimeException); - virtual void SAL_CALL ignorableWhitespace( const OUString& aWhitespaces ) throw (SAXException, RuntimeException); - virtual void SAL_CALL processingInstruction( const OUString& aTarget, const OUString& aData ) throw (SAXException, RuntimeException); - -private: - void parseRelationship( const AttributeList& rAttribs ); - - OUString getFilterNameFromContentType( const OUString& rContentType ) const; - void parseContentTypesDefault( const AttributeList& rAttribs ); - void parseContentTypesOverride( const AttributeList& rAttribs ); - -private: - typedef ::std::vector< sal_Int32 > ContextVector; - - OUString& mrFilter; - ContextVector maContextStack; - OUString maTargetPath; -}; - -// ============================================================================ - -FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilter ) : - mrFilter( rFilter ) +FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilterName ) : + mrFilterName( rFilterName ) { maContextStack.reserve( 2 ); } @@ -134,8 +97,6 @@ void SAL_CALL FilterDetectDocHandler::setDocumentLocator( const Reference& rAttribs ) throw (SAXException,RuntimeException) @@ -213,8 +174,6 @@ void SAL_CALL FilterDetectDocHandler::processingInstruction( { } -// ============================================================================ - void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs ) { OUString aType = rAttribs.getString( XML_Type, OUString() ); @@ -224,6 +183,14 @@ void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs ) OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType ) const { + if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" ) || + rContentType.equalsAscii( "application/vnd.ms-word.document.macroEnabled.main+xml" ) ) + return CREATE_OUSTRING( "writer_MS_Word_2007" ); + + if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml" ) || + rContentType.equalsAscii( "application/vnd.ms-word.template.macroEnabledTemplate.main+xml" ) ) + return CREATE_OUSTRING( "writer_MS_Word_2007_Template" ); + if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" ) || rContentType.equalsAscii( "application/vnd.ms-excel.sheet.macroEnabled.main+xml" ) ) return CREATE_OUSTRING( "MS Excel 2007 XML" ); @@ -249,44 +216,24 @@ OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& r void FilterDetectDocHandler::parseContentTypesDefault( const AttributeList& rAttribs ) { // only if no overridden part name found - if( mrFilter.getLength() == 0 ) + if( mrFilterName.getLength() == 0 ) { // check if target path ends with extension OUString aExtension = rAttribs.getString( XML_Extension, OUString() ); sal_Int32 nExtPos = maTargetPath.getLength() - aExtension.getLength(); if( (nExtPos > 0) && (maTargetPath[ nExtPos - 1 ] == '.') && maTargetPath.match( aExtension, nExtPos ) ) - mrFilter = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) ); + mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) ); } } void FilterDetectDocHandler::parseContentTypesOverride( const AttributeList& rAttribs ) { if( rAttribs.getString( XML_PartName, OUString() ).equals( maTargetPath ) ) - mrFilter = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) ); + mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) ); } // ============================================================================ -class FilterDetect : public ::cppu::WeakImplHelper2< XExtendedFilterDetection, XServiceInfo > -{ -public: - explicit FilterDetect( const Reference< XMultiServiceFactory >& xFactory ); - virtual ~FilterDetect(); - - // XServiceInfo - virtual OUString SAL_CALL getImplementationName() throw( RuntimeException ); - virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) throw( RuntimeException ); - virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( RuntimeException ); - - // XExtendedFilterDetect - virtual OUString SAL_CALL detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException ); - -private: - Reference< XMultiServiceFactory > mxFactory; -}; - -// ---------------------------------------------------------------------------- - /* Helper for XServiceInfo */ Sequence< OUString > FilterDetect_getSupportedServiceNames() { @@ -307,8 +254,10 @@ Reference< XInterface > SAL_CALL FilterDetect_createInstance( const Reference< X return Reference< XInterface >( *new FilterDetect( xServiceManager ) ); } -FilterDetect::FilterDetect( const Reference< XMultiServiceFactory >& xFactory ) : - mxFactory( xFactory ) +// ---------------------------------------------------------------------------- + +FilterDetect::FilterDetect( const Reference< XMultiServiceFactory >& rxFactory ) : + mxFactory( rxFactory ) { OSL_ENSURE( mxFactory.is(), "FilterDetect::FilterDetect - no service factory" ); } @@ -317,45 +266,319 @@ FilterDetect::~FilterDetect() { } -// com.sun.star.document.XExtendedFilterDetect interface ---------------------- +/* =========================================================================== */ +/* Kudos to Caolan McNamara who provided the core decryption implementations. */ +/* =========================================================================== */ -OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException ) +namespace { + +const sal_uInt32 ENCRYPTINFO_CRYPTOAPI = 0x00000004; +const sal_uInt32 ENCRYPTINFO_DOCPROPS = 0x00000008; +const sal_uInt32 ENCRYPTINFO_EXTERNAL = 0x00000010; +const sal_uInt32 ENCRYPTINFO_AES = 0x00000020; + +const sal_uInt32 ENCRYPT_ALGO_AES128 = 0x0000660E; +const sal_uInt32 ENCRYPT_ALGO_AES192 = 0x0000660F; +const sal_uInt32 ENCRYPT_ALGO_AES256 = 0x00006610; +const sal_uInt32 ENCRYPT_ALGO_RC4 = 0x00006801; + +const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004; + +// ---------------------------------------------------------------------------- + +bool lclIsZipPackage( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm ) { - OUString aFilter; + ZipStorage aZipStorage( rxFactory, rxInStrm ); + return aZipStorage.isStorage(); +} - if( mxFactory.is() ) try +// ---------------------------------------------------------------------------- + +struct PackageEncryptionInfo +{ + sal_uInt8 mpnSalt[ 16 ]; + sal_uInt8 mpnEncrVerifier[ 16 ]; + sal_uInt8 mpnEncrVerifierHash[ 32 ]; + sal_uInt32 mnFlags; + sal_uInt32 mnAlgorithmId; + sal_uInt32 mnAlgorithmIdHash; + sal_uInt32 mnKeySize; + sal_uInt32 mnSaltSize; + sal_uInt32 mnVerifierHashSize; +}; + +bool lclReadEncryptionInfo( PackageEncryptionInfo& rEncrInfo, BinaryInputStream& rStrm ) +{ + rStrm.skip( 4 ); + rStrm >> rEncrInfo.mnFlags; + if( getFlag( rEncrInfo.mnFlags, ENCRYPTINFO_EXTERNAL ) ) + return false; + + sal_uInt32 nHeaderSize, nRepeatedFlags; + rStrm >> nHeaderSize >> nRepeatedFlags; + if( (nHeaderSize < 20) || (nRepeatedFlags != rEncrInfo.mnFlags) ) + return false; + + rStrm.skip( 4 ); + rStrm >> rEncrInfo.mnAlgorithmId >> rEncrInfo.mnAlgorithmIdHash >> rEncrInfo.mnKeySize; + rStrm.skip( nHeaderSize - 20 ); + rStrm >> rEncrInfo.mnSaltSize; + if( rEncrInfo.mnSaltSize != 16 ) + return false; + + rStrm.readMemory( rEncrInfo.mpnSalt, 16 ); + rStrm.readMemory( rEncrInfo.mpnEncrVerifier, 16 ); + rStrm >> rEncrInfo.mnVerifierHashSize; + rStrm.readMemory( rEncrInfo.mpnEncrVerifierHash, 32 ); + return !rStrm.isEof(); +} + +// ---------------------------------------------------------------------------- + +void lclDeriveKey( const sal_uInt8* pnHash, sal_uInt32 nHashLen, sal_uInt8* pnKeyDerived, sal_uInt32 nRequiredKeyLen ) +{ + sal_uInt8 pnBuffer[ 64 ]; + memset( pnBuffer, 0x36, sizeof( pnBuffer ) ); + for( sal_uInt32 i = 0; i < nHashLen; ++i ) + pnBuffer[ i ] ^= pnHash[ i ]; + + rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); + rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) ); + sal_uInt8 pnX1[ RTL_DIGEST_LENGTH_SHA1 ]; + aError = rtl_digest_get( aDigest, pnX1, RTL_DIGEST_LENGTH_SHA1 ); + rtl_digest_destroy( aDigest ); + + memset( pnBuffer, 0x5C, sizeof( pnBuffer ) ); + for( sal_uInt32 i = 0; i < nHashLen; ++i ) + pnBuffer[ i ] ^= pnHash[ i ]; + + aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); + aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) ); + sal_uInt8 pnX2[ RTL_DIGEST_LENGTH_SHA1 ]; + aError = rtl_digest_get( aDigest, pnX2, RTL_DIGEST_LENGTH_SHA1 ); + rtl_digest_destroy( aDigest ); + + if( nRequiredKeyLen > RTL_DIGEST_LENGTH_SHA1 ) { - Reference< XFastParser > xParser( mxFactory->createInstance( - CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW ); - - xParser->setFastDocumentHandler( new FilterDetectDocHandler( aFilter ) ); - xParser->setTokenHandler( new FastTokenHandler ); - - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ), NMSP_PACKAGE_RELATIONSHIPS ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ), NMSP_RELATIONSHIPS ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/content-types" ), NMSP_CONTENT_TYPES ); - - MediaDescriptor aDescriptor( lDescriptor ); - aDescriptor.addInputStream(); - Reference< XInputStream > xInputStream( aDescriptor[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY_THROW ); - StorageRef xStorage( new ZipStorage( mxFactory, xInputStream ) ); - - // Parse _rels/.rels to get the target path. - InputSource aParserInput; - aParserInput.sSystemId = CREATE_OUSTRING( "_rels/.rels" ); - aParserInput.aInputStream = xStorage->openInputStream( aParserInput.sSystemId ); - xParser->parseStream( aParserInput ); - - // Parse [Content_Types].xml to determine the content type of the part at the target path. - aParserInput.sSystemId = CREATE_OUSTRING( "[Content_Types].xml" ); - aParserInput.aInputStream = xStorage->openInputStream( aParserInput.sSystemId ); - xParser->parseStream( aParserInput ); + memcpy( pnKeyDerived + RTL_DIGEST_LENGTH_SHA1, pnX2, nRequiredKeyLen - RTL_DIGEST_LENGTH_SHA1 ); + nRequiredKeyLen = RTL_DIGEST_LENGTH_SHA1; } - catch ( const Exception& ) + memcpy( pnKeyDerived, pnX1, nRequiredKeyLen ); +} + +// ---------------------------------------------------------------------------- + +bool lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen ) +{ + size_t nBufferSize = rEncrInfo.mnSaltSize + 2 * rPassword.getLength(); + sal_uInt8* pnBuffer = new sal_uInt8[ nBufferSize ]; + memcpy( pnBuffer, rEncrInfo.mpnSalt, rEncrInfo.mnSaltSize ); + + sal_uInt8* pnPasswordLoc = pnBuffer + rEncrInfo.mnSaltSize; + const sal_Unicode* pStr = rPassword.getStr(); + for( sal_Int32 i = 0, nLen = rPassword.getLength(); i < nLen; ++i, ++pStr, pnPasswordLoc += 2 ) + ByteOrderConverter::writeLittleEndian( pnPasswordLoc, static_cast< sal_uInt16 >( *pStr ) ); + + rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); + rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, nBufferSize ); + delete[] pnBuffer; + + size_t nHashSize = RTL_DIGEST_LENGTH_SHA1 + 4; + sal_uInt8* pnHash = new sal_uInt8[ nHashSize ]; + aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 ); + rtl_digest_destroy( aDigest ); + + for( sal_uInt32 i = 0; i < 50000; ++i ) { + ByteOrderConverter::writeLittleEndian( pnHash, i ); + aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); + aError = rtl_digest_update( aDigest, pnHash, nHashSize ); + aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 ); + rtl_digest_destroy( aDigest ); } - return aFilter; + memmove( pnHash, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 ); + memset( pnHash + RTL_DIGEST_LENGTH_SHA1, 0, 4 ); + aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); + aError = rtl_digest_update( aDigest, pnHash, nHashSize ); + aError = rtl_digest_get( aDigest, pnHash, RTL_DIGEST_LENGTH_SHA1 ); + rtl_digest_destroy( aDigest ); + + lclDeriveKey( pnHash, RTL_DIGEST_LENGTH_SHA1, pnKey, nRequiredKeyLen ); + delete[] pnHash; + + // check password + EVP_CIPHER_CTX aes_ctx; + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + int nOutLen = 0; + sal_uInt8 pnVerifier[ 16 ] = { 0 }; + /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifier, &nOutLen, rEncrInfo.mpnEncrVerifier, sizeof( rEncrInfo.mpnEncrVerifier ) ); + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + sal_uInt8 pnVerifierHash[ 32 ] = { 0 }; + /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifierHash, &nOutLen, rEncrInfo.mpnEncrVerifierHash, sizeof( rEncrInfo.mpnEncrVerifierHash ) ); + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + + aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); + aError = rtl_digest_update( aDigest, pnVerifier, sizeof( pnVerifier ) ); + sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ]; + aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 ); + rtl_digest_destroy( aDigest ); + + return memcmp( pnSha1Hash, pnVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0; +} + +// the password verifier ------------------------------------------------------ + +class PasswordVerifier : public ::comphelper::IDocPasswordVerifier +{ +public: + explicit PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ); + + virtual ::comphelper::DocPasswordVerifierResult + verifyPassword( const OUString& rPassword ); + + inline const sal_uInt8* getKey() const { return &maKey.front(); } + +private: + const PackageEncryptionInfo& mrEncryptInfo; + ::std::vector< sal_uInt8 > maKey; +}; + +PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) : + mrEncryptInfo( rEncryptInfo ), + maKey( static_cast< size_t >( rEncryptInfo.mnKeySize / 8 ), 0 ) +{ +} + +::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword ) +{ + // verifies the password and writes the related decryption key into maKey + return lclGenerateEncryptionKey( mrEncryptInfo, rPassword, &maKey.front(), maKey.size() ) ? + ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; +} + +} // namespace + +// ---------------------------------------------------------------------------- + +Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescriptor& rMediaDesc ) const +{ + if( mxFactory.is() ) + { + // try the plain input stream + Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY ); + if( !xInStrm.is() || lclIsZipPackage( mxFactory, xInStrm ) ) + return xInStrm; + + // check if a temporary file is passed in the 'ComponentData' property + Sequence< NamedValue > aCompData = rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_COMPONENTDATA(), Sequence< NamedValue >() ); + SequenceAsHashMap aCompDataMap( aCompData ); + Reference< XStream > xDecrypted = aCompDataMap.getUnpackedValueOrDefault( CREATE_OUSTRING( "DecryptedPackage" ), Reference< XStream >() ); + if( xDecrypted.is() ) + { + Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); + if( lclIsZipPackage( mxFactory, xDecrInStrm ) ) + return xDecrInStrm; + } + + // try to decrypt an encrypted OLE package + OleStorage aOleStorage( mxFactory, xInStrm, false ); + if( aOleStorage.isStorage() ) try + { + // open the required input streams in the encrypted package + Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW ); + Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW ); + + // read the encryption info stream + PackageEncryptionInfo aEncryptInfo; + BinaryXInputStream aInfoStrm( xEncryptionInfo, true ); + bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm ); + + // check flags and agorithm IDs, requiered are AES128 and SHA-1 + bool bImplemented = bValidInfo && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) && + // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set + ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) && + // hash algorithm ID 0 defaults to SHA-1 too + ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) && + (aEncryptInfo.mnVerifierHashSize == 20); + + if( bImplemented ) + { + /* "VelvetSweatshop" is the built-in default encryption + password used by MS Excel for the "workbook protection" + feature with password. Try this first before prompting the + user for a password. */ + ::std::vector< OUString > aDefaultPasswords; + aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); + + /* Use the comphelper password helper to request a password. + This helper returns either with the correct password + (according to the verifier), or with an empty string if + user has cancelled the password input dialog. */ + PasswordVerifier aVerifier( aEncryptInfo ); + OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); + + if( aPassword.getLength() == 0 ) + { + rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; + } + else + { + // create temporary file for unencrypted package + Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW ); + BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); + BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); + + EVP_CIPHER_CTX aes_ctx; + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + + sal_uInt8 pnInBuffer[ 1024 ]; + sal_uInt8 pnOutBuffer[ 1024 ]; + sal_Int32 nInLen; + int nOutLen; + aEncryptedPackage.skip( 8 ); // decrypted size + while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) + { + EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); + aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); + } + EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); + aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); + + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + xDecryptedPackage->flush(); + aDecryptedPackage.seekToStart(); + + // store temp file in media descriptor to keep it alive + Sequence< NamedValue > aPropSeq( 1 ); + aPropSeq[ 0 ].Name = CREATE_OUSTRING( "DecryptedPackage" ); + aPropSeq[ 0 ].Value <<= xTempFile; + rMediaDesc[ MediaDescriptor::PROP_COMPONENTDATA() ] <<= aPropSeq; + + Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); + if( lclIsZipPackage( mxFactory, xDecrInStrm ) ) + return xDecrInStrm; + } + } + } + catch( Exception& ) + { + } + } + + return Reference< XInputStream >(); } // com.sun.star.lang.XServiceInfo interface ----------------------------------- @@ -378,6 +601,62 @@ Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames() throw( Ru return FilterDetect_getSupportedServiceNames(); } +// com.sun.star.document.XExtendedFilterDetection interface ------------------- + +OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq ) throw( RuntimeException ) +{ + OUString aFilterName; + MediaDescriptor aMediaDesc( rMediaDescSeq ); + + /* Check that the user has not choosen to abort detection, e.g. by hitting + 'Cancel' in the password input dialog. This may happen because this + filter detection is used by different filters. */ + bool bAborted = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_ABORTED(), false ); + if( !bAborted && mxFactory.is() ) try + { + aMediaDesc.addInputStream(); + + /* Get the unencrypted input stream. This may include creation of a + temporary file that contains the decrypted package. This temporary + file will be stored in the 'ComponentData' property of the media + descriptor. */ + Reference< XInputStream > xInStrm( extractUnencryptedPackage( aMediaDesc ), UNO_SET_THROW ); + + // try to detect the file type, must be a ZIP package + ZipStorage aZipStorage( mxFactory, xInStrm ); + if( aZipStorage.isStorage() ) + { + Reference< XFastParser > xParser( mxFactory->createInstance( + CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW ); + + xParser->setFastDocumentHandler( new FilterDetectDocHandler( aFilterName ) ); + xParser->setTokenHandler( new FastTokenHandler ); + + xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ), NMSP_PACKAGE_RELATIONSHIPS ); + xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ), NMSP_RELATIONSHIPS ); + xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/content-types" ), NMSP_CONTENT_TYPES ); + + // Parse _rels/.rels to get the target path. + InputSource aParserInput; + aParserInput.sSystemId = CREATE_OUSTRING( "_rels/.rels" ); + aParserInput.aInputStream = aZipStorage.openInputStream( aParserInput.sSystemId ); + xParser->parseStream( aParserInput ); + + // Parse [Content_Types].xml to determine the content type of the part at the target path. + aParserInput.sSystemId = CREATE_OUSTRING( "[Content_Types].xml" ); + aParserInput.aInputStream = aZipStorage.openInputStream( aParserInput.sSystemId ); + xParser->parseStream( aParserInput ); + } + } + catch( Exception& ) + { + } + + // write back changed media descriptor members + aMediaDesc >> rMediaDescSeq; + return aFilterName; +} + // ============================================================================ } // namespace core diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk index 3443bd35c7f8..51804e1d04c8 100644 --- a/oox/source/core/makefile.mk +++ b/oox/source/core/makefile.mk @@ -42,6 +42,10 @@ ENABLE_EXCEPTIONS=TRUE .INCLUDE : settings.mk .INCLUDE: $(PRJ)$/util$/makefile.pmk +.IF "$(SYSTEM_OPENSSL)" == "YES" +CFLAGS+= $(OPENSSL_CFLAGS) +.ENDIF + # --- Files -------------------------------------------------------- SLOFILES = \ diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index 6fb94434cc59..27b3eef0ce60 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -28,16 +28,7 @@ * ************************************************************************/ -#include "properties.hxx" #include "oox/core/xmlfilterbase.hxx" -#include "oox/core/fasttokenhandler.hxx" -#include "oox/core/fragmenthandler.hxx" -#include "oox/core/namespaces.hxx" -#include "oox/core/recordparser.hxx" -#include "oox/core/relationshandler.hxx" -#include "oox/helper/containerhelper.hxx" -#include "oox/helper/propertyset.hxx" -#include "oox/helper/zipstorage.hxx" #include @@ -47,9 +38,19 @@ #include #include #include +#include #include - +#include "properties.hxx" #include "tokens.hxx" +#include "oox/helper/containerhelper.hxx" +#include "oox/helper/propertyset.hxx" +#include "oox/helper/zipstorage.hxx" +#include "oox/core/fasttokenhandler.hxx" +#include "oox/core/filterdetect.hxx" +#include "oox/core/fragmenthandler.hxx" +#include "oox/core/namespaces.hxx" +#include "oox/core/recordparser.hxx" +#include "oox/core/relationshandler.hxx" using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -76,6 +77,7 @@ using ::com::sun::star::xml::sax::InputSource; using ::com::sun::star::xml::sax::SAXException; using ::com::sun::star::document::XDocumentProperties; using ::com::sun::star::util::DateTime; +using ::comphelper::MediaDescriptor; using ::sax_fastparser::FastSerializerHelper; using ::sax_fastparser::FSHelperPtr; @@ -479,16 +481,27 @@ XmlFilterBase& XmlFilterBase::exportDocumentProperties( Reference< XDocumentProp return *this; } -StorageRef XmlFilterBase::implCreateStorage( - Reference< XInputStream >& rxInStream, Reference< XStream >& rxOutStream ) const -{ - StorageRef xStorage; - if( rxInStream.is() ) - xStorage.reset( new ZipStorage( getGlobalFactory(), rxInStream ) ); - else if( rxOutStream.is() ) - xStorage.reset( new ZipStorage( getGlobalFactory(), rxOutStream ) ); +// protected ------------------------------------------------------------------ - return xStorage; +Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const +{ + /* Get the input stream directly from the media descriptor, or decrypt the + package again. The latter is needed e.g. when the document is reloaded. + All this is implemented in the detector service. */ + FilterDetect aDetector( getGlobalFactory() ); + return aDetector.extractUnencryptedPackage( rMediaDesc ); +} + +// private -------------------------------------------------------------------- + +StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const +{ + return StorageRef( new ZipStorage( getGlobalFactory(), rxInStream ) ); +} + +StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const +{ + return StorageRef( new ZipStorage( getGlobalFactory(), rxOutStream ) ); } // ============================================================================ diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 95b7da811a74..f4a53a4a0da0 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -50,6 +50,7 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::util::DateTime; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::io::XInputStream; +using ::comphelper::MediaDescriptor; using ::oox::core::FilterBase; using namespace ::oox::xls; @@ -326,14 +327,6 @@ bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos, ornRecPos = mxBiffStrm->tellBase() - 4; ornRecId = mxBiffStrm->getRecId(); - // record specific settings - switch( mxBiffStrm->getRecId() ) - { - case BIFF_ID_CHEND: - out().decIndent(); - break; - } - // special CONTINUE handling mxBiffStrm->resetRecord( mbMergeContRec ); if( mbMergeContRec ) switch( mxBiffStrm->getRecId() ) @@ -350,6 +343,21 @@ bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos, break; } + // record specific settings + switch( mxBiffStrm->getRecId() ) + { + case BIFF2_ID_BOF: + case BIFF3_ID_BOF: + case BIFF4_ID_BOF: + case BIFF5_ID_BOF: + case BIFF_ID_INTERFACEHDR: + mxBiffStrm->enableDecoder( false ); + break; + case BIFF_ID_CHEND: + out().decIndent(); + break; + } + ornRecSize = mxBiffStrm->getLength(); return bValid; } @@ -2183,6 +2191,52 @@ void WorkbookStreamObject::implDumpRecordBody() } break; + case BIFF_ID_FILEPASS: + { + rStrm.enableDecoder( false ); + if( eBiff == BIFF8 ) + { + switch( dumpDec< sal_uInt16 >( "type", "FILEPASS-TYPE" ) ) + { + case 0: + dumpHex< sal_uInt16 >( "key" ); + dumpHex< sal_uInt16 >( "verifier" ); + break; + case 1: + { + sal_uInt16 nMajor = dumpDec< sal_uInt16 >( "major-version", "FILEPASS-MAJOR" ); + dumpDec< sal_uInt16 >( "minor-version" ); + switch( nMajor ) + { + case 1: + dumpArray( "salt", 16 ); + dumpArray( "verifier", 16 ); + dumpArray( "verifier-hash", 16 ); + break; + } + } + break; + } + } + else + { + dumpHex< sal_uInt16 >( "key" ); + dumpHex< sal_uInt16 >( "verifier" ); + } + rStrm.seekToStart(); + BiffDecoderRef xDecoder = BiffCodecHelper::implReadFilePass( rStrm, eBiff ); + if( xDecoder.get() ) + cfg().requestPassword( *xDecoder ); + setBinaryOnlyMode( !xDecoder || !xDecoder->isValid() ); + } + break; + + case BIFF_ID_FILESHARING: + dumpBool< sal_uInt16 >( "recommend-read-only" ); + dumpHex< sal_uInt16 >( "password-hash" ); + dumpString( "password-creator", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS ); + break; + case BIFF2_ID_FONT: case BIFF3_ID_FONT: dumpFontRec(); @@ -2602,9 +2656,14 @@ void WorkbookStreamObject::implDumpRecordBody() break; case BIFF_ID_SHEET: - if( eBiff >= BIFF5 ) dumpHex< sal_uInt32 >( "sheet-stream-pos", "CONV-DEC" ); - if( eBiff >= BIFF5 ) dumpDec< sal_uInt8 >( "sheet-state", "SHEET-STATE" ); - if( eBiff >= BIFF5 ) dumpDec< sal_uInt8 >( "sheet-type", "SHEET-TYPE" ); + if( eBiff >= BIFF5 ) + { + rStrm.enableDecoder( false ); + dumpHex< sal_uInt32 >( "sheet-stream-pos", "CONV-DEC" ); + rStrm.enableDecoder( true ); + dumpDec< sal_uInt8 >( "sheet-state", "SHEET-STATE" ); + dumpDec< sal_uInt8 >( "sheet-type", "SHEET-TYPE" ); + } dumpString( "sheet-name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH ); break; @@ -3682,7 +3741,8 @@ Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Refere if( rxFactory.is() && rxInStrm.is() ) { StorageRef xStrg( new OleStorage( rxFactory, rxInStrm, true ) ); - ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName ) ); + MediaDescriptor aMediaDesc; + ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index 069e18d355ea..df9518e92726 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -1093,6 +1093,11 @@ constlist=EXTERNSHEET-IDX-BIFF8 -2=special end +# FILEPASS ------------------------------------------------------------------- + +shortlist=FILEPASS-TYPE,0,xor,rc4 +shortlist=FILEPASS-MAJOR,1,rc4,crypto-api-2003,crypto-api-2007 + # FONT ----------------------------------------------------------------------- flagslist=FONT-FLAGS diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx index e3a553ffa523..81f63062b4ad 100644 --- a/oox/source/dump/dumperbase.cxx +++ b/oox/source/dump/dumperbase.cxx @@ -39,6 +39,7 @@ #include #include #include +#include #include "oox/helper/binaryoutputstream.hxx" #include "oox/core/filterbase.hxx" #include "oox/xls/biffhelper.hxx" @@ -51,8 +52,8 @@ using ::rtl::OStringToOUString; using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::rtl::OUStringToOString; -using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::util::DateTime; using ::com::sun::star::lang::XMultiServiceFactory; @@ -60,9 +61,10 @@ using ::com::sun::star::ucb::XSimpleFileAccess; using ::com::sun::star::io::XActiveDataSink; using ::com::sun::star::io::XActiveDataSource; using ::com::sun::star::io::XInputStream; -using ::com::sun::star::io::XTextInputStream; using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::io::XTextInputStream; using ::com::sun::star::io::XTextOutputStream; +using ::comphelper::MediaDescriptor; using ::oox::core::FilterBase; namespace oox { @@ -1465,11 +1467,14 @@ NameListRef NameListWrapper::getNameList( const Config& rCfg ) const // ============================================================================ SharedConfigData::SharedConfigData( const OUString& rFileName, - const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName ) : + const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, + const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) : mxFactory( rxFactory ), mxRootStrg( rxRootStrg ), maSysFileName( rSysFileName ), - mbLoaded( false ) + mrMediaDesc( rMediaDesc ), + mbLoaded( false ), + mbPwCancelled( false ) { OUString aFileUrl = InputOutputHelper::convertFileNameToUrl( rFileName ); if( aFileUrl.getLength() > 0 ) @@ -1515,6 +1520,20 @@ NameListRef SharedConfigData::getNameList( const OUString& rListName ) const return xList; } +OUString SharedConfigData::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) +{ + OUString aPassword; + if( !mbPwCancelled ) + { + ::std::vector< OUString > aDefaultPasswords; + aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); + aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + rVerifier, mrMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); + mbPwCancelled = aPassword.getLength() == 0; + } + return aPassword; +} + bool SharedConfigData::implIsValid() const { return mbLoaded && mxFactory.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0); @@ -1614,9 +1633,9 @@ Config::Config( const sal_Char* pcEnvVar, const FilterBase& rFilter ) construct( pcEnvVar, rFilter ); } -Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName ) +Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) { - construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName ); + construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName, rMediaDesc ); } Config::~Config() @@ -1631,14 +1650,14 @@ void Config::construct( const Config& rParent ) void Config::construct( const sal_Char* pcEnvVar, const FilterBase& rFilter ) { if( rFilter.getFileUrl().getLength() > 0 ) - construct( pcEnvVar, rFilter.getGlobalFactory(), rFilter.getStorage(), rFilter.getFileUrl() ); + construct( pcEnvVar, rFilter.getGlobalFactory(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() ); } -void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName ) +void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) { if( pcEnvVar && rxRootStrg.get() && (rSysFileName.getLength() > 0) ) if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) ) - mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName ) ); + mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName, rMediaDesc ) ); } void Config::setStringOption( const String& rKey, const String& rData ) @@ -1683,6 +1702,16 @@ NameListRef Config::getNameList( const String& rListName ) const return implGetNameList( rListName ); } +OUString Config::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) +{ + return mxCfgData->requestPassword( rVerifier ); +} + +bool Config::isPasswordCancelled() const +{ + return mxCfgData->isPasswordCancelled(); +} + bool Config::implIsValid() const { return isValid( mxCfgData ); @@ -3050,7 +3079,7 @@ void RecordObjectBase::implDump() sal_Int64 nRecPos = in().tell(); // record body - if( cfg().hasName( xRecNames, mnRecId ) ) + if( !mbBinaryOnly && cfg().hasName( xRecNames, mnRecId ) ) { ItemFormatMap::const_iterator aIt = aSimpleRecs.find( mnRecId ); if( aIt != aSimpleRecs.end() ) @@ -3081,6 +3110,7 @@ void RecordObjectBase::constructRecObjBase( const BinaryInputStreamRef& rxBaseSt maRecNames = rRecNames; maSimpleRecs = rSimpleRecs; mnRecPos = mnRecId = mnRecSize = 0; + mbBinaryOnly = false; if( InputObjectBase::implIsValid() ) mbShowRecPos = cfg().getBoolOption( "show-record-position", true ); } @@ -3166,6 +3196,11 @@ bool DumperBase::isImportEnabled() const return !isValid() || cfg().isImportEnabled(); } +bool DumperBase::isImportCancelled() const +{ + return isValid() && cfg().isPasswordCancelled(); +} + void DumperBase::construct( const ConfigRef& rxConfig ) { if( isValid( rxConfig ) && rxConfig->isDumperEnabled() ) diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx index d1694000f03b..0e04cb821d4a 100644 --- a/oox/source/dump/pptxdumper.cxx +++ b/oox/source/dump/pptxdumper.cxx @@ -41,6 +41,7 @@ using ::rtl::OUString; using ::com::sun::star::uno::Reference; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::io::XInputStream; +using ::comphelper::MediaDescriptor; using ::oox::core::FilterBase; namespace oox { @@ -127,7 +128,8 @@ Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Refere if( rxFactory.is() && rxInStrm.is() ) { StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) ); - ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName ) ); + MediaDescriptor aMediaDesc; + ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx index 819aff6bed92..3db91fd7383d 100644 --- a/oox/source/dump/xlsbdumper.cxx +++ b/oox/source/dump/xlsbdumper.cxx @@ -48,6 +48,7 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::util::DateTime; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::io::XInputStream; +using ::comphelper::MediaDescriptor; using ::oox::core::FilterBase; using namespace ::oox::xls; @@ -1492,6 +1493,12 @@ void RecordStreamObject::implDumpRecordBody() dumpString( "#sheet-name" ); break; + case OOBIN_ID_FILESHARING: + dumpBool< sal_uInt16 >( "recommend-read-only" ); + dumpHex< sal_uInt16 >( "password-hash" ); + dumpString( "password-creator" ); + break; + case OOBIN_ID_FILL: dumpDec< sal_Int32 >( "fill-pattern", "FILLPATTERNS" ); dumpColor( "fg-color" ); @@ -2267,7 +2274,8 @@ Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Refere if( rxFactory.is() && rxInStrm.is() ) { StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) ); - ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName ) ); + MediaDescriptor aMediaDesc; + ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index e583248adcfa..d586196acee4 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -319,7 +319,7 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS if( !maShapeModel.mxClientData.get() || !mrDrawing.convertShapeClientAnchor( aShapeRect, maShapeModel.mxClientData->maAnchor ) ) aShapeRect = getRectangle( pParentAnchor ); // convert the shape, if the calculated rectangle is not empty - if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) && rxShapes.is() ) + if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) xShape = implConvertAndInsert( rxShapes, aShapeRect ); return xShape; } diff --git a/oox/source/xls/biffcodec.cxx b/oox/source/xls/biffcodec.cxx index b76f51ad0e7e..a589b1b3218f 100644 --- a/oox/source/xls/biffcodec.cxx +++ b/oox/source/xls/biffcodec.cxx @@ -31,26 +31,21 @@ #include "oox/xls/biffcodec.hxx" #include #include +#include "oox/core/filterbase.hxx" #include "oox/xls/biffinputstream.hxx" using ::rtl::OString; using ::rtl::OUString; using ::rtl::OStringToOUString; +using ::oox::core::FilterBase; namespace oox { namespace xls { // ============================================================================ -BiffDecoderBase::BiffDecoderBase( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ), - mnError( CODEC_ERROR_UNSUPP_CRYPT ) -{ -} - -BiffDecoderBase::BiffDecoderBase( const BiffDecoderBase& rDecoder ) : - WorkbookHelper( rDecoder ), - mnError( rDecoder.mnError ) +BiffDecoderBase::BiffDecoderBase() : + mbValid( false ) { } @@ -58,63 +53,42 @@ BiffDecoderBase::~BiffDecoderBase() { } +::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword ) +{ + mbValid = implVerify( rPassword ); + return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; +} + void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) { if( pnDestData && pnSrcData && (nBytes > 0) ) { - if( isValid() ) + if( mbValid ) implDecode( pnDestData, pnSrcData, nStreamPos, nBytes ); else memcpy( pnDestData, pnSrcData, nBytes ); } } -void BiffDecoderBase::setHasValidPassword( bool bValid ) -{ - mnError = bValid ? CODEC_OK : CODEC_ERROR_WRONG_PASS; -} - // ============================================================================ -BiffDecoder_XOR::BiffDecoder_XOR( const WorkbookHelper& rHelper, sal_uInt16 nKey, sal_uInt16 nHash ) : - BiffDecoderBase( rHelper ), +BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) : maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ), + maPassword( 16 ), mnKey( nKey ), mnHash( nHash ) { - init( BiffCodecHelper::getBiff5WbProtPassword() ); - if( !isValid() ) - init( OUStringToOString( getCodecHelper().queryPassword(), osl_getThreadTextEncoding() ) ); } BiffDecoder_XOR::BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ) : - BiffDecoderBase( rDecoder ), + BiffDecoderBase(), // must be called to prevent compiler warning maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ), + maPassword( rDecoder.maPassword ), mnKey( rDecoder.mnKey ), mnHash( rDecoder.mnHash ) { - init( rDecoder.maPass ); -} - -void BiffDecoder_XOR::init( const OString& rPass ) -{ - maPass = rPass; - sal_Int32 nLen = maPass.getLength(); - bool bValid = (0 < nLen) && (nLen < 16); - - if( bValid ) - { - // copy byte string to sal_uInt8 array - sal_uInt8 pnPassw[ 16 ]; - memset( pnPassw, 0, sizeof( pnPassw ) ); - memcpy( pnPassw, maPass.getStr(), static_cast< size_t >( nLen ) ); - - // init codec - maCodec.initKey( pnPassw ); - bValid = maCodec.verifyKey( mnKey, mnHash ); - } - - setHasValidPassword( bValid ); + if( isValid() ) + maCodec.initKey( &maPassword.front() ); } BiffDecoder_XOR* BiffDecoder_XOR::implClone() @@ -122,6 +96,26 @@ BiffDecoder_XOR* BiffDecoder_XOR::implClone() return new BiffDecoder_XOR( *this ); } +bool BiffDecoder_XOR::implVerify( const OUString& rPassword ) +{ + /* Convert password to a byte string. TODO: this needs some finetuning + according to the spec... */ + OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() ); + sal_Int32 nLen = aBytePassword.getLength(); + if( (0 < nLen) && (nLen < 16) ) + { + // copy byte string to sal_uInt8 array + maPassword.clear(); + maPassword.resize( 16, 0 ); + memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) ); + + // init codec + maCodec.initKey( &maPassword.front() ); + return maCodec.verifyKey( mnKey, mnHash ); + } + return false; +} + void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) { maCodec.startBlock(); @@ -149,50 +143,23 @@ sal_Int32 lclGetRcfOffset( sal_Int64 nStreamPos ) // ---------------------------------------------------------------------------- -BiffDecoder_RCF::BiffDecoder_RCF( const WorkbookHelper& rHelper, - sal_uInt8 pnDocId[ 16 ], sal_uInt8 pnSaltData[ 16 ], sal_uInt8 pnSaltHash[ 16 ] ) : - BiffDecoderBase( rHelper ), - maDocId( pnDocId, pnDocId + 16 ), - maSaltData( pnSaltData, pnSaltData + 16 ), - maSaltHash( pnSaltHash, pnSaltHash + 16 ) +BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) : + maPassword( 16, 0 ), + maSalt( pnSalt, pnSalt + 16 ), + maVerifier( pnVerifier, pnVerifier + 16 ), + maVerifierHash( pnVerifierHash, pnVerifierHash + 16 ) { - init( BiffCodecHelper::getBiff8WbProtPassword() ); - if( !isValid() ) - init( getCodecHelper().queryPassword() ); } BiffDecoder_RCF::BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ) : - BiffDecoderBase( rDecoder ), - maDocId( rDecoder.maDocId ), - maSaltData( rDecoder.maSaltData ), - maSaltHash( rDecoder.maSaltHash ) + BiffDecoderBase(), // must be called to prevent compiler warning + maPassword( rDecoder.maPassword ), + maSalt( rDecoder.maSalt ), + maVerifier( rDecoder.maVerifier ), + maVerifierHash( rDecoder.maVerifierHash ) { - init( rDecoder.maPass ); -} - -void BiffDecoder_RCF::init( const OUString& rPass ) -{ - maPass = rPass; - sal_Int32 nLen = maPass.getLength(); - bool bValid = (0 < nLen) && (nLen < 16); - - if( bValid ) - { - // copy string to sal_uInt16 array - sal_uInt16 pnPassw[ 16 ]; - memset( pnPassw, 0, sizeof( pnPassw ) ); - const sal_Unicode* pcChar = maPass.getStr(); - const sal_Unicode* pcCharEnd = pcChar + nLen; - sal_uInt16* pnCurrPass = pnPassw; - for( ; pcChar < pcCharEnd; ++pcChar, ++pnCurrPass ) - *pnCurrPass = static_cast< sal_uInt16 >( *pcChar ); - - // init codec - maCodec.initKey( pnPassw, &maDocId.front() ); - bValid = maCodec.verifyKey( &maSaltData.front(), &maSaltHash.front() ); - } - - setHasValidPassword( bValid ); + if( isValid() ) + maCodec.initKey( &maPassword.front(), &maSalt.front() ); } BiffDecoder_RCF* BiffDecoder_RCF::implClone() @@ -200,6 +167,27 @@ BiffDecoder_RCF* BiffDecoder_RCF::implClone() return new BiffDecoder_RCF( *this ); } +bool BiffDecoder_RCF::implVerify( const OUString& rPassword ) +{ + sal_Int32 nLen = rPassword.getLength(); + if( (0 < nLen) && (nLen < 16) ) + { + // copy string to sal_uInt16 array + maPassword.clear(); + maPassword.resize( 16, 0 ); + const sal_Unicode* pcChar = rPassword.getStr(); + const sal_Unicode* pcCharEnd = pcChar + nLen; + ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin(); + for( ; pcChar < pcCharEnd; ++pcChar, ++aIt ) + *aIt = static_cast< sal_uInt16 >( *pcChar ); + + // init codec + maCodec.initKey( &maPassword.front(), &maSalt.front() ); + return maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ); + } + return false; +} + void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) { sal_uInt8* pnCurrDest = pnDestData; @@ -229,57 +217,110 @@ void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcD namespace { -const sal_uInt16 BIFF_FILEPASS_BIFF2 = 0x0000; -const sal_uInt16 BIFF_FILEPASS_BIFF8 = 0x0001; -const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF = 0x0001; -const sal_uInt16 BIFF_FILEPASS_BIFF8_STRONG = 0x0002; +const sal_uInt16 BIFF_FILEPASS_XOR = 0; +const sal_uInt16 BIFF_FILEPASS_RCF = 1; + +const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF = 1; +const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003 = 2; +const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007 = 3; + +// ---------------------------------------------------------------------------- + +BiffDecoderRef lclReadFilePass_XOR( BiffInputStream& rStrm ) +{ + BiffDecoderRef xDecoder; + OSL_ENSURE( rStrm.getRemaining() == 4, "lclReadFilePass_XOR - wrong record size" ); + if( rStrm.getRemaining() == 4 ) + { + sal_uInt16 nBaseKey, nHash; + rStrm >> nBaseKey >> nHash; + xDecoder.reset( new BiffDecoder_XOR( nBaseKey, nHash ) ); + } + return xDecoder; +} + +BiffDecoderRef lclReadFilePass_RCF( BiffInputStream& rStrm ) +{ + BiffDecoderRef xDecoder; + OSL_ENSURE( rStrm.getRemaining() == 48, "lclReadFilePass_RCF - wrong record size" ); + if( rStrm.getRemaining() == 48 ) + { + sal_uInt8 pnSalt[ 16 ]; + sal_uInt8 pnVerifier[ 16 ]; + sal_uInt8 pnVerifierHash[ 16 ]; + rStrm.readMemory( pnSalt, 16 ); + rStrm.readMemory( pnVerifier, 16 ); + rStrm.readMemory( pnVerifierHash, 16 ); + xDecoder.reset( new BiffDecoder_RCF( pnSalt, pnVerifier, pnVerifierHash ) ); + } + return xDecoder; +} + +BiffDecoderRef lclReadFilePass_CryptoApi( BiffInputStream& /*rStrm*/ ) +{ + // not supported + return BiffDecoderRef(); +} + +BiffDecoderRef lclReadFilePassBiff8( BiffInputStream& rStrm ) +{ + BiffDecoderRef xDecoder; + switch( rStrm.readuInt16() ) + { + case BIFF_FILEPASS_XOR: + xDecoder = lclReadFilePass_XOR( rStrm ); + break; + + case BIFF_FILEPASS_RCF: + { + sal_uInt16 nMajor = rStrm.readuInt16(); + rStrm.skip( 2 ); + switch( nMajor ) + { + case BIFF_FILEPASS_BIFF8_RCF: + xDecoder = lclReadFilePass_RCF( rStrm ); + break; + case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003: + case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007: + xDecoder = lclReadFilePass_CryptoApi( rStrm ); + break; + default: + OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown BIFF8 encryption sub mode" ); + } + } + break; + + default: + OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown encryption mode" ); + } + return xDecoder; +} } // namespace // ---------------------------------------------------------------------------- BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ), - mbHasPassword( false ) + WorkbookHelper( rHelper ) { } -const OString& BiffCodecHelper::getBiff5WbProtPassword() +/*static*/ BiffDecoderRef BiffCodecHelper::implReadFilePass( BiffInputStream& rStrm, BiffType eBiff ) { - static const OString saPass( "VelvetSweatshop" ); - return saPass; -} - -const OUString& BiffCodecHelper::getBiff8WbProtPassword() -{ - static const OUString saPass = OStringToOUString( getBiff5WbProtPassword(), RTL_TEXTENCODING_ASCII_US ); - return saPass; -} - -OUString BiffCodecHelper::queryPassword() -{ - if( !mbHasPassword ) - { - //! TODO - maPassword = OUString(); - // set to true, even if dialog has been cancelled (never ask twice) - mbHasPassword = true; - } - return maPassword; + rStrm.enableDecoder( false ); + BiffDecoderRef xDecoder = (eBiff == BIFF8) ? lclReadFilePassBiff8( rStrm ) : lclReadFilePass_XOR( rStrm ); + rStrm.setDecoder( xDecoder ); + return xDecoder; } bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm ) { OSL_ENSURE( !mxDecoder, "BiffCodecHelper::importFilePass - multiple FILEPASS records" ); - rStrm.enableDecoder( false ); - mxDecoder.reset(); - if( getBiff() == BIFF8 ) importFilePass8( rStrm ); else importFilePass2( rStrm ); - - // set decoder at import stream - rStrm.setDecoder( mxDecoder ); - //! TODO remember encryption state for export -// mrStrm.GetRoot().GetExtDocOptions().GetDocSettings().mbEncrypted = true; - + mxDecoder = implReadFilePass( rStrm, getBiff() ); + // request and verify a password (decoder implements IDocPasswordVerifier) + if( mxDecoder.get() ) + getBaseFilter().requestPassword( *mxDecoder ); + // correct password is indicated by isValid() function of decoder return mxDecoder.get() && mxDecoder->isValid(); } @@ -289,72 +330,6 @@ void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm ) rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) ); } -// private -------------------------------------------------------------------- - -void BiffCodecHelper::importFilePass_XOR( BiffInputStream& rStrm ) -{ - OSL_ENSURE( rStrm.getRemaining() == 4, "BiffCodecHelper::importFilePass_XOR - wrong record size" ); - if( rStrm.getRemaining() == 4 ) - { - sal_uInt16 nBaseKey, nHash; - rStrm >> nBaseKey >> nHash; - mxDecoder.reset( new BiffDecoder_XOR( *this, nBaseKey, nHash ) ); - } -} - -void BiffCodecHelper::importFilePass_RCF( BiffInputStream& rStrm ) -{ - OSL_ENSURE( rStrm.getRemaining() == 48, "BiffCodecHelper::importFilePass_RCF - wrong record size" ); - if( rStrm.getRemaining() == 48 ) - { - sal_uInt8 pnDocId[ 16 ]; - sal_uInt8 pnSaltData[ 16 ]; - sal_uInt8 pnSaltHash[ 16 ]; - rStrm.readMemory( pnDocId, 16 ); - rStrm.readMemory( pnSaltData, 16 ); - rStrm.readMemory( pnSaltHash, 16 ); - mxDecoder.reset( new BiffDecoder_RCF( *this, pnDocId, pnSaltData, pnSaltHash ) ); - } -} - -void BiffCodecHelper::importFilePass_Strong( BiffInputStream& /*rStrm*/ ) -{ - // not supported -} - -void BiffCodecHelper::importFilePass2( BiffInputStream& rStrm ) -{ - importFilePass_XOR( rStrm ); -} - -void BiffCodecHelper::importFilePass8( BiffInputStream& rStrm ) -{ - switch( rStrm.readuInt16() ) - { - case BIFF_FILEPASS_BIFF2: - importFilePass_XOR( rStrm ); - break; - - case BIFF_FILEPASS_BIFF8: - rStrm.skip( 2 ); - switch( rStrm.readuInt16() ) - { - case BIFF_FILEPASS_BIFF8_RCF: - importFilePass_RCF( rStrm ); - break; - case BIFF_FILEPASS_BIFF8_STRONG: - importFilePass_Strong( rStrm ); - break; - default: - OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown BIFF8 encryption sub mode" ); - } - break; - - default: - OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown encryption mode" ); - } -} - // ============================================================================ } // namespace xls diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index d5904877b7ee..1779cb4a7691 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -101,8 +101,9 @@ ContextHandlerRef OoxWorkbookFragment::onCreateContext( sal_Int32 nElement, cons case XLS_TOKEN( definedNames ): case XLS_TOKEN( pivotCaches ): return this; - case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break; - case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break; + case XLS_TOKEN( fileSharing ): getWorkbookSettings().importFileSharing( rAttribs ); break; + case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break; + case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break; } break; @@ -151,6 +152,7 @@ ContextHandlerRef OoxWorkbookFragment::onCreateRecordContext( sal_Int32 nRecId, case OOBIN_ID_EXTERNALREFS: case OOBIN_ID_PIVOTCACHES: return this; + case OOBIN_ID_FILESHARING: getWorkbookSettings().importFileSharing( rStrm ); break; case OOBIN_ID_WORKBOOKPR: getWorkbookSettings().importWorkbookPr( rStrm ); break; case OOBIN_ID_CALCPR: getWorkbookSettings().importCalcPr( rStrm ); break; case OOBIN_ID_DEFINEDNAME: getDefinedNames().importDefinedName( rStrm ); break; @@ -402,7 +404,8 @@ bool BiffWorkbookFragment::importFragment() } // final conversions, e.g. calculation settings and view settings - finalizeWorkbookImport(); + if( bRet ) + finalizeWorkbookImport(); return bRet; } @@ -509,33 +512,35 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress case BIFF3: switch( nRecId ) { - case BIFF_ID_CRN: bExtLinkRec = true; break; - case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break; - case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break; - case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; - case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break; - case BIFF2_ID_FORMAT: rStyles.importFormat( mrStrm ); break; - case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; - case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break; - case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break; - case BIFF_ID_XCT: bExtLinkRec = true; break; - case BIFF3_ID_XF: rStyles.importXf( mrStrm ); break; + case BIFF_ID_CRN: bExtLinkRec = true; break; + case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break; + case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break; + case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; + case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break; + case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break; + case BIFF2_ID_FORMAT: rStyles.importFormat( mrStrm ); break; + case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; + case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break; + case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break; + case BIFF_ID_XCT: bExtLinkRec = true; break; + case BIFF3_ID_XF: rStyles.importXf( mrStrm ); break; } break; case BIFF4: switch( nRecId ) { - case BIFF_ID_CRN: bExtLinkRec = true; break; - case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break; - case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break; - case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; - case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break; - case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break; - case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; - case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break; - case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break; - case BIFF_ID_XCT: bExtLinkRec = true; break; - case BIFF4_ID_XF: rStyles.importXf( mrStrm ); break; + case BIFF_ID_CRN: bExtLinkRec = true; break; + case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break; + case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break; + case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; + case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break; + case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break; + case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break; + case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; + case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break; + case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break; + case BIFF_ID_XCT: bExtLinkRec = true; break; + case BIFF4_ID_XF: rStyles.importXf( mrStrm ); break; } break; @@ -546,6 +551,7 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break; case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break; case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; + case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break; case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break; case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break; case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; @@ -567,6 +573,7 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress case BIFF_ID_EXTERNALBOOK: bExtLinkRec = true; break; case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break; case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; + case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break; case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break; case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break; case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; @@ -591,8 +598,11 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress // finalize global buffers rProgressBar.setPosition( 0.5 ); - rSharedStrings.finalizeImport(); - rStyles.finalizeImport(); + if( bRet ) + { + rSharedStrings.finalizeImport(); + rStyles.finalizeImport(); + } /* Import external link data (EXTERNSHEET, EXTERNALNAME, DEFINEDNAME) which need existing internal sheets (SHEET records). The SHEET records diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx index b91315f663fb..e4de0ff2dd0c 100644 --- a/oox/source/xls/workbooksettings.cxx +++ b/oox/source/xls/workbooksettings.cxx @@ -32,10 +32,12 @@ #include #include #include +#include #include "properties.hxx" #include "oox/helper/attributelist.hxx" #include "oox/helper/propertyset.hxx" #include "oox/helper/recordinputstream.hxx" +#include "oox/core/filterbase.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/unitconverter.hxx" @@ -45,6 +47,7 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::util::Date; using ::com::sun::star::util::XNumberFormatsSupplier; using ::com::sun::star::sheet::XCalculatable; +using ::oox::core::CodecHelper; namespace oox { namespace xls { @@ -73,6 +76,14 @@ const sal_Int16 API_SHOWMODE_PLACEHOLDER = 2; /// Show placeholder // ============================================================================ +FileSharingModel::FileSharingModel() : + mnPasswordHash( 0 ), + mbRecommendReadOnly( false ) +{ +} + +// ============================================================================ + WorkbookSettingsModel::WorkbookSettingsModel() : mnShowObjectMode( XML_all ), mnUpdateLinksMode( XML_userSet ), @@ -113,6 +124,13 @@ WorkbookSettings::WorkbookSettings( const WorkbookHelper& rHelper ) : { } +void WorkbookSettings::importFileSharing( const AttributeList& rAttribs ) +{ + maFileSharing.maUserName = rAttribs.getXString( XML_userName, OUString() ); + maFileSharing.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_reservationPassword ); + maFileSharing.mbRecommendReadOnly = rAttribs.getBool( XML_readOnlyRecommended, false ); +} + void WorkbookSettings::importWorkbookPr( const AttributeList& rAttribs ) { maBookSettings.maCodeName = rAttribs.getString( XML_codePage, OUString() ); @@ -138,6 +156,12 @@ void WorkbookSettings::importCalcPr( const AttributeList& rAttribs ) maCalcSettings.mbConcurrent = rAttribs.getBool( XML_concurrentCalc, true ); } +void WorkbookSettings::importFileSharing( RecordInputStream& rStrm ) +{ + maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0; + rStrm >> maFileSharing.mnPasswordHash >> maFileSharing.maUserName; +} + void WorkbookSettings::importWorkbookPr( RecordInputStream& rStrm ) { sal_uInt32 nFlags; @@ -170,6 +194,23 @@ void WorkbookSettings::setSaveExtLinkValues( bool bSaveExtLinks ) maBookSettings.mbSaveExtLinkValues = bSaveExtLinks; } +void WorkbookSettings::importFileSharing( BiffInputStream& rStrm ) +{ + maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0; + rStrm >> maFileSharing.mnPasswordHash; + if( getBiff() == BIFF8 ) + { + sal_uInt16 nStrLen = rStrm.readuInt16(); + // there is no string flags field if string is empty + if( nStrLen > 0 ) + maFileSharing.maUserName = rStrm.readUniStringBody( nStrLen ); + } + else + { + maFileSharing.maUserName = rStrm.readByteStringUC( false, getTextEncoding() ); + } +} + void WorkbookSettings::importBookBool( BiffInputStream& rStrm ) { // value of 0 means save external values, value of 1 means strip external values @@ -254,6 +295,10 @@ void WorkbookSettings::finalizeImport() break; } + // write protection + if( maFileSharing.mbRecommendReadOnly || (maFileSharing.mnPasswordHash != 0) ) + getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true; + // calculation settings Date aNullDate = getNullDate(); diff --git a/oox/source/xls/worksheetsettings.cxx b/oox/source/xls/worksheetsettings.cxx index 48cc9c3041df..d791e4801217 100644 --- a/oox/source/xls/worksheetsettings.cxx +++ b/oox/source/xls/worksheetsettings.cxx @@ -41,6 +41,7 @@ using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::util::XProtectable; +using ::oox::core::CodecHelper; namespace oox { namespace xls { @@ -112,16 +113,6 @@ SheetProtectionModel::SheetProtectionModel() : // ============================================================================ -namespace { - -sal_uInt16 lclGetCheckedHash( sal_Int32 nHash ) -{ - OSL_ENSURE( (0 <= nHash) && (nHash <= SAL_MAX_UINT16), "lclGetCheckedHash - invalid password hash" ); - return getLimitedValue< sal_uInt16, sal_Int32 >( nHash, 0, SAL_MAX_UINT16 ); -} - -} // namespace - WorksheetSettings::WorksheetSettings( const WorksheetHelper& rHelper ) : WorksheetHelper( rHelper ), maPhoneticSett( rHelper ) @@ -153,7 +144,7 @@ void WorksheetSettings::importOutlinePr( const AttributeList& rAttribs ) void WorksheetSettings::importSheetProtection( const AttributeList& rAttribs ) { - maSheetProt.mnPasswordHash = lclGetCheckedHash( rAttribs.getIntegerHex( XML_password, 0 ) ); + maSheetProt.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_password ); maSheetProt.mbSheet = rAttribs.getBool( XML_sheet, false ); maSheetProt.mbObjects = rAttribs.getBool( XML_objects, false ); maSheetProt.mbScenarios = rAttribs.getBool( XML_scenarios, false ); @@ -174,7 +165,7 @@ void WorksheetSettings::importSheetProtection( const AttributeList& rAttribs ) void WorksheetSettings::importChartProtection( const AttributeList& rAttribs ) { - maSheetProt.mnPasswordHash = lclGetCheckedHash( rAttribs.getIntegerHex( XML_password, 0 ) ); + maSheetProt.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_password ); maSheetProt.mbSheet = rAttribs.getBool( XML_content, false ); maSheetProt.mbObjects = rAttribs.getBool( XML_objects, false ); } diff --git a/oox/util/makefile.mk b/oox/util/makefile.mk index f98003b0fe0d..93669d2d40b1 100644 --- a/oox/util/makefile.mk +++ b/oox/util/makefile.mk @@ -74,6 +74,20 @@ SHL1STDLIBS= \ $(BASEGFXLIB) \ $(SAXLIB) +# link openssl, copied this bit from ucb/source/ucp/webdav/makefile.mk +.IF "$(GUI)"=="WNT" +SHL1STDLIBS+= $(OPENSSLLIB) +.ELSE # WNT +.IF "$(OS)"=="SOLARIS" +SHL1STDLIBS+= -lnsl -lsocket -ldl +.ENDIF # SOLARIS +.IF "$(SYSTEM_OPENSSL)"=="YES" +SHL1STDLIBS+= $(OPENSSLLIB) +.ELSE +SHL1STDLIBS+= $(OPENSSLLIBST) +.ENDIF +.ENDIF # WNT + SHL1DEF= $(MISC)$/$(SHL1TARGET).def SHL1LIBS= $(LIB1TARGET) DEF1NAME =$(SHL1TARGET) diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index b67b7dd283ac..af27bac94540 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include #include @@ -44,6 +46,7 @@ #include using namespace ::rtl; using namespace ::com::sun::star; +using ::comphelper::MediaDescriptor; /*-- 09.06.2006 10:15:20--------------------------------------------------- @@ -62,28 +65,29 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes if (!xExprtr.is() || !xFltr.is()) return sal_False; xExprtr->setSourceDocument(m_xSrcDoc); - if (xFltr->filter(aDescriptor)) - return sal_True; - return sal_False; + return xFltr->filter(aDescriptor); } else if (m_xDstDoc.is()) { + MediaDescriptor aMediaDesc( aDescriptor ); + OUString sFilterName = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_FILTERNAME(), OUString() ); - sal_Int32 nLength = aDescriptor.getLength(); - const beans::PropertyValue * pValue = aDescriptor.getConstArray(); - uno::Reference < io::XInputStream > xInputStream; - ::rtl::OUString sFilterName; - for ( sal_Int32 i = 0 ; i < nLength; i++) - { - if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) ) - pValue[i].Value >>= xInputStream; - else if( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "FilterName" ) ) ) - pValue[i].Value >>= sFilterName; - } - if ( !xInputStream.is() ) - { - return sal_False; - } + uno::Reference< io::XInputStream > xInputStream; + try + { + // use the oox.core.FilterDetect implementation to extract the decrypted ZIP package + uno::Reference< lang::XMultiServiceFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_QUERY_THROW ); + ::oox::core::FilterDetect aDetector( xFactory ); + xInputStream = aDetector.extractUnencryptedPackage( aMediaDesc ); + } + catch( uno::Exception& ) + { + } + + if ( !xInputStream.is() ) + { + return sal_False; + } #ifdef DEBUG_ELEMENT writerfilter::TagLogger::Pointer_t debugLogger diff --git a/writerfilter/util/makefile.mk b/writerfilter/util/makefile.mk index 08033ab9c8df..4e99764c688f 100644 --- a/writerfilter/util/makefile.mk +++ b/writerfilter/util/makefile.mk @@ -1,7 +1,7 @@ #************************************************************************ # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# +# # Copyright 2008 by Sun Microsystems, Inc. # # OpenOffice.org - a multi-platform office productivity suite @@ -63,7 +63,8 @@ SHL1STDLIBS=\ $(CPPUHELPERLIB) \ $(COMPHELPERLIB) \ $(CPPULIB) \ - $(SALLIB) + $(SALLIB) \ + $(OOXLIB) SHL1DEPN= From 347a3c4c94acc84f9a11878741cacc31e3aa6a2b Mon Sep 17 00:00:00 2001 From: Oliver Bolte Date: Tue, 8 Sep 2009 14:13:58 +0000 Subject: [PATCH 02/16] CWS-TOOLING: integrate CWS os134 2009-09-02 08:03:24 +0200 os r275688 : newline added 2009-09-01 15:36:05 +0200 os r275664 : newline added 2009-09-01 09:24:34 +0200 os r275643 : #i104499# ruby property support fixed 2009-08-27 08:51:05 +0200 os r275455 : CWS-TOOLING: rebase CWS os134 to trunk@275331 (milestone: DEV300:m56) 2009-08-25 08:54:46 +0200 os r275334 : #i76332# switch to edit mode - regard 'Open in design mode' setting 2009-08-05 14:00:01 +0200 os r274664 : #b6863593#/#i102949# print options ProspectRTL, HiddenText, Placedholder added to SwXPrintSettings 2009-08-05 13:17:21 +0200 os r274655 : #b6858652# find linked sections/bookmarks case sensitively first 2009-07-30 11:14:03 +0200 os r274472 : #i99860# button size on security page enhanced 2009-07-30 10:40:40 +0200 os r274471 : #i97565# moving global document content needs undo, related string has no parameter --- filter/source/pdf/impdialog.src | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src index e8e79f0c162d..d9bcfebc2008 100644 --- a/filter/source/pdf/impdialog.src +++ b/filter/source/pdf/impdialog.src @@ -503,7 +503,7 @@ TabPage RID_PDF_TAB_SECURITY TabStop = TRUE ; Disable = TRUE ; Pos = MAP_APPFONT ( 12, 5 ) ; - Size = MAP_APPFONT ( 100 , 13 ) ; + Size = MAP_APPFONT ( 120 , 13 ) ; Text[ en-US ] = "Set ~open password..."; }; @@ -538,7 +538,7 @@ TabPage RID_PDF_TAB_SECURITY TabStop = TRUE ; Disable = TRUE ; Pos = MAP_APPFONT ( 12, 45 ) ; - Size = MAP_APPFONT ( 100 , 13 ) ; + Size = MAP_APPFONT ( 120 , 13 ) ; Text[ en-US ] = "Set ~permission password..."; }; From 24c5f3e8bfea21cd7c9e86a764fd946041a3866a Mon Sep 17 00:00:00 2001 From: Oliver Bolte Date: Wed, 9 Sep 2009 09:19:53 +0000 Subject: [PATCH 03/16] CWS-TOOLING: integrate CWS impress174 2009-08-27 18:21:38 +0200 af r275502 : #i73289# Fixed detection of the cases when the layout menu is be disabled. 2009-08-24 17:45:50 +0200 sj r275326 : #i103360# only setting filltype if there is also a correct fill element 2009-08-24 16:11:06 +0200 cl r275322 : #i73871# only remove replaced objects from mark list if replaced by SdrEditView::ReplaceObjectAtView(). see issue for reason 2009-08-24 15:03:33 +0200 cl r275319 : fixed merge error 2009-08-20 12:45:29 +0200 sj r275174 : CWS-TOOLING: rebase CWS impress174 to trunk@275001 (milestone: DEV300:m55) 2009-08-19 15:54:47 +0200 sj r275153 : #158486# text of flipped shapes is not flipped in word 2009-08-17 17:30:16 +0200 sj r275063 : #158486# also correcting text bound for additional text rotation 2009-08-05 11:09:32 +0200 sj r274643 : #i102797# adapted customshape coloring (fixed fontwork) 2009-08-04 14:17:36 +0200 sj r274620 : #i99501# pdf export: fixed export of rotated graphics 2009-07-30 16:15:44 +0200 sj r274494 : #158653# binary ppt import: fixed table border lines 2009-07-27 18:28:02 +0200 sj r274376 : added shape text clipping for customshapes 2009-07-20 18:09:14 +0200 sj r274154 : #i101918# fixed gallery preview (now taking the correct mapmode) 2009-07-13 18:00:58 +0200 cl r273948 : #i103238# clear hard set attributes only if new style set is manually applied 2009-07-13 17:58:07 +0200 cl r273947 : #i73289# do not expand a toolpanel when it gets enabled 2009-07-08 12:39:49 +0200 sj r273827 : #i101566# applied patch from cmc to solve font width inconsistencies 2009-07-08 12:11:13 +0200 sj r273826 : #i87727# added PDFDialog service 2009-07-06 17:22:40 +0200 sj r273755 : #i103360# fixed a merge problem, no more looping when loading transparence gradients on background page 2009-07-03 14:42:07 +0200 sj r273701 : #102797# added patch from thb (Adapted customshape coloring) 2009-07-03 14:09:44 +0200 sj r273696 : #102797# removed warning 2009-07-03 14:01:47 +0200 sj r273695 : #102797# added patch from thb (Adapted customshape coloring) 2009-07-03 13:13:39 +0200 sj r273688 : #102797# added patch from thb (Adapted customshape coloring) 2009-07-03 11:25:30 +0200 sj r273684 : #i103278# fixed import of lines 2009-07-01 16:23:47 +0200 cl r273599 : #i96820# correctly call setChanged on model if table is modified 2009-07-01 14:43:09 +0200 cl r273588 : #i8770# Patch: fix missing type provider for pdf export dialog 2009-07-01 14:40:28 +0200 cl r273586 : #i73871# activate picture bar after converting shape to bitmap 2009-07-01 14:39:05 +0200 cl r273584 : #i73871# activate picture bar after converting shape to bitmap 2009-07-01 14:04:53 +0200 cl r273578 : #i73289# PATCH: Disable layout pane on the masterslide --- filter/source/pdf/pdfdialog.cxx | 35 ++----------------- filter/source/pdf/pdfdialog.hxx | 21 +++++------ .../drawingml/fillpropertiesgroupcontext.cxx | 13 ++++--- 3 files changed, 19 insertions(+), 50 deletions(-) diff --git a/filter/source/pdf/pdfdialog.cxx b/filter/source/pdf/pdfdialog.cxx index c1217b4b109c..78ee2f82dbc5 100644 --- a/filter/source/pdf/pdfdialog.cxx +++ b/filter/source/pdf/pdfdialog.cxx @@ -97,8 +97,8 @@ Reference< XInterface > SAL_CALL PDFDialog_createInstance( const Reference< XMul // - PDFDialog - // ------------- -PDFDialog::PDFDialog( const Reference< XMultiServiceFactory > &rxMSF ) : - OGenericUnoDialog( rxMSF ) +PDFDialog::PDFDialog( const Reference< XMultiServiceFactory > &rxMSF ) +: PDFDialog_Base( rxMSF ) { ByteString aResMgrName( "pdffilter" ); @@ -114,37 +114,6 @@ PDFDialog::~PDFDialog() // ----------------------------------------------------------------------------- -Any SAL_CALL PDFDialog::queryInterface( const Type& rType ) - throw (RuntimeException) -{ - Any aReturn = OGenericUnoDialog::queryInterface( rType ); - - if( !aReturn.hasValue() ) - aReturn = ::cppu::queryInterface( rType, - static_cast< XPropertyAccess* >( this ), - static_cast< XExporter* >( this ) ); - - return aReturn; -} - -// ----------------------------------------------------------------------------- - -void SAL_CALL PDFDialog::acquire() - throw () -{ - OWeakObject::acquire(); -} - -// ----------------------------------------------------------------------------- - -void SAL_CALL PDFDialog::release() - throw () -{ - OWeakObject::release(); -} - -// ----------------------------------------------------------------------------- - Sequence< sal_Int8 > SAL_CALL PDFDialog::getImplementationId() throw(RuntimeException) { diff --git a/filter/source/pdf/pdfdialog.hxx b/filter/source/pdf/pdfdialog.hxx index 44841fc2a91f..682e7974c11f 100644 --- a/filter/source/pdf/pdfdialog.hxx +++ b/filter/source/pdf/pdfdialog.hxx @@ -34,6 +34,8 @@ #include "pdffilter.hxx" #include +#include + // ------------- // - PDFDialog - // ------------- @@ -41,10 +43,15 @@ class Window; class ResMgr; -class PDFDialog : public ::svt::OGenericUnoDialog, - public ::comphelper::OPropertyArrayUsageHelper< PDFDialog >, - public XPropertyAccess, - public XExporter +typedef ::svt::OGenericUnoDialog PDFDialog_DialogBase; +typedef ::cppu::ImplInheritanceHelper2 < + PDFDialog_DialogBase, + XPropertyAccess, + XExporter + > PDFDialog_Base; + +class PDFDialog : public PDFDialog_Base, + public ::comphelper::OPropertyArrayUsageHelper< PDFDialog > { private: @@ -54,12 +61,6 @@ private: Reference< XComponent > mxSrcDoc; protected: - - // XInterface - virtual Any SAL_CALL queryInterface( const Type& aType ) throw (RuntimeException); - virtual void SAL_CALL acquire() throw (); - virtual void SAL_CALL release() throw (); - // OGenericUnoDialog virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(RuntimeException); virtual OUString SAL_CALL getImplementationName() throw (RuntimeException); diff --git a/oox/source/drawingml/fillpropertiesgroupcontext.cxx b/oox/source/drawingml/fillpropertiesgroupcontext.cxx index 1e27dcd60bb7..dfe395ec8f34 100644 --- a/oox/source/drawingml/fillpropertiesgroupcontext.cxx +++ b/oox/source/drawingml/fillpropertiesgroupcontext.cxx @@ -271,15 +271,14 @@ Reference< XFastContextHandler > FillPropertiesContext::createFastChildContext( ContextHandler& rParent, sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs, FillProperties& rFillProps ) { - rFillProps.moFillType = getToken( nElement ); switch( nElement ) { - case A_TOKEN( noFill ): return 0; - case A_TOKEN( solidFill ): return new SolidFillContext( rParent, rxAttribs, rFillProps ); - case A_TOKEN( gradFill ): return new GradientFillContext( rParent, rxAttribs, rFillProps.maGradientProps ); - case A_TOKEN( pattFill ): return new PatternFillContext( rParent, rxAttribs, rFillProps.maPatternProps ); - case A_TOKEN( blipFill ): return new BlipFillContext( rParent, rxAttribs, rFillProps.maBlipProps ); - case A_TOKEN( grpFill ): return 0; // TODO + case A_TOKEN( noFill ): { rFillProps.moFillType = getToken( nElement ); return 0; }; + case A_TOKEN( solidFill ): { rFillProps.moFillType = getToken( nElement ); return new SolidFillContext( rParent, rxAttribs, rFillProps ); }; + case A_TOKEN( gradFill ): { rFillProps.moFillType = getToken( nElement ); return new GradientFillContext( rParent, rxAttribs, rFillProps.maGradientProps ); }; + case A_TOKEN( pattFill ): { rFillProps.moFillType = getToken( nElement ); return new PatternFillContext( rParent, rxAttribs, rFillProps.maPatternProps ); }; + case A_TOKEN( blipFill ): { rFillProps.moFillType = getToken( nElement ); return new BlipFillContext( rParent, rxAttribs, rFillProps.maBlipProps ); }; + case A_TOKEN( grpFill ): { rFillProps.moFillType = getToken( nElement ); return 0; }; // TODO } return 0; } From c98137541cc93a58f05a334882f17b544ddab5c8 Mon Sep 17 00:00:00 2001 From: Kurt Zenker Date: Thu, 10 Sep 2009 22:33:17 +0000 Subject: [PATCH 04/16] CWS-TOOLING: integrate CWS mh232 2009-08-26 03:52:57 +0200 mh r275385 : #i102182# FreeBSD patch 2009-08-26 03:43:20 +0200 mh r275384 : #i101333# patch for FreeBSD 2009-08-26 03:11:20 +0200 mh r275383 : #i39230 2009-08-26 03:07:51 +0200 mh r275382 : #i39230# more space for initials field 2009-08-26 02:41:19 +0200 mh r275380 : #i39230# use vos::osecurity for reading the user name 2009-08-18 22:06:00 +0200 mh r275130 : #i104243#, line ending problem with newer perl 2009-08-18 21:53:21 +0200 mh r275129 : #i39230# read initials via getpwnam 2009-08-18 21:34:05 +0200 mh r275128 : enable CAIROCANVAS for Linux and Mac, #i88613# 2009-08-17 18:02:59 +0200 mh r275067 : #i95498# make compile with gcc3 --- filter/source/pdf/impdialog.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx index 5cc851f6732e..46b9835eb648 100644 --- a/filter/source/pdf/impdialog.cxx +++ b/filter/source/pdf/impdialog.cxx @@ -1436,8 +1436,8 @@ ImplErrorDialog::ImplErrorDialog( const std::set< vcl::PDFWriter::ErrorCode >& r { // load images - Image aWarnImg( BitmapEx( ResId( IMG_WARN, rResMgr ) ) ); - Image aErrImg( BitmapEx( ResId( IMG_ERR, rResMgr ) ) ); + Image aWarnImg = Image ( BitmapEx( ResId( IMG_WARN, rResMgr ) ) ); + Image aErrImg= Image ( BitmapEx( ResId( IMG_ERR, rResMgr ) ) ); for( std::set::const_iterator it = rErrors.begin(); it != rErrors.end(); ++it ) From 47bce7355f0d4dd1a0162bc0f52b1099d05784ec Mon Sep 17 00:00:00 2001 From: Kurt Zenker Date: Fri, 11 Sep 2009 14:29:45 +0000 Subject: [PATCH 05/16] CWS-TOOLING: integrate CWS odfmetadata3 2009-09-11 Michael Stahl merge DEV300_m58 2009-09-07 Michael Stahl SwFmtFld::Modify(): do nothing on RES_OBJECTDYING 2009-08-27 Michael Stahl #i91565#, #i91566#: TextPortionEnumerationTest.java: add test document 2009-08-27 Michael Stahl #i91565#, #i91566#: add complex test: TextPortionEnumerationTest.java 2009-08-27 Michael Stahl CLiteral::initialize(): zero-length literals probably not an error 2009-08-27 Michael Stahl #i91565#, #i91566#: offapi: new InContentMetadata and MetadataField services adapt TextPortion for InContentMetadata 2009-08-27 Michael Stahl #i91564#: xmloff: load/store xml:id and RDFa for text:bookmark(-start). 2009-08-27 Michael Stahl #i91564#: sw core: add support for xml:id at bookmarks: sw::mark::Bookmark: derive from Metadatable. SwHistoryBookmark, SaveBookmark: store a MetadatableUndo. ndcopy.cxx: lcl_CopyBookmarks(): copy the xml:id. SwXBookmark: derive from MetadatableMixin. 2009-08-27 Michael Stahl #i91565#, #i91566#: xmloff: refactor ruby import so nested meta(-field) works: remove XMLRubyHint_Impl. XMLImpRubyContext_Impl::~XMLImpRubyContext_Impl(): insert ruby directly. 2009-08-27 Michael Stahl #i91565#, #i91566#: xmloff: fix text:meta(-field) import/export: new XMLTextParagraphExport::exportTextField() overload for XTextField. CreateAndInsertMark(): set xml:id after insertion. fix meta(-field) service names, bugs etc. 2009-08-27 Michael Stahl #i91565#, #i91566#: sw text formatting: paint background of meta(-field) body: SwFont: add member m_nMetaCount. txttypes.hxx: add POR_META. atrstck.cxx: handle RES_TXTATR_META(FIELD). itrform2.cxx: SwTxtFormatter::WhichTxtPor(): create new class SwMetaPortion. 2009-08-27 Michael Stahl #i91566#: sw text formatting: display meta-field prefix and suffix: SwAttrIter::GetAttr(): replace with call to GetTxtAttrForCharAt(). SwTxtFormatter::NewExtraPortion(): handle meta-field prefix. SwTxtFormatter: new member m_nHintEndIndex. SwTxtFormatter::WhichFirstPortion(): call TryNewNoLengthPortion(). SwTxtFormatter::TryNewNoLengthPortion(): new; handle suffix of meta-field. SwTxtFormatter::UnderFlow(): UGLY HACK: decrement m_nHintEndIndex. SwFldPortion: add flag m_bNoLength: portion has zero length (for suffix). 2009-08-27 Michael Stahl #i91565#, #i91566#: extend text:meta(-field) uno wrapper with XText interface: unoobj.hxx: new CursorType CURSOR_META. unoobj2.cxx: refactor SwXText implementation to ensure that when the SwXText belongs to a SwXMeta, content is always inserted inside the meta(-field). unoobj.cxx: new SwXTextCursor::ForceIntoMeta(): cursor stays in meta(-field). unometa.hxx: SwXMeta implements XText, forwarding to a member SwXMetaText. DocInsertStringSplitCR(), SwX*::attachToRange(), SwX*::DeleteAndInsert(): use FORCEHINTEXPAND hack to ensure insert into the meta(-field) at the end. 2009-08-27 Michael Stahl #i91565#, #i91566#: add text:meta(-field) uno wrapper to sw: fmtmeta.hxx, fmtatr2.cxx: new class sw::MetaField, new sw::MetaFieldManager. doc.hxx, docnew.cxx: new SwDoc::GetMetaFieldManager(). unocoll.hxx,.cxx: new SW_SERVICE_FIELDTYPE_METAFIELD, SW_SERVICE_TYPE_META. unomap.hxx,.cxx: new PROPERTY_MAP_METAFIELD. unoprnms.hxx: new UNO_NAME_META. unoport.hxx: new PORTION_META; add "InContentMetadata" prop to SwXTextPortion. new unometa.hxx: new class SwXMeta and SwXMetaField. unofield.cxx: SwXFieldEnumeration: include meta-fields. unoportenum.cxx: handle RES_TXTATR_META(FIELD) by using a portion list stack. unotext.cxx: SwXText::insertTextContent(): handle meta(-field) as attribute. 2009-08-27 Michael Stahl #i91565#, #i91566#: ndhints.cxx: remove sort number from SwTxtAttrNesting 2009-08-27 Michael Stahl #i91565#, #i91566#: add support for hints with end and CH_TXTATR to sw core: doc.hxx, docedt.cxx: replace SwDoc::Delete(), DeleteAndJoin(), ReplaceRange() with wrappers that split at left-overlapped end+CH_TXTATR hints. txatbase.hxx: new member SwTxtAttr::m_bHasDummyChar. ndtxt.hxx: rename SwTxtNode::GetTxtAttr() to GetTxtAttrForCharAt(). ndtxt.cxx: SwTxtNode::CopyText(): copy end+CH_TXTATR hints iff copy CH_TXTATR. txtatr2.cxx, thints.cxx: SwTxtMeta gets a CH_TXTATR. 2009-08-27 Michael Stahl #i91565#, #i91566#: add text:meta(-field) to sw core: txatbase.hxx: new member SwTxtAttr::m_bNesting. hintids.hxx: new ids RES_TXTATR_META, RES_TXTATR_METAFIELD. txtatr.hxx: new base class SwTxtAttrNesting. new hint SwTxtMeta. SwTxtRuby derives from SwTxtAttrNesting. txtinet.hxx: SwTxtINetFmt derives from SwTxtAttrNesting. new header fmtmeta.hxx: new pool item SwFmtMeta. new class sw::Meta. ndhints.hxx, thints.cxx: new method SwpHints::TryInsertNesting(). thints.cxx: refactoring: BuildPortions() no longer handles Ruby/Hyperlink, but TryInsertNesting(), which also handles meta(-field). SwTxtNode::InsertItem(): check if the hint is actually inserted. ndhints.cxx: sort nesting hints based on sort number. ndtxt.cxx: lcl_CopyHint(): handle copy of meta/meta-field. 2009-08-27 Michael Stahl enable expanding hints with m_bLockExpandFlag set: add new InsertFlag: INS_FORCEHINTEXPAND. add new SetAttrMode: SETATTR_FORCEHINTEXPAND. rename SwEditShell::Insert() to Insert2() because changed signature fails to compile when SwWrtShell tries to overwrite these non-virtual members... SwWrtShell::Insert() sets FOCEHINTEXPAND if range was selected/deleted. adapt SwUndoInsert to store flags. 2009-08-27 Michael Stahl change formal parameters of item insertion methods to type SetAttrMode 2009-08-27 Michael Stahl fix incorrect resetting of text attributes in SwUndoInsSection, SwUndoInserts 2009-08-27 Michael Stahl clean up SwTxtNode::CutImpl() and lcl_CopyHint() 2009-08-27 Michael Stahl rename SwDoc::Copy() to CopyRange(), and _Copy() to CopyImpl() 2009-08-27 Michael Stahl rename SwNodes::Move() to MoveRange(), and remove unused parameter 2009-08-27 Michael Stahl rename SwDoc::Move() to MoveRange()/MoveNodeRange() 2009-08-27 Michael Stahl rename SwDoc::Insert() to InsertString(), and remove sal_Unicode variant 2009-08-27 Michael Stahl rename SwDoc::Insert() to InsertPoolItem()/InsertItemSet()/InsertSwSection() 2009-08-27 Michael Stahl rename SwDoc::Replace() to ReplaceRange() 2009-08-27 Michael Stahl remove SwDoc::Overwrite() sal_Unicode variant 2009-08-27 Michael Stahl split up SwDoc::DeleteAndJoin(): factor out DeleteAndJoinWithRedline() 2009-08-27 Michael Stahl rename overloaded SwDoc::Delete() to DeleteRange()/DeleteTOXMark() 2009-08-27 Michael Stahl rename SwTxtNode::Copy() to CopyText() 2009-08-27 Michael Stahl rename SwTxtNode::Cut() to CutText(), and _Cut() to CutImpl() 2009-08-27 Michael Stahl rename SwTxtNode::Delete() to DeleteAttribute()/DeleteAttributes() 2009-08-27 Michael Stahl rename SwTxtNode::Replace() to ReplaceText(), and remove the xub_Unicode variant 2009-08-27 Michael Stahl rename SwTxtNode::Erase() to EraseText() 2009-08-27 Michael Stahl rename SwTxtNode::Insert() to InsertText(), and remove the xub_Unicode variant 2009-08-27 Michael Stahl clean up SwTxtNode::Update() 2009-08-27 Michael Stahl remove SwTxtAttr::RemoveFromPool() and make destructor non-public, to be invoked by new method SwTxtAttr::Destroy() 2009-08-27 Michael Stahl ensure that SwDoc::Insert() for item (set) returns success indicator: replace SwRegHistory constructor with method InsertItems(), returning bool. refactor InsAttr() so that it checks if InsertItems() succeeds. 2009-08-27 Michael Stahl move SwXTextPortionEnumeration from unoobj.hxx to unoport.hxx 2009-08-27 Michael Stahl add missing SolarMutex in SwXTextPortion methods 2009-08-27 Michael Stahl SwXTextPortion: new member m_xTextField (so the TextField property need not be returned indirectly via SwUnoCursorHelper). factor out function CreateSwXTextField(). 2009-08-27 Michael Stahl SwXTextPortion: remove PORTION_CONTROL_CHAR and implementation of XTextField 2009-08-27 Michael Stahl remove obsolete hint SwTxtHardBlank and formats SwFmtHardBlank/SwFmtSoftHyph 2009-08-27 Michael Stahl clean up SwTxtAttr and friends: remove many accessor methods for obsolete (due to autofmt) char format items. remove unused flag SwTxtAttr::m_bDontMergeAttr. MakeRedlineTxtAttr() now dedicated function, no longer calls MakeTxtAttr(). 2009-08-27 Michael Stahl remove obsolete attribute SwTxt2Lines 2009-08-27 Michael Stahl SwXTextPortionEnumeration: finish refactoring CreatePortions change ExportHints so it always returns a text portion for hint w/ CH_TXTATR. remove special case for handling end of paragraph. unfortunately had to refactor the fieldmarks export as well (got in the way). 2009-08-27 Michael Stahl SwXTextPortionEnumeration: refactor CreatePortions: frames export extract function ExportFrames() from CreatePortions(). remove (un)dead code that calls evil MovePara(fnParaCurr, fnParaEnd) 2009-08-27 Michael Stahl clean up SwXParaFrameEnumeration 2009-08-27 Michael Stahl CollectFrameAtNode: replace SwDependArr with STL based FrameDependList_t 2009-08-27 Michael Stahl SwXTextPortionEnumeration: tweak refmark/toxmark export so ExportHints returns the portion for point marks 2009-08-27 Michael Stahl clean up SwXTextPortionEnumeration: prefix members, remove casts, replace SvWeirdArray with STL, etc. make CreatePortions() method a function, and remove lots of members. extract fieldmarks function from CreatePortions. 2009-08-27 Michael Stahl remove FOREACHUNOPAM_START/END macros 2009-08-27 Michael Stahl clean up SwXTextPortion: prefix members, remove casts, etc. remove SwXRubyPortion: replace it with another SwXTextPortion constructor 2009-08-27 Michael Stahl #i102541# SwXReferenceMark::InsertRefMark(): use flag SETATTR_DONTEXPAND 2009-08-27 Michael Stahl rename SwTxtNode::Insert to SwTxtNode::InsertHint, and fix constness in SwTxtNode::InsertItem 2009-08-27 Michael Stahl turn SwTxtNode::MakeTxtAttr() methods into global functions in ndhints.hxx 2009-08-27 Michael Stahl remove obsolete sw/inc/bookmrk.hxx 2009-08-27 Michael Stahl pam.cxx: fix ComparePosition functions (returned wrong result in one case) 2009-08-27 Michael Stahl #i103613# only import RDF metadata on normal open of a document 2009-09-11 kz CWS-TOOLING: integrate CWS impress176 2009-09-08 20:18:24 +0200 sj r275957 : fixed warning (shadowed variable) 2009-09-08 18:02:05 +0200 cl r275948 : #i104315# added missing tab pages 2009-09-08 17:35:18 +0200 cl r275947 : #i104866# fixed angle import 2009-09-08 17:32:53 +0200 cl r275946 : #i104841# fixed angle import 2009-09-08 17:01:25 +0200 cl r275943 : #i103935# fixed the SID_EVENTCONFIG mess 2009-09-08 14:32:57 +0200 sj r275928 : #i104685# only comments 2009-09-07 12:37:36 +0200 sj r275886 : #i104683# fixed import of bold/italic attributes for normal text shapes 2009-09-04 15:07:46 +0200 sj r275808 : #104689# fixed bullet color problem 2009-09-03 15:25:07 +0200 sj r275753 : #160200# added vertical alignment of table cells 2009-09-11 kz CWS-TOOLING: integrate CWS dv14 2009-09-10 15:16:32 +0200 sg r276035 : #160513# updated wfs scheme to accept ports 2009-09-10 07:41:47 +0200 dv r276019 : #i104942# Better renaming algorithmen 2009-08-31 13:41:11 +0200 dv r275604 : #160505# Setting APP1PRODUCTNAME must not overwrite APP1PRODUCTDEF 2009-09-11 kz CWS-TOOLING: integrate CWS jl131 2009-09-02 16:42:40 +0200 jl r275720 : #i97896# 2009-08-31 13:01:53 +0200 jl r275599 : CWS-TOOLING: rebase CWS jl131 to trunk@275331 (milestone: DEV300:m56) 2009-07-31 14:35:30 +0200 jl r274531 : CWS-TOOLING: rebase CWS jl131 to trunk@274203 (milestone: DEV300:m53) 2009-07-23 14:20:32 +0200 jl r274272 : #i79839# better error text when trying to modify shared layer without having write permission, eg. unopkg add --shared, unopkg remove --shared, unopkg reinstall --shared 2009-07-22 16:38:02 +0200 jl r274252 : #i97896# localize error message for lock file 2009-07-22 16:37:22 +0200 jl r274251 : #i80462# unprecise wording in updatedialog 2009-07-22 16:36:06 +0200 jl r274250 : #i97896# localize error message for lock file 2009-07-22 16:35:20 +0200 jl r274249 : #i97896# localize error message for lock file 2009-07-22 15:07:30 +0200 jl r274242 : #i98873# minimum java version is 1.5 since OOo 3.0 2009-09-11 kz CWS-TOOLING: integrate CWS changehc 2009-08-31 19:38:50 +0200 pl r275633 : remove dbug printf 2009-08-31 17:41:50 +0200 pl r275623 : CWS-TOOLING: rebase CWS changehc to trunk@275331 (milestone: DEV300:m56) 2009-07-15 19:45:46 +0200 pl r274028 : #i35482# use HC flag to decide high contrast mode 2009-07-15 17:40:52 +0200 pl r274020 : #i35482# use HC flag to decide high contrast mode 2009-07-15 17:39:50 +0200 pl r274019 : #i35482# update autohc correctly in MergeSystemSettings 2009-07-15 17:38:57 +0200 pl r274018 : #i35482# update autohc correctly in MergeSystemSettings 2009-09-11 kz CWS-TOOLING: integrate CWS notes10 2009-08-24 07:25:57 +0200 mod r275287 : 2009-07-26 02:38:32 +0200 mod r274343 : #i#i103645# 2009-07-26 02:01:53 +0200 mod r274342 : #i103645# 2009-07-26 01:52:42 +0200 mod r274341 : #i103490# 2009-07-22 08:31:48 +0200 mod r274215 : #i103373# 2009-07-15 00:55:11 +0200 mod r273987 : #i101419# 2009-07-14 07:07:55 +0200 mod r273956 : #i101419# 2009-07-14 07:07:43 +0200 mod r273955 : #i101419# 2009-07-14 07:02:10 +0200 mod r273954 : changes from notes9 2009-07-14 06:14:25 +0200 mod r273953 : #i103476# 2009-09-11 kz CWS-TOOLING: integrate CWS ab70 2009-09-10 15:12:54 +0200 jsk r276034 : #i85434# - mandatory automatic update test 2009-09-10 15:11:06 +0200 jsk r276033 : #i85434# - mandatory automatic update test 2009-09-02 09:49:24 +0200 ab r275698 : #i85434# Dialog Import 2009-09-11 kz CWS-TOOLING: integrate CWS hb32bugs02 2009-09-02 Henning Brinkmann #i102420# revert changes 2009-08-26 Henning Brinkmann merged DEV300_m56 2009-08-19 Henning Brinkmann merged DEV300_m55 2009-08-14 Henning Brinkmann merged changes from wntmsci12 2009-08-12 Henning Brinkmann Implemented NoSpaceEdit constructor and destructor in .cxx to allow compile with debug on wntmsci12. 2009-08-12 Henning Brinkmann Added some SW_DLLPUBLIC to make compilable on wntmsci12. 2009-08-11 Henning Brinkmann #i102420# dbg_out: surround output for SwNodes with . 2009-08-10 Henning Brinkmann #i102420# rewritten debug output for SwNodes. 2009-08-07 Henning Brinkmann #i102420# debug _MoveNodes: output the destination, too. Break after two iterations. 2009-08-07 Henning Brinkmann #i102420# _MoveNodes: Additionally check if destination index is inside source => false Check if current range was already handled => loop Debug output current range 2009-08-06 Henning Brinkmann merged DEV300_m54 2009-08-06 Henning Brinkmann added master fix 2009-08-06 Henning Brinkmann debug output for SwNodeRange 2009-08-04 Henning Brinkmann #i102844# robustness: check for NULL pointer to prevent crash 2009-08-03 Henning Brinkmann #i103475# applied patch and verified 2009-08-03 Henning Brinkmann Removed code preventing build of sw with DEBUG. 2009-09-11 convert-repo update tags 2009-09-10 kz CWS-TOOLING: integrate CWS os2port06dev300 2009-09-05 22:49:00 +0200 ydario r275858 : #i99588# applied os2port06 diff to DEV300 tree. 2009-09-10 kz CWS-TOOLING: integrate CWS mingwport23 2009-08-29 07:07:53 +0200 tono r275555 : i#104522: mingw port graphite 2009-08-29 07:07:26 +0200 tono r275554 : i#104522: mingw port printf format fix 2009-09-10 kz CWS-TOOLING: integrate CWS mh232 2009-08-26 03:52:57 +0200 mh r275385 : #i102182# FreeBSD patch 2009-08-26 03:43:20 +0200 mh r275384 : #i101333# patch for FreeBSD 2009-08-26 03:11:20 +0200 mh r275383 : #i39230 2009-08-26 03:07:51 +0200 mh r275382 : #i39230# more space for initials field 2009-08-26 02:41:19 +0200 mh r275380 : #i39230# use vos::osecurity for reading the user name 2009-08-18 22:06:00 +0200 mh r275130 : #i104243#, line ending problem with newer perl 2009-08-18 21:53:21 +0200 mh r275129 : #i39230# read initials via getpwnam 2009-08-18 21:34:05 +0200 mh r275128 : enable CAIROCANVAS for Linux and Mac, #i88613# 2009-08-17 18:02:59 +0200 mh r275067 : #i95498# make compile with gcc3 2009-09-10 kz CWS-TOOLING: integrate CWS tkr24 2009-09-07 14:31:06 +0200 is r275898 : #160081# adding NO_LICENSE_INTO_COPYRIGHT 2009-09-10 releng #i10000# change KeyMapping to SingletonRef 2009-09-11 convert-repo update tags 2009-09-10 kz CWS-TOOLING: integrate CWS os2port06dev300 2009-09-05 22:49:00 +0200 ydario r275858 : #i99588# applied os2port06 diff to DEV300 tree. 2009-09-10 kz CWS-TOOLING: integrate CWS mingwport23 2009-08-29 07:07:53 +0200 tono r275555 : i#104522: mingw port graphite 2009-08-29 07:07:26 +0200 tono r275554 : i#104522: mingw port printf format fix 2009-09-10 kz CWS-TOOLING: integrate CWS mh232 2009-08-26 03:52:57 +0200 mh r275385 : #i102182# FreeBSD patch 2009-08-26 03:43:20 +0200 mh r275384 : #i101333# patch for FreeBSD 2009-08-26 03:11:20 +0200 mh r275383 : #i39230 2009-08-26 03:07:51 +0200 mh r275382 : #i39230# more space for initials field 2009-08-26 02:41:19 +0200 mh r275380 : #i39230# use vos::osecurity for reading the user name 2009-08-18 22:06:00 +0200 mh r275130 : #i104243#, line ending problem with newer perl 2009-08-18 21:53:21 +0200 mh r275129 : #i39230# read initials via getpwnam 2009-08-18 21:34:05 +0200 mh r275128 : enable CAIROCANVAS for Linux and Mac, #i88613# 2009-08-17 18:02:59 +0200 mh r275067 : #i95498# make compile with gcc3 2009-09-10 kz CWS-TOOLING: integrate CWS tkr24 2009-09-07 14:31:06 +0200 is r275898 : #160081# adding NO_LICENSE_INTO_COPYRIGHT 2009-09-10 releng #i10000# change KeyMapping to SingletonRef --- unoxml/source/rdf/CLiteral.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unoxml/source/rdf/CLiteral.cxx b/unoxml/source/rdf/CLiteral.cxx index 5b63e81b832b..25a8267f5cc5 100644 --- a/unoxml/source/rdf/CLiteral.cxx +++ b/unoxml/source/rdf/CLiteral.cxx @@ -124,7 +124,7 @@ void SAL_CALL CLiteral::initialize(const css::uno::Sequence< ::com::sun::star::u "argument must be string"), *this, 0); } //FIXME: what is legal? - if (arg0.getLength() > 0) { + if (true) { m_Value = arg0; } else { throw css::lang::IllegalArgumentException( From 0504dde7fb924dd875acf7815b41802a8b470b0b Mon Sep 17 00:00:00 2001 From: Kurt Zenker Date: Fri, 11 Sep 2009 18:55:06 +0000 Subject: [PATCH 06/16] CWS-TOOLING: integrate CWS odff06 2009-09-10 18:58:49 +0200 dr r276042 : #i104954# excel export: fixed broken handling of unary operators 2009-09-06 19:30:43 +0200 er r275861 : warnings 2009-09-05 19:48:41 +0200 er r275849 : warnings; wntmsci12 tries to be too smart 2009-09-05 19:37:47 +0200 er r275848 : warnings 2009-09-03 22:45:42 +0200 er r275776 : #i5658# GetCellValueOrZero: missed the formula cell case 2009-09-03 14:28:41 +0200 er r275752 : #i90759# better description of ZTEST 2009-09-03 03:34:03 +0200 er r275739 : warnings 2009-09-03 03:31:19 +0200 er r275738 : warnings 2009-09-03 03:16:46 +0200 er r275737 : warnings 2009-09-03 03:11:42 +0200 er r275736 : CELLTYPE_DESTROYED only if DBG_UTIL 2009-09-03 03:06:31 +0200 er r275735 : warnings 2009-09-03 03:00:30 +0200 er r275734 : warnings 2009-09-03 02:32:35 +0200 er r275733 : fix broken rebase merge 2009-09-02 22:27:53 +0200 er r275730 : CWS-TOOLING: rebase CWS odff06 to trunk@275331 (milestone: DEV300:m56) 2009-09-02 14:45:05 +0200 er r275712 : #i5658# calculate with string operands as long as they unambiguously represent an integer or ISO 8601 date and/or time value 2009-08-29 22:05:31 +0200 er r275559 : #i99140# CONVERT_ADD new conversions as per ODFF; patch from , slightly changed 2009-08-25 13:23:59 +0200 er r275349 : #i90759# rewording of ZTEST description 2009-08-21 00:10:22 +0200 er r275204 : #i82007# correct description of POWER and parameters; patch from 2009-08-20 23:58:20 +0200 er r275203 : #i74704# B correct calculation for SP arguments 0 and 1; patch from 2009-08-20 22:58:57 +0200 er r275201 : #i90759# ZTEST correct calculation using the 3rd parameter sigma 2009-08-14 17:55:45 +0200 er r275000 : #i81214# LOOKUP with single values, data arrays and result arrays; based on a patch from 2009-08-11 00:47:48 +0200 er r274845 : unxlngi6 compiler warnings 2009-08-11 00:43:06 +0200 er r274844 : unxlngi6 compiler warnings 2009-08-10 23:59:05 +0200 er r274843 : #91351# make HYPERLINK accept and return numeric values, propagate errors 2009-07-08 18:46:00 +0200 dr r273846 : #i102022# export 3D refs to cond. formats and data validation 2009-07-02 17:59:40 +0200 dr r273667 : #i102702# adapt changes from sc/source/filter/excel 2009-07-02 15:20:37 +0200 dr r273656 : #i102702# reimplementation of formula token class export 2009-07-02 14:41:02 +0200 er r273653 : a surrogate with value 0x10000 is also valid (ran into when testing #i99900# Calc's UNICHAR function), and Unicode ends at 0x10ffff 2009-07-01 00:10:16 +0200 er r273536 : #i99900# iterateCodePoints: check index against string length to avoid assertion; caught this when testing Calc's new UNICHAR function, with the result of a surrogate pair forming one character. 2009-07-01 00:03:57 +0200 er r273535 : #i99900# new UNICODE and UNICHAR functions; patch from 2009-06-15 16:42:06 +0200 er r272999 : merge patch from #i102701 2009-06-15 11:15:16 +0200 dr r272970 : #i102702# in BIFF, the SKIP flag may be missing for the tAttrSkip token 2009-06-11 13:27:46 +0200 er r272867 : CWS-TOOLING: rebase CWS odff06 to trunk@272827 (milestone: DEV300:m50) 2009-04-30 18:28:02 +0200 er r271423 : #i94618# on status bar, ignore error of cell for COUNT and COUNTA if selection; patch from 2009-04-30 13:58:44 +0200 er r271413 : get rid of that ugly mail address thingie in RTL_LOGFILE_CONTEXT_AUTHOR introduced by CWS frmdlg ... 2009-04-30 12:32:44 +0200 er r271411 : #i94618# do not display error of cell for COUNT and COUNTA status bar functions 2009-04-30 01:32:38 +0200 er r271399 : #i101316# improve accuracy of STDEV on equal values; patch from 2009-04-30 01:18:54 +0200 er r271398 : #i97605# improve accuracy of ASINH and ACOSH; patch from 2009-04-30 00:46:00 +0200 er r271397 : #i59153# improve accuracy of MOD; patch from 2009-04-30 00:29:43 +0200 er r271396 : #i69069# improve accuracy of NORMSDIST and POISSON; patch from 2009-04-29 23:53:28 +0200 er r271395 : #i100119# NORMDIST and LOGNORMDIST optional parameters, plus improvement in accuracy also of NORMSDIST (part of i69069); patch from 2009-04-28 18:22:07 +0200 er r271337 : #i97052# REPLACE with no length of text to be removed simply inserts new text; patch from , slightly modified 2009-03-24 17:29:36 +0100 er r269982 : #i97091# moved implementation of erf() and erfc() from scaddins to sal to provide C99 functions for compilers lacking it --- oox/inc/oox/xls/formulabase.hxx | 164 ++++-- oox/source/dump/biffdumper.cxx | 1 + oox/source/dump/biffdumper.ini | 1 + oox/source/xls/formulabase.cxx | 934 ++++++++++++++++--------------- oox/source/xls/formulaparser.cxx | 14 +- 5 files changed, 632 insertions(+), 482 deletions(-) diff --git a/oox/inc/oox/xls/formulabase.hxx b/oox/inc/oox/xls/formulabase.hxx index b2e576d3fdd5..11a0be44600a 100644 --- a/oox/inc/oox/xls/formulabase.hxx +++ b/oox/inc/oox/xls/formulabase.hxx @@ -58,8 +58,6 @@ const size_t BIFF_TOKARR_MAXLEN = 4096; /// Maximum size of // token class flags ---------------------------------------------------------- const sal_uInt8 BIFF_TOKCLASS_MASK = 0x60; -const sal_uInt8 BIFF_TOKID_MASK = 0x1F; - const sal_uInt8 BIFF_TOKCLASS_NONE = 0x00; /// 00-1F: Base tokens. const sal_uInt8 BIFF_TOKCLASS_REF = 0x20; /// 20-3F: Reference class tokens. const sal_uInt8 BIFF_TOKCLASS_VAL = 0x40; /// 40-5F: Value class tokens. @@ -69,6 +67,8 @@ const sal_uInt8 BIFF_TOKFLAG_INVALID = 0x80; /// This bit must be // base token identifiers ----------------------------------------------------- +const sal_uInt8 BIFF_TOKID_MASK = 0x1F; + const sal_uInt8 BIFF_TOKID_NONE = 0x00; /// Placeholder for invalid token id. const sal_uInt8 BIFF_TOKID_EXP = 0x01; /// Array or shared formula reference. const sal_uInt8 BIFF_TOKID_TBL = 0x02; /// Multiple operation reference. @@ -361,6 +361,115 @@ struct ApiOpCodes sal_Int32 OPCODE_RANGE; /// Range operator. }; +// Function parameter info ==================================================== + +/** Enumerates validity modes for a function parameter. */ +enum FuncParamValidity +{ + FUNC_PARAM_NONE = 0, /// Default for an unspecified entry in a C-array. + FUNC_PARAM_REGULAR, /// Parameter supported by Calc and Excel. + FUNC_PARAM_CALCONLY, /// Parameter supported by Calc only. + FUNC_PARAM_EXCELONLY /// Parameter supported by Excel only. +}; + +/** Enumerates different types of token class conversion in function parameters. */ +enum FuncParamConversion +{ + FUNC_PARAMCONV_ORG, /// Use original class of current token. + FUNC_PARAMCONV_VAL, /// Convert tokens to VAL class. + FUNC_PARAMCONV_ARR, /// Convert tokens to ARR class. + FUNC_PARAMCONV_RPT, /// Repeat parent conversion in VALTYPE parameters. + FUNC_PARAMCONV_RPX, /// Repeat parent conversion in REFTYPE parameters. + FUNC_PARAMCONV_RPO /// Repeat parent conversion in operands of operators. +}; + +/** Structure that contains all needed information for a parameter in a + function. + + The member meValid specifies which application supports the parameter. If + set to CALCONLY, import filters have to insert a default value for this + parameter, and export filters have to skip the parameter. If set to + EXCELONLY, import filters have to skip the parameter, and export filters + have to insert a default value for this parameter. + + The member mbValType specifies whether the parameter requires tokens to be + of value type (VAL or ARR class). + + If set to false, the parameter is called to be REFTYPE. Tokens with REF + default class can be inserted for the parameter (e.g. tAreaR tokens). + + If set to true, the parameter is called to be VALTYPE. Tokens with REF + class need to be converted to VAL tokens first (e.g. tAreaR will be + converted to tAreaV), and further conversion is done according to this + new token class. + + The member meConv specifies how to convert the current token class of the + token inserted for the parameter. If the token class is still REF this + means that the token has default REF class and the parameter is REFTYPE + (see member mbValType), the token will not be converted at all and remains + in REF class. Otherwise, token class conversion is depending on the actual + token class of the return value of the function containing this parameter. + The function may return REF class (tFuncR, tFuncVarR, tFuncCER), or it may + return VAL or ARR class (tFuncV, tFuncA, tFuncVarV, tFuncVarA, tFuncCEV, + tFuncCEA). Even if the function is able to return REF class, it may return + VAL or ARR class instead due to the VALTYPE data type of the parent + function parameter that calls the own function. Example: The INDIRECT + function returns REF class by default. But if called from a VALTYPE + function parameter, e.g. in the formula =ABS(INDIRECT("A1")), it returns + VAL or ARR class instead. Additionally, the repeating conversion types RPT + and RPX rely on the conversion executed for the function token class. + + 1) ORG: + Use the original class of the token (VAL or ARR), regardless of any + conversion done for the function return class. + + 2) VAL: + Convert ARR tokens to VAL class, regardless of any conversion done for + the function return class. + + 3) ARR: + Convert VAL tokens to ARR class, regardless of any conversion done for + the function return class. + + 4) RPT: + If the own function returns REF class (thus it is called from a REFTYPE + parameter, see above), and the parent conversion type (for the function + return class) was ORG, VAL, or ARR, ignore that conversion and always + use VAL conversion for the own token instead. If the parent conversion + type was RPT or RPX, repeat the conversion that would have been used if + the function would return value type. + If the own function returns value type (VAL or ARR class, see above), + and the parent conversion type (for the function return class) was ORG, + VAL, ARR, or RPT, repeat this conversion for the own token. If the + parent conversion type was RPX, always use ORG conversion type for the + own token instead. + + 5) RPX: + This type of conversion only occurs in functions returning VAL class by + default. If the own token is value type, and the VAL return class of + the own function has been changed to ARR class (due to direct ARR + conversion, or due to ARR conversion repeated by RPT or RPX), set the + own token to ARR type. Otherwise use the original token type (VAL + conversion from parent parameter will not be repeated at all). If + nested functions have RPT or value-type RPX parameters, they will not + repeat this conversion type, but will use ORG conversion instead (see + description of RPT above). + + 6) RPO: + This type of conversion is only used for the operands of all operators + (unary and binary arithmetic operators, comparison operators, and range + operators). It is not used for function parameters. On conversion, it + will be replaced by the last conversion type that was not the RPO + conversion. This leads to a slightly different behaviour than the RPT + conversion for operands in conjunction with a parent RPX conversion. + */ +struct FunctionParamInfo +{ + FuncParamValidity meValid; /// Parameter validity. + FuncParamConversion meConv; /// Token class conversion type. + bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE). +}; + // function data ============================================================== /** This enumeration contains constants for all known external libraries @@ -373,23 +482,13 @@ enum FunctionLibraryType // ---------------------------------------------------------------------------- -const sal_uInt8 FUNCINFO_MAXPARAM = 30; /// Maximum parameter count. - -const sal_uInt8 FUNCINFO_PARAM_EXCELONLY = 0x01; /// Flag for a parameter existing in Excel, but not in Calc. -const sal_uInt8 FUNCINFO_PARAM_CALCONLY = 0x02; /// Flag for a parameter existing in Calc, but not in Excel. -const sal_uInt8 FUNCINFO_PARAM_INVALID = 0x04; /// Flag for an invalid token class. - /** Represents information for a spreadsheet function. - The member mpnParamClass contains an array of BIFF token classes for each - parameter of the function. The last existing (non-null) value in this array - is used for all following parameters used in a function. Additionally to - the three actual token classes, this array may contain the special values - FUNCINFO_PARAM_CALCONLY, FUNCINFO_PARAM_EXCELONLY, and - FUNCINFO_PARAM_INVALID. The former two specify parameters only existing in - one of the applications. FUNCINFO_PARAM_INVALID is simply a terminator for - the array to prevent repetition of the last token class or special value - for additional parameters. + The member mpParamInfos points to an array of type information structures + for all parameters of the function. The last initialized structure + describing a regular parameter (member meValid == EXC_PARAMVALID_ALWAYS) in + this array is used repeatedly for all following parameters supported by a + function. */ struct FunctionInfo { @@ -404,7 +503,8 @@ struct FunctionInfo sal_uInt8 mnMinParamCount; /// Minimum number of parameters. sal_uInt8 mnMaxParamCount; /// Maximum number of parameters. sal_uInt8 mnRetClass; /// BIFF token class of the return value. - const sal_uInt8* mpnParamClass; /// Expected BIFF token classes of parameters. + const FunctionParamInfo* mpParamInfos; /// Information about all parameters. + bool mbParamPairs; /// true = optional parameters are expected to appear in pairs. bool mbVolatile; /// True = volatile function. bool mbExternal; /// True = external function in Calc. bool mbMacroFunc; /// True = macro sheet function or command. @@ -415,28 +515,28 @@ typedef RefVector< FunctionInfo > FunctionInfoVector; // function info parameter class iterator ===================================== -/** Iterator working on the mpnParamClass member of the FunctionInfo struct. +/** Iterator working on the mpParamInfos member of the FunctionInfo struct. This iterator can be used to iterate through the array containing the - expected token classes of function parameters. This iterator repeats the - last valid token class in the array - it stops automatically before the - first empty array entry or before the end of the array, even for repeated - calls to the increment operator. + token class conversion information of function parameters. This iterator + repeats the last valid structure in the array - it stops automatically + before the first empty array entry or before the end of the array, even for + repeated calls to the increment operator. */ -class FuncInfoParamClassIterator +class FunctionParamInfoIterator { public: - explicit FuncInfoParamClassIterator( const FunctionInfo& rFuncInfo ); + explicit FunctionParamInfoIterator( const FunctionInfo& rFuncInfo ); - FuncInfoParamClassIterator& operator++(); - - inline sal_uInt8 getParamClass() const { return *mpnParamClass; } - inline sal_uInt8 isExcelOnlyParam() const { return getFlag( *mpnParamClass, FUNCINFO_PARAM_EXCELONLY ); } - inline sal_uInt8 isCalcOnlyParam() const { return getFlag( *mpnParamClass, FUNCINFO_PARAM_CALCONLY ); } + const FunctionParamInfo& getParamInfo() const; + bool isCalcOnlyParam() const; + bool isExcelOnlyParam() const; + FunctionParamInfoIterator& operator++(); private: - const sal_uInt8* mpnParamClass; - const sal_uInt8* mpnParamClassEnd; + const FunctionParamInfo* mpParamInfo; + const FunctionParamInfo* mpParamInfoEnd; + bool mbParamPairs; }; // base function provider ===================================================== diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index f4a53a4a0da0..60cca8754a91 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -1337,6 +1337,7 @@ bool FormulaObject::dumpAttrToken() dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip-err" ); } break; + case 0: // in array formulas and defined names, the skip-bit may be 0 case BIFF_TOK_ATTR_SKIP: dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip" ); break; diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index df9518e92726..48c514b170d2 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -207,6 +207,7 @@ combilist=NLRADDFLAGS end flagslist=ATTRTYPES + 0x00=skip 0x01=volatile 0x02=if 0x04=choose diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index 7ba8af38324b..5240960f7a88 100644 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -227,7 +227,7 @@ void ApiTokenIterator::skipSpaces() namespace { -const size_t FUNCINFO_CLASSCOUNT = 5; /// Number of token class entries. +const size_t FUNCINFO_PARAMINFOCOUNT = 5; /// Number of parameter type entries. const sal_uInt16 FUNCFLAG_VOLATILE = 0x0001; /// Result is volatile (e.g. NOW() function). const sal_uInt16 FUNCFLAG_IMPORTONLY = 0x0002; /// Only used in import filter. @@ -237,6 +237,7 @@ const sal_uInt16 FUNCFLAG_EXTERNAL = 0x0010; /// Function is external const sal_uInt16 FUNCFLAG_MACROFUNC = 0x0020; /// Function is a macro-sheet function. const sal_uInt16 FUNCFLAG_MACROCMD = 0x0040; /// Function is a macro-sheet command. const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0080; /// Function is always represented by a tFuncVar token. +const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0100; /// Optional parameters are expected to appear in pairs. const sal_uInt16 FUNCFLAG_FUNCLIBMASK = 0xF000; /// Mask for function library bits. const sal_uInt16 FUNCFLAG_EUROTOOL = 0x1000; /// Function is part of the EuroTool add-in. @@ -252,7 +253,7 @@ struct FunctionData sal_uInt8 mnMinParamCount; /// Minimum number of parameters. sal_uInt8 mnMaxParamCount; /// Maximum number of parameters. sal_uInt8 mnRetClass; /// BIFF token class of the return value. - sal_uInt8 mpnParamClass[ FUNCINFO_CLASSCOUNT ]; /// Expected BIFF token classes of parameters. + FunctionParamInfo mpParamInfos[ FUNCINFO_PARAMINFOCOUNT ]; /// Information about all parameters. sal_uInt16 mnFlags; /// Additional flags. inline bool isSupported( bool bImportFilter ) const; @@ -265,165 +266,179 @@ inline bool FunctionData::isSupported( bool bImportFilter ) const return !getFlag( mnFlags, bImportFilter ? FUNCFLAG_EXPORTONLY : FUNCFLAG_IMPORTONLY ); } -const sal_uInt8 R = BIFF_TOKCLASS_REF; -const sal_uInt8 V = BIFF_TOKCLASS_VAL; -const sal_uInt8 A = BIFF_TOKCLASS_ARR; -const sal_uInt8 ER = FUNCINFO_PARAM_EXCELONLY | BIFF_TOKCLASS_REF; -const sal_uInt8 EV = FUNCINFO_PARAM_EXCELONLY | BIFF_TOKCLASS_VAL; -const sal_uInt8 EA = FUNCINFO_PARAM_EXCELONLY | BIFF_TOKCLASS_ARR; -const sal_uInt8 C = FUNCINFO_PARAM_CALCONLY; -const sal_uInt8 I = FUNCINFO_PARAM_INVALID; -const sal_uInt16 NOID = SAL_MAX_UINT16; -const sal_uInt8 MX = SAL_MAX_UINT8; +const sal_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF/OOBIN function identifier available. +const sal_uInt8 MX = SAL_MAX_UINT8; /// Maximum parameter count. + +// abbreviations for function return token class +const sal_uInt8 R = BIFF_TOKCLASS_REF; +const sal_uInt8 V = BIFF_TOKCLASS_VAL; +const sal_uInt8 A = BIFF_TOKCLASS_ARR; + +// abbreviations for parameter infos +#define RO { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ORG, false } +#define RV { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_VAL, false } +#define RA { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ARR, false } +#define RR { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPT, false } +#define RX { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPX, false } +#define VO { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ORG, true } +#define VV { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_VAL, true } +#define VA { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ARR, true } +#define VR { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPT, true } +#define VX { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPX, true } +#define RO_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_ORG, false } +#define VR_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_RPT, true } +#define C { FUNC_PARAM_CALCONLY, FUNC_PARAMCONV_ORG, false } + +// Note: parameter types of all macro sheet functions (FUNCFLAG_MACROFUNC/FUNCFLAG_MACROCMD) untested! /** Functions new in BIFF2. */ static const FunctionData saFuncTableBiff2[] = { - { "COUNT", "COUNT", 0, 0, 0, MX, V, { R }, 0 }, - { "IF", "IF", 1, 1, 2, 3, R, { V, R }, 0 }, - { "ISNA", "ISNA", 2, 2, 1, 1, V, { V }, 0 }, - { "ISERROR", "ISERROR", 3, 3, 1, 1, V, { V }, 0 }, - { "SUM", "SUM", 4, 4, 0, MX, V, { R }, 0 }, - { "AVERAGE", "AVERAGE", 5, 5, 1, MX, V, { R }, 0 }, - { "MIN", "MIN", 6, 6, 1, MX, V, { R }, 0 }, - { "MAX", "MAX", 7, 7, 1, MX, V, { R }, 0 }, - { "ROW", "ROW", 8, 8, 0, 1, V, { R }, 0 }, - { "COLUMN", "COLUMN", 9, 9, 0, 1, V, { R }, 0 }, + { "COUNT", "COUNT", 0, 0, 0, MX, V, { RX }, 0 }, + { "IF", "IF", 1, 1, 2, 3, R, { VO, RO }, 0 }, + { "ISNA", "ISNA", 2, 2, 1, 1, V, { VR }, 0 }, + { "ISERROR", "ISERROR", 3, 3, 1, 1, V, { VR }, 0 }, + { "SUM", "SUM", 4, 4, 0, MX, V, { RX }, 0 }, + { "AVERAGE", "AVERAGE", 5, 5, 1, MX, V, { RX }, 0 }, + { "MIN", "MIN", 6, 6, 1, MX, V, { RX }, 0 }, + { "MAX", "MAX", 7, 7, 1, MX, V, { RX }, 0 }, + { "ROW", "ROW", 8, 8, 0, 1, V, { RO }, 0 }, + { "COLUMN", "COLUMN", 9, 9, 0, 1, V, { RO }, 0 }, { "NA", "NA", 10, 10, 0, 0, V, {}, 0 }, - { "NPV", "NPV", 11, 11, 2, MX, V, { V, R }, 0 }, - { "STDEV", "STDEV", 12, 12, 1, MX, V, { R }, 0 }, - { "DOLLAR", "DOLLAR", 13, 13, 1, 2, V, { V }, 0 }, - { "FIXED", "FIXED", 14, 14, 1, 2, V, { V, V, C, I }, 0 }, - { "SIN", "SIN", 15, 15, 1, 1, V, { V }, 0 }, - { "COS", "COS", 16, 16, 1, 1, V, { V }, 0 }, - { "TAN", "TAN", 17, 17, 1, 1, V, { V }, 0 }, - { "COT", 0, 17, 17, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY }, - { "ATAN", "ATAN", 18, 18, 1, 1, V, { V }, 0 }, - { "ACOT", 0, 18, 18, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY }, + { "NPV", "NPV", 11, 11, 2, MX, V, { VR, RX }, 0 }, + { "STDEV", "STDEV", 12, 12, 1, MX, V, { RX }, 0 }, + { "DOLLAR", "DOLLAR", 13, 13, 1, 2, V, { VR }, 0 }, + { "FIXED", "FIXED", 14, 14, 1, 2, V, { VR, VR, C }, 0 }, + { "SIN", "SIN", 15, 15, 1, 1, V, { VR }, 0 }, + { "COS", "COS", 16, 16, 1, 1, V, { VR }, 0 }, + { "TAN", "TAN", 17, 17, 1, 1, V, { VR }, 0 }, + { "COT", "TAN", 17, 17, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, + { "ATAN", "ATAN", 18, 18, 1, 1, V, { VR }, 0 }, + { "ACOT", "ATAN", 18, 18, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "PI", "PI", 19, 19, 0, 0, V, {}, 0 }, - { "SQRT", "SQRT", 20, 20, 1, 1, V, { V }, 0 }, - { "EXP", "EXP", 21, 21, 1, 1, V, { V }, 0 }, - { "LN", "LN", 22, 22, 1, 1, V, { V }, 0 }, - { "LOG10", "LOG10", 23, 23, 1, 1, V, { V }, 0 }, - { "ABS", "ABS", 24, 24, 1, 1, V, { V }, 0 }, - { "INT", "INT", 25, 25, 1, 1, V, { V }, 0 }, - { "SIGN", "SIGN", 26, 26, 1, 1, V, { V }, 0 }, - { "ROUND", "ROUND", 27, 27, 2, 2, V, { V }, 0 }, - { "LOOKUP", "LOOKUP", 28, 28, 2, 3, V, { V, R }, 0 }, - { "INDEX", "INDEX", 29, 29, 2, 4, R, { R, V }, 0 }, - { "REPT", "REPT", 30, 30, 2, 2, V, { V }, 0 }, - { "MID", "MID", 31, 31, 3, 3, V, { V }, 0 }, - { "LEN", "LEN", 32, 32, 1, 1, V, { V }, 0 }, - { "VALUE", "VALUE", 33, 33, 1, 1, V, { V }, 0 }, + { "SQRT", "SQRT", 20, 20, 1, 1, V, { VR }, 0 }, + { "EXP", "EXP", 21, 21, 1, 1, V, { VR }, 0 }, + { "LN", "LN", 22, 22, 1, 1, V, { VR }, 0 }, + { "LOG10", "LOG10", 23, 23, 1, 1, V, { VR }, 0 }, + { "ABS", "ABS", 24, 24, 1, 1, V, { VR }, 0 }, + { "INT", "INT", 25, 25, 1, 1, V, { VR }, 0 }, + { "SIGN", "SIGN", 26, 26, 1, 1, V, { VR }, 0 }, + { "ROUND", "ROUND", 27, 27, 2, 2, V, { VR }, 0 }, + { "LOOKUP", "LOOKUP", 28, 28, 2, 3, V, { VR, RA }, 0 }, + { "INDEX", "INDEX", 29, 29, 2, 4, R, { RA, VV }, 0 }, + { "REPT", "REPT", 30, 30, 2, 2, V, { VR }, 0 }, + { "MID", "MID", 31, 31, 3, 3, V, { VR }, 0 }, + { "LEN", "LEN", 32, 32, 1, 1, V, { VR }, 0 }, + { "VALUE", "VALUE", 33, 33, 1, 1, V, { VR }, 0 }, { "TRUE", "TRUE", 34, 34, 0, 0, V, {}, 0 }, { "FALSE", "FALSE", 35, 35, 0, 0, V, {}, 0 }, - { "AND", "AND", 36, 36, 1, MX, V, { R }, 0 }, - { "OR", "OR", 37, 37, 1, MX, V, { R }, 0 }, - { "NOT", "NOT", 38, 38, 1, 1, V, { V }, 0 }, - { "MOD", "MOD", 39, 39, 2, 2, V, { V }, 0 }, - { "DCOUNT", "DCOUNT", 40, 40, 3, 3, V, { R }, 0 }, - { "DSUM", "DSUM", 41, 41, 3, 3, V, { R }, 0 }, - { "DAVERAGE", "DAVERAGE", 42, 42, 3, 3, V, { R }, 0 }, - { "DMIN", "DMIN", 43, 43, 3, 3, V, { R }, 0 }, - { "DMAX", "DMAX", 44, 44, 3, 3, V, { R }, 0 }, - { "DSTDEV", "DSTDEV", 45, 45, 3, 3, V, { R }, 0 }, - { "VAR", "VAR", 46, 46, 1, MX, V, { R }, 0 }, - { "DVAR", "DVAR", 47, 47, 3, 3, V, { R }, 0 }, - { "TEXT", "TEXT", 48, 48, 2, 2, V, { V }, 0 }, - { "LINEST", "LINEST", 49, 49, 1, 2, A, { R, R, C, C, I }, 0 }, - { "TREND", "TREND", 50, 50, 1, 3, A, { R, R, R, C, I }, 0 }, - { "LOGEST", "LOGEST", 51, 51, 1, 2, A, { R, R, C, C, I }, 0 }, - { "GROWTH", "GROWTH", 52, 52, 1, 3, A, { R, R, R, C, I }, 0 }, - { 0, "RETURN", 55, 55, 0, 1, R, { R }, FUNCFLAG_MACROFUNC }, - { "PV", "PV", 56, 56, 3, 5, V, { V }, 0 }, - { "FV", "FV", 57, 57, 3, 5, V, { V }, 0 }, - { "NPER", "NPER", 58, 58, 3, 5, V, { V }, 0 }, - { "PMT", "PMT", 59, 59, 3, 5, V, { V }, 0 }, - { "RATE", "RATE", 60, 60, 3, 6, V, { V }, 0 }, - { "MIRR", "MIRR", 61, 61, 3, 3, V, { R, V }, 0 }, - { "IRR", "IRR", 62, 62, 1, 2, V, { R, V }, 0 }, + { "AND", "AND", 36, 36, 1, MX, V, { RX }, 0 }, + { "OR", "OR", 37, 37, 1, MX, V, { RX }, 0 }, + { "NOT", "NOT", 38, 38, 1, 1, V, { VR }, 0 }, + { "MOD", "MOD", 39, 39, 2, 2, V, { VR }, 0 }, + { "DCOUNT", "DCOUNT", 40, 40, 3, 3, V, { RO, RR }, 0 }, + { "DSUM", "DSUM", 41, 41, 3, 3, V, { RO, RR }, 0 }, + { "DAVERAGE", "DAVERAGE", 42, 42, 3, 3, V, { RO, RR }, 0 }, + { "DMIN", "DMIN", 43, 43, 3, 3, V, { RO, RR }, 0 }, + { "DMAX", "DMAX", 44, 44, 3, 3, V, { RO, RR }, 0 }, + { "DSTDEV", "DSTDEV", 45, 45, 3, 3, V, { RO, RR }, 0 }, + { "VAR", "VAR", 46, 46, 1, MX, V, { RX }, 0 }, + { "DVAR", "DVAR", 47, 47, 3, 3, V, { RO, RR }, 0 }, + { "TEXT", "TEXT", 48, 48, 2, 2, V, { VR }, 0 }, + { "LINEST", "LINEST", 49, 49, 1, 2, A, { RA, RA, C, C }, 0 }, + { "TREND", "TREND", 50, 50, 1, 3, A, { RA, RA, RA, C }, 0 }, + { "LOGEST", "LOGEST", 51, 51, 1, 2, A, { RA, RA, C, C }, 0 }, + { "GROWTH", "GROWTH", 52, 52, 1, 3, A, { RA, RA, RA, C }, 0 }, + { 0, "RETURN", 55, 55, 0, 1, R, { RO }, FUNCFLAG_MACROFUNC }, + { "PV", "PV", 56, 56, 3, 5, V, { VR }, 0 }, + { "FV", "FV", 57, 57, 3, 5, V, { VR }, 0 }, + { "NPER", "NPER", 58, 58, 3, 5, V, { VR }, 0 }, + { "PMT", "PMT", 59, 59, 3, 5, V, { VR }, 0 }, + { "RATE", "RATE", 60, 60, 3, 6, V, { VR }, 0 }, + { "MIRR", "MIRR", 61, 61, 3, 3, V, { RA, VR }, 0 }, + { "IRR", "IRR", 62, 62, 1, 2, V, { RA, VR }, 0 }, { "RAND", "RAND", 63, 63, 0, 0, V, {}, FUNCFLAG_VOLATILE }, - { "MATCH", "MATCH", 64, 64, 2, 3, V, { V, R }, 0 }, - { "DATE", "DATE", 65, 65, 3, 3, V, { V }, 0 }, - { "TIME", "TIME", 66, 66, 3, 3, V, { V }, 0 }, - { "DAY", "DAY", 67, 67, 1, 1, V, { V }, 0 }, - { "MONTH", "MONTH", 68, 68, 1, 1, V, { V }, 0 }, - { "YEAR", "YEAR", 69, 69, 1, 1, V, { V }, 0 }, - { "WEEKDAY", "WEEKDAY", 70, 70, 1, 1, V, { V, C, I }, 0 }, - { "HOUR", "HOUR", 71, 71, 1, 1, V, { V }, 0 }, - { "MINUTE", "MINUTE", 72, 72, 1, 1, V, { V }, 0 }, - { "SECOND", "SECOND", 73, 73, 1, 1, V, { V }, 0 }, + { "MATCH", "MATCH", 64, 64, 2, 3, V, { VR, RX, RR }, 0 }, + { "DATE", "DATE", 65, 65, 3, 3, V, { VR }, 0 }, + { "TIME", "TIME", 66, 66, 3, 3, V, { VR }, 0 }, + { "DAY", "DAY", 67, 67, 1, 1, V, { VR }, 0 }, + { "MONTH", "MONTH", 68, 68, 1, 1, V, { VR }, 0 }, + { "YEAR", "YEAR", 69, 69, 1, 1, V, { VR }, 0 }, + { "WEEKDAY", "WEEKDAY", 70, 70, 1, 1, V, { VR, C }, 0 }, + { "HOUR", "HOUR", 71, 71, 1, 1, V, { VR }, 0 }, + { "MINUTE", "MINUTE", 72, 72, 1, 1, V, { VR }, 0 }, + { "SECOND", "SECOND", 73, 73, 1, 1, V, { VR }, 0 }, { "NOW", "NOW", 74, 74, 0, 0, V, {}, FUNCFLAG_VOLATILE }, - { "AREAS", "AREAS", 75, 75, 1, 1, V, { R }, 0 }, - { "ROWS", "ROWS", 76, 76, 1, 1, V, { R }, 0 }, - { "COLUMNS", "COLUMNS", 77, 77, 1, 1, V, { R }, 0 }, - { "OFFSET", "OFFSET", 78, 78, 3, 5, R, { R, V }, FUNCFLAG_VOLATILE }, - { 0, "ABSREF", 79, 79, 2, 2, R, { V, R }, FUNCFLAG_MACROFUNC }, - { "SEARCH", "SEARCH", 82, 82, 2, 3, V, { V }, 0 }, - { "TRANSPOSE", "TRANSPOSE", 83, 83, 1, 1, A, { A }, 0 }, - { "TYPE", "TYPE", 86, 86, 1, 1, V, { V }, 0 }, + { "AREAS", "AREAS", 75, 75, 1, 1, V, { RO }, 0 }, + { "ROWS", "ROWS", 76, 76, 1, 1, V, { RO }, 0 }, + { "COLUMNS", "COLUMNS", 77, 77, 1, 1, V, { RO }, 0 }, + { "OFFSET", "OFFSET", 78, 78, 3, 5, R, { RO, VR }, FUNCFLAG_VOLATILE }, + { 0, "ABSREF", 79, 79, 2, 2, R, { VR, RO }, FUNCFLAG_MACROFUNC }, + { "SEARCH", "SEARCH", 82, 82, 2, 3, V, { VR }, 0 }, + { "TRANSPOSE", "TRANSPOSE", 83, 83, 1, 1, A, { VO }, 0 }, + { "TYPE", "TYPE", 86, 86, 1, 1, V, { VX }, 0 }, { 0, "ACTIVE.CELL", 94, 94, 0, 0, R, {}, FUNCFLAG_MACROFUNC }, - { "ATAN2", "ATAN2", 97, 97, 2, 2, V, { V }, 0 }, - { "ASIN", "ASIN", 98, 98, 1, 1, V, { V }, 0 }, - { "ACOS", "ACOS", 99, 99, 1, 1, V, { V }, 0 }, - { "CHOOSE", "CHOOSE", 100, 100, 2, MX, R, { V, R }, 0 }, - { "HLOOKUP", "HLOOKUP", 101, 101, 3, 3, V, { V, R, R, C, I }, 0 }, - { "VLOOKUP", "VLOOKUP", 102, 102, 3, 3, V, { V, R, R, C, I }, 0 }, - { "ISREF", "ISREF", 105, 105, 1, 1, V, { R }, 0 }, - { "LOG", "LOG", 109, 109, 1, 2, V, { V }, 0 }, - { "CHAR", "CHAR", 111, 111, 1, 1, V, { V }, 0 }, - { "LOWER", "LOWER", 112, 112, 1, 1, V, { V }, 0 }, - { "UPPER", "UPPER", 113, 113, 1, 1, V, { V }, 0 }, - { "PROPER", "PROPER", 114, 114, 1, 1, V, { V }, 0 }, - { "LEFT", "LEFT", 115, 115, 1, 2, V, { V }, 0 }, - { "RIGHT", "RIGHT", 116, 116, 1, 2, V, { V }, 0 }, - { "EXACT", "EXACT", 117, 117, 2, 2, V, { V }, 0 }, - { "TRIM", "TRIM", 118, 118, 1, 1, V, { V }, 0 }, - { "REPLACE", "REPLACE", 119, 119, 4, 4, V, { V }, 0 }, - { "SUBSTITUTE", "SUBSTITUTE", 120, 120, 3, 4, V, { V }, 0 }, - { "CODE", "CODE", 121, 121, 1, 1, V, { V }, 0 }, - { "FIND", "FIND", 124, 124, 2, 3, V, { V }, 0 }, - { "CELL", "CELL", 125, 125, 1, 2, V, { V, R }, FUNCFLAG_VOLATILE }, - { "ISERR", "ISERR", 126, 126, 1, 1, V, { V }, 0 }, - { "ISTEXT", "ISTEXT", 127, 127, 1, 1, V, { V }, 0 }, - { "ISNUMBER", "ISNUMBER", 128, 128, 1, 1, V, { V }, 0 }, - { "ISBLANK", "ISBLANK", 129, 129, 1, 1, V, { V }, 0 }, - { "T", "T", 130, 130, 1, 1, V, { R }, 0 }, - { "N", "N", 131, 131, 1, 1, V, { R }, 0 }, - { "DATEVALUE", "DATEVALUE", 140, 140, 1, 1, V, { V }, 0 }, - { "TIMEVALUE", "TIMEVALUE", 141, 141, 1, 1, V, { V }, 0 }, - { "SLN", "SLN", 142, 142, 3, 3, V, { V }, 0 }, - { "SYD", "SYD", 143, 143, 4, 4, V, { V }, 0 }, - { "DDB", "DDB", 144, 144, 4, 5, V, { V }, 0 }, - { "INDIRECT", "INDIRECT", 148, 148, 1, 2, R, { V }, FUNCFLAG_VOLATILE }, + { "ATAN2", "ATAN2", 97, 97, 2, 2, V, { VR }, 0 }, + { "ASIN", "ASIN", 98, 98, 1, 1, V, { VR }, 0 }, + { "ACOS", "ACOS", 99, 99, 1, 1, V, { VR }, 0 }, + { "CHOOSE", "CHOOSE", 100, 100, 2, MX, R, { VO, RO }, 0 }, + { "HLOOKUP", "HLOOKUP", 101, 101, 3, 3, V, { VV, RO, RO, C }, 0 }, + { "VLOOKUP", "VLOOKUP", 102, 102, 3, 3, V, { VV, RO, RO, C }, 0 }, + { "ISREF", "ISREF", 105, 105, 1, 1, V, { RX }, 0 }, + { "LOG", "LOG", 109, 109, 1, 2, V, { VR }, 0 }, + { "CHAR", "CHAR", 111, 111, 1, 1, V, { VR }, 0 }, + { "LOWER", "LOWER", 112, 112, 1, 1, V, { VR }, 0 }, + { "UPPER", "UPPER", 113, 113, 1, 1, V, { VR }, 0 }, + { "PROPER", "PROPER", 114, 114, 1, 1, V, { VR }, 0 }, + { "LEFT", "LEFT", 115, 115, 1, 2, V, { VR }, 0 }, + { "RIGHT", "RIGHT", 116, 116, 1, 2, V, { VR }, 0 }, + { "EXACT", "EXACT", 117, 117, 2, 2, V, { VR }, 0 }, + { "TRIM", "TRIM", 118, 118, 1, 1, V, { VR }, 0 }, + { "REPLACE", "REPLACE", 119, 119, 4, 4, V, { VR }, 0 }, + { "SUBSTITUTE", "SUBSTITUTE", 120, 120, 3, 4, V, { VR }, 0 }, + { "CODE", "CODE", 121, 121, 1, 1, V, { VR }, 0 }, + { "FIND", "FIND", 124, 124, 2, 3, V, { VR }, 0 }, + { "CELL", "CELL", 125, 125, 1, 2, V, { VV, RO }, FUNCFLAG_VOLATILE }, + { "ISERR", "ISERR", 126, 126, 1, 1, V, { VR }, 0 }, + { "ISTEXT", "ISTEXT", 127, 127, 1, 1, V, { VR }, 0 }, + { "ISNUMBER", "ISNUMBER", 128, 128, 1, 1, V, { VR }, 0 }, + { "ISBLANK", "ISBLANK", 129, 129, 1, 1, V, { VR }, 0 }, + { "T", "T", 130, 130, 1, 1, V, { RO }, 0 }, + { "N", "N", 131, 131, 1, 1, V, { RO }, 0 }, + { "DATEVALUE", "DATEVALUE", 140, 140, 1, 1, V, { VR }, 0 }, + { "TIMEVALUE", "TIMEVALUE", 141, 141, 1, 1, V, { VR }, 0 }, + { "SLN", "SLN", 142, 142, 3, 3, V, { VR }, 0 }, + { "SYD", "SYD", 143, 143, 4, 4, V, { VR }, 0 }, + { "DDB", "DDB", 144, 144, 4, 5, V, { VR }, 0 }, + { "INDIRECT", "INDIRECT", 148, 148, 1, 2, R, { VR }, FUNCFLAG_VOLATILE }, { 0, "ADD.BAR", 151, 151, 0, 0, V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, - { 0, "ADD.MENU", 152, 152, 2, 2, V, { V, R }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, - { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { V, R }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, - { "CLEAN", "CLEAN", 162, 162, 1, 1, V, { V }, 0 }, - { "MDETERM", "MDETERM", 163, 163, 1, 1, V, { A }, 0 }, - { "MINVERSE", "MINVERSE", 164, 164, 1, 1, A, { A }, 0 }, - { "MMULT", "MMULT", 165, 165, 2, 2, A, { A }, 0 }, - { "IPMT", "IPMT", 167, 167, 4, 6, V, { V }, 0 }, - { "PPMT", "PPMT", 168, 168, 4, 6, V, { V }, 0 }, - { "COUNTA", "COUNTA", 169, 169, 0, MX, V, { R }, 0 }, - { "PRODUCT", "PRODUCT", 183, 183, 0, MX, V, { R }, 0 }, - { "FACT", "FACT", 184, 184, 1, 1, V, { V }, 0 }, - { "DPRODUCT", "DPRODUCT", 189, 189, 3, 3, V, { R }, 0 }, - { "ISNONTEXT", "ISNONTEXT", 190, 190, 1, 1, V, { V }, 0 }, - { "STDEVP", "STDEVP", 193, 193, 1, MX, V, { R }, 0 }, - { "VARP", "VARP", 194, 194, 1, MX, V, { R }, 0 }, - { "DSTDEVP", "DSTDEVP", 195, 195, 3, 3, V, { R }, 0 }, - { "DVARP", "DVARP", 196, 196, 3, 3, V, { R }, 0 }, - { "TRUNC", "TRUNC", 197, 197, 1, 1, V, { V, C, I }, 0 }, - { "ISLOGICAL", "ISLOGICAL", 198, 198, 1, 1, V, { V }, 0 }, - { "DCOUNTA", "DCOUNTA", 199, 199, 3, 3, V, { R }, 0 }, - { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { ER, R }, FUNCFLAG_IMPORTONLY }, + { 0, "ADD.MENU", 152, 152, 2, 2, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, + { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, + { "CLEAN", "CLEAN", 162, 162, 1, 1, V, { VR }, 0 }, + { "MDETERM", "MDETERM", 163, 163, 1, 1, V, { VA }, 0 }, + { "MINVERSE", "MINVERSE", 164, 164, 1, 1, A, { VA }, 0 }, + { "MMULT", "MMULT", 165, 165, 2, 2, A, { VA }, 0 }, + { "IPMT", "IPMT", 167, 167, 4, 6, V, { VR }, 0 }, + { "PPMT", "PPMT", 168, 168, 4, 6, V, { VR }, 0 }, + { "COUNTA", "COUNTA", 169, 169, 0, MX, V, { RX }, 0 }, + { "PRODUCT", "PRODUCT", 183, 183, 0, MX, V, { RX }, 0 }, + { "FACT", "FACT", 184, 184, 1, 1, V, { VR }, 0 }, + { "DPRODUCT", "DPRODUCT", 189, 189, 3, 3, V, { RO, RR }, 0 }, + { "ISNONTEXT", "ISNONTEXT", 190, 190, 1, 1, V, { VR }, 0 }, + { "STDEVP", "STDEVP", 193, 193, 1, MX, V, { RX }, 0 }, + { "VARP", "VARP", 194, 194, 1, MX, V, { RX }, 0 }, + { "DSTDEVP", "DSTDEVP", 195, 195, 3, 3, V, { RO, RR }, 0 }, + { "DVARP", "DVARP", 196, 196, 3, 3, V, { RO, RR }, 0 }, + { "TRUNC", "TRUNC", 197, 197, 1, 1, V, { VR, C }, 0 }, + { "ISLOGICAL", "ISLOGICAL", 198, 198, 1, 1, V, { VR }, 0 }, + { "DCOUNTA", "DCOUNTA", 199, 199, 3, 3, V, { RO, RR }, 0 }, + { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_IMPORTONLY }, // *** macro sheet commands *** - { 0, "A1.R1C1", 30, 30, 0, 1, V, { V }, FUNCFLAG_MACROCMD }, + { 0, "A1.R1C1", 30, 30, 0, 1, V, { VR }, FUNCFLAG_MACROCMD }, { 0, "ADD.ARROW", 81, 81, 0, 0, V, {}, FUNCFLAG_MACROCMD }, - { 0, "ACTIVATE", 103, 103, 0, 2, V, { V }, FUNCFLAG_MACROCMD }, + { 0, "ACTIVATE", 103, 103, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, { 0, "ACTIVATE.NEXT", 104, 104, 0, 0, V, {}, FUNCFLAG_MACROCMD }, { 0, "ACTIVATE.PREV", 105, 105, 0, 0, V, {}, FUNCFLAG_MACROCMD } }; @@ -431,336 +446,336 @@ static const FunctionData saFuncTableBiff2[] = /** Functions new in BIFF3. */ static const FunctionData saFuncTableBiff3[] = { - { "LINEST", "LINEST", 49, 49, 1, 4, A, { R, R, V, V }, 0 }, // BIFF2: 1-2, BIFF3: 1-4 - { "TREND", "TREND", 50, 50, 1, 4, A, { R, R, R, V }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 - { "LOGEST", "LOGEST", 51, 51, 1, 4, A, { R, R, V, V }, 0 }, // BIFF2: 1-2, BIFF3: 1-4 - { "GROWTH", "GROWTH", 52, 52, 1, 4, A, { R, R, R, V }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 - { 0, "ADD.BAR", 151, 151, 0, 1, V, { V }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1 - { 0, "ADD.MENU", 152, 152, 2, 3, V, { V, R }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3 - { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { V, R }, FUNCFLAG_MACROFUNC }, // BIFF2: 3, BIFF3: 3-4 - { "TRUNC", "TRUNC", 197, 197, 1, 2, V, { V }, 0 }, // BIFF2: 1, BIFF3: 1-2 - { "DOLLAR", "USDOLLAR", 204, 204, 1, 2, V, { V }, FUNCFLAG_IMPORTONLY }, - { 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { V }, 0 }, - { 0/*"SEARCH"*/, "SEARCHB", 206, 206, 2, 3, V, { V }, 0 }, - { 0/*"REPLACE"*/, "REPLACEB", 207, 207, 4, 4, V, { V }, 0 }, - { 0/*"LEFT"*/, "LEFTB", 208, 208, 1, 2, V, { V }, 0 }, - { 0/*"RIGHT"*/, "RIGHTB", 209, 209, 1, 2, V, { V }, 0 }, - { 0/*"MID"*/, "MIDB", 210, 210, 3, 3, V, { V }, 0 }, - { 0/*"LEN"*/, "LENB", 211, 211, 1, 1, V, { V }, 0 }, - { "ROUNDUP", "ROUNDUP", 212, 212, 2, 2, V, { V }, 0 }, - { "ROUNDDOWN", "ROUNDDOWN", 213, 213, 2, 2, V, { V }, 0 }, - { "ASC", "ASC", 214, 214, 1, 1, V, { V }, 0 }, - { "JIS", "DBCS", 215, 215, 1, 1, V, { V }, 0 }, - { "ADDRESS", "ADDRESS", 219, 219, 2, 5, V, { V }, 0 }, - { "DAYS360", "DAYS360", 220, 220, 2, 2, V, { V, V, C, I }, 0 }, + { "LINEST", "LINEST", 49, 49, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4 + { "TREND", "TREND", 50, 50, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 + { "LOGEST", "LOGEST", 51, 51, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4 + { "GROWTH", "GROWTH", 52, 52, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 + { 0, "ADD.BAR", 151, 151, 0, 1, V, { VR }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1 + { 0, "ADD.MENU", 152, 152, 2, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3 + { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 3, BIFF3: 3-4 + { "TRUNC", "TRUNC", 197, 197, 1, 2, V, { VR }, 0 }, // BIFF2: 1, BIFF3: 1-2 + { "DOLLAR", "USDOLLAR", 204, 204, 1, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, + { 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { VR }, 0 }, + { 0/*"SEARCH"*/, "SEARCHB", 206, 206, 2, 3, V, { VR }, 0 }, + { 0/*"REPLACE"*/, "REPLACEB", 207, 207, 4, 4, V, { VR }, 0 }, + { 0/*"LEFT"*/, "LEFTB", 208, 208, 1, 2, V, { VR }, 0 }, + { 0/*"RIGHT"*/, "RIGHTB", 209, 209, 1, 2, V, { VR }, 0 }, + { 0/*"MID"*/, "MIDB", 210, 210, 3, 3, V, { VR }, 0 }, + { 0/*"LEN"*/, "LENB", 211, 211, 1, 1, V, { VR }, 0 }, + { "ROUNDUP", "ROUNDUP", 212, 212, 2, 2, V, { VR }, 0 }, + { "ROUNDDOWN", "ROUNDDOWN", 213, 213, 2, 2, V, { VR }, 0 }, + { "ASC", "ASC", 214, 214, 1, 1, V, { VR }, 0 }, + { "JIS", "DBCS", 215, 215, 1, 1, V, { VR }, 0 }, + { "ADDRESS", "ADDRESS", 219, 219, 2, 5, V, { VR }, 0 }, + { "DAYS360", "DAYS360", 220, 220, 2, 2, V, { VR, VR, C }, 0 }, { "TODAY", "TODAY", 221, 221, 0, 0, V, {}, FUNCFLAG_VOLATILE }, - { "VDB", "VDB", 222, 222, 5, 7, V, { V }, 0 }, - { "MEDIAN", "MEDIAN", 227, 227, 1, MX, V, { R }, 0 }, - { "SUMPRODUCT", "SUMPRODUCT", 228, 228, 1, MX, V, { A }, 0 }, - { "SINH", "SINH", 229, 229, 1, 1, V, { V }, 0 }, - { "COSH", "COSH", 230, 230, 1, 1, V, { V }, 0 }, - { "TANH", "TANH", 231, 231, 1, 1, V, { V }, 0 }, - { "COTH", 0, 231, 231, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY }, - { "ASINH", "ASINH", 232, 232, 1, 1, V, { V }, 0 }, - { "ACOSH", "ACOSH", 233, 233, 1, 1, V, { V }, 0 }, - { "ATANH", "ATANH", 234, 234, 1, 1, V, { V }, 0 }, - { "ACOTH", 0, 234, 234, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY }, - { "DGET", "DGET", 235, 235, 3, 3, V, { R }, 0 }, - { "INFO", "INFO", 244, 244, 1, 1, V, { V }, FUNCFLAG_VOLATILE } + { "VDB", "VDB", 222, 222, 5, 7, V, { VR }, 0 }, + { "MEDIAN", "MEDIAN", 227, 227, 1, MX, V, { RX }, 0 }, + { "SUMPRODUCT", "SUMPRODUCT", 228, 228, 1, MX, V, { VA }, 0 }, + { "SINH", "SINH", 229, 229, 1, 1, V, { VR }, 0 }, + { "COSH", "COSH", 230, 230, 1, 1, V, { VR }, 0 }, + { "TANH", "TANH", 231, 231, 1, 1, V, { VR }, 0 }, + { "COTH", "TANH", 231, 231, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, + { "ASINH", "ASINH", 232, 232, 1, 1, V, { VR }, 0 }, + { "ACOSH", "ACOSH", 233, 233, 1, 1, V, { VR }, 0 }, + { "ATANH", "ATANH", 234, 234, 1, 1, V, { VR }, 0 }, + { "ACOTH", "ATANH", 234, 234, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, + { "DGET", "DGET", 235, 235, 3, 3, V, { RO, RR }, 0 }, + { "INFO", "INFO", 244, 244, 1, 1, V, { VR }, FUNCFLAG_VOLATILE } }; /** Functions new in BIFF4. */ static const FunctionData saFuncTableBiff4[] = { - { "FIXED", "FIXED", 14, 14, 1, 3, V, { V }, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3 - { "RANK", "RANK", 216, 216, 2, 3, V, { V, R, V }, 0 }, - { "DB", "DB", 247, 247, 4, 5, V, { V }, 0 }, - { "FREQUENCY", "FREQUENCY", 252, 252, 2, 2, A, { R }, 0 }, - { "ORG.OPENOFFICE.ERRORTYPE","ERROR.TYPE", 261, 261, 1, 1, V, { V }, 0 }, - { "AVEDEV", "AVEDEV", 269, 269, 1, MX, V, { R }, 0 }, - { "BETADIST", "BETADIST", 270, 270, 3, 5, V, { V }, 0 }, - { "GAMMALN", "GAMMALN", 271, 271, 1, 1, V, { V }, 0 }, - { "BETAINV", "BETAINV", 272, 272, 3, 5, V, { V }, 0 }, - { "BINOMDIST", "BINOMDIST", 273, 273, 4, 4, V, { V }, 0 }, - { "LEGACY.CHIDIST", "CHIDIST", 274, 274, 2, 2, V, { V }, 0 }, - { "LEGACY.CHIINV", "CHIINV", 275, 275, 2, 2, V, { V }, 0 }, - { "COMBIN", "COMBIN", 276, 276, 2, 2, V, { V }, 0 }, - { "CONFIDENCE", "CONFIDENCE", 277, 277, 3, 3, V, { V }, 0 }, - { "CRITBINOM", "CRITBINOM", 278, 278, 3, 3, V, { V }, 0 }, - { "EVEN", "EVEN", 279, 279, 1, 1, V, { V }, 0 }, - { "EXPONDIST", "EXPONDIST", 280, 280, 3, 3, V, { V }, 0 }, - { "LEGACY.FDIST", "FDIST", 281, 281, 3, 3, V, { V }, 0 }, - { "LEGACY.FINV", "FINV", 282, 282, 3, 3, V, { V }, 0 }, - { "FISHER", "FISHER", 283, 283, 1, 1, V, { V }, 0 }, - { "FISHERINV", "FISHERINV", 284, 284, 1, 1, V, { V }, 0 }, - { "FLOOR", "FLOOR", 285, 285, 2, 2, V, { V, V, C, I }, 0 }, - { "GAMMADIST", "GAMMADIST", 286, 286, 4, 4, V, { V }, 0 }, - { "GAMMAINV", "GAMMAINV", 287, 287, 3, 3, V, { V }, 0 }, - { "CEILING", "CEILING", 288, 288, 2, 2, V, { V, V, C, I }, 0 }, - { "HYPGEOMDIST", "HYPGEOMDIST", 289, 289, 4, 4, V, { V }, 0 }, - { "LOGNORMDIST", "LOGNORMDIST", 290, 290, 3, 3, V, { V }, 0 }, - { "LOGINV", "LOGINV", 291, 291, 3, 3, V, { V }, 0 }, - { "NEGBINOMDIST", "NEGBINOMDIST", 292, 292, 3, 3, V, { V }, 0 }, - { "NORMDIST", "NORMDIST", 293, 293, 4, 4, V, { V }, 0 }, - { "LEGACY.NORMSDIST", "NORMSDIST", 294, 294, 1, 1, V, { V }, 0 }, - { "NORMINV", "NORMINV", 295, 295, 3, 3, V, { V }, 0 }, - { "LEGACY.NORMSINV", "NORMSINV", 296, 296, 1, 1, V, { V }, 0 }, - { "STANDARDIZE", "STANDARDIZE", 297, 297, 3, 3, V, { V }, 0 }, - { "ODD", "ODD", 298, 298, 1, 1, V, { V }, 0 }, - { "PERMUT", "PERMUT", 299, 299, 2, 2, V, { V }, 0 }, - { "POISSON", "POISSON", 300, 300, 3, 3, V, { V }, 0 }, - { "TDIST", "TDIST", 301, 301, 3, 3, V, { V }, 0 }, - { "WEIBULL", "WEIBULL", 302, 302, 4, 4, V, { V }, 0 }, - { "SUMXMY2", "SUMXMY2", 303, 303, 2, 2, V, { A }, 0 }, - { "SUMX2MY2", "SUMX2MY2", 304, 304, 2, 2, V, { A }, 0 }, - { "SUMX2PY2", "SUMX2PY2", 305, 305, 2, 2, V, { A }, 0 }, - { "LEGACY.CHITEST", "CHITEST", 306, 306, 2, 2, V, { A }, 0 }, - { "CORREL", "CORREL", 307, 307, 2, 2, V, { A }, 0 }, - { "COVAR", "COVAR", 308, 308, 2, 2, V, { A }, 0 }, - { "FORECAST", "FORECAST", 309, 309, 3, 3, V, { V, A }, 0 }, - { "FTEST", "FTEST", 310, 310, 2, 2, V, { A }, 0 }, - { "INTERCEPT", "INTERCEPT", 311, 311, 2, 2, V, { A }, 0 }, - { "PEARSON", "PEARSON", 312, 312, 2, 2, V, { A }, 0 }, - { "RSQ", "RSQ", 313, 313, 2, 2, V, { A }, 0 }, - { "STEYX", "STEYX", 314, 314, 2, 2, V, { A }, 0 }, - { "SLOPE", "SLOPE", 315, 315, 2, 2, V, { A }, 0 }, - { "TTEST", "TTEST", 316, 316, 4, 4, V, { A, A, V }, 0 }, - { "PROB", "PROB", 317, 317, 3, 4, V, { A, A, V }, 0 }, - { "DEVSQ", "DEVSQ", 318, 318, 1, MX, V, { R }, 0 }, - { "GEOMEAN", "GEOMEAN", 319, 319, 1, MX, V, { R }, 0 }, - { "HARMEAN", "HARMEAN", 320, 320, 1, MX, V, { R }, 0 }, - { "SUMSQ", "SUMSQ", 321, 321, 0, MX, V, { R }, 0 }, - { "KURT", "KURT", 322, 322, 1, MX, V, { R }, 0 }, - { "SKEW", "SKEW", 323, 323, 1, MX, V, { R }, 0 }, - { "ZTEST", "ZTEST", 324, 324, 2, 3, V, { R, V }, 0 }, - { "LARGE", "LARGE", 325, 325, 2, 2, V, { R, V }, 0 }, - { "SMALL", "SMALL", 326, 326, 2, 2, V, { R, V }, 0 }, - { "QUARTILE", "QUARTILE", 327, 327, 2, 2, V, { R, V }, 0 }, - { "PERCENTILE", "PERCENTILE", 328, 328, 2, 2, V, { R, V }, 0 }, - { "PERCENTRANK", "PERCENTRANK", 329, 329, 2, 3, V, { R, V, EV, I }, 0 }, - { "MODE", "MODE", 330, 330, 1, MX, V, { A }, 0 }, - { "TRIMMEAN", "TRIMMEAN", 331, 331, 2, 2, V, { R, V }, 0 }, - { "TINV", "TINV", 332, 332, 2, 2, V, { V }, 0 }, + { "FIXED", "FIXED", 14, 14, 1, 3, V, { VR }, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3 + { "RANK", "RANK", 216, 216, 2, 3, V, { VR, RO, VR }, 0 }, + { "DB", "DB", 247, 247, 4, 5, V, { VR }, 0 }, + { "FREQUENCY", "FREQUENCY", 252, 252, 2, 2, A, { RA }, 0 }, + { "ORG.OPENOFFICE.ERRORTYPE","ERROR.TYPE", 261, 261, 1, 1, V, { VR }, 0 }, + { "AVEDEV", "AVEDEV", 269, 269, 1, MX, V, { RX }, 0 }, + { "BETADIST", "BETADIST", 270, 270, 3, 5, V, { VR }, 0 }, + { "GAMMALN", "GAMMALN", 271, 271, 1, 1, V, { VR }, 0 }, + { "BETAINV", "BETAINV", 272, 272, 3, 5, V, { VR }, 0 }, + { "BINOMDIST", "BINOMDIST", 273, 273, 4, 4, V, { VR }, 0 }, + { "LEGACY.CHIDIST", "CHIDIST", 274, 274, 2, 2, V, { VR }, 0 }, + { "LEGACY.CHIINV", "CHIINV", 275, 275, 2, 2, V, { VR }, 0 }, + { "COMBIN", "COMBIN", 276, 276, 2, 2, V, { VR }, 0 }, + { "CONFIDENCE", "CONFIDENCE", 277, 277, 3, 3, V, { VR }, 0 }, + { "CRITBINOM", "CRITBINOM", 278, 278, 3, 3, V, { VR }, 0 }, + { "EVEN", "EVEN", 279, 279, 1, 1, V, { VR }, 0 }, + { "EXPONDIST", "EXPONDIST", 280, 280, 3, 3, V, { VR }, 0 }, + { "LEGACY.FDIST", "FDIST", 281, 281, 3, 3, V, { VR }, 0 }, + { "LEGACY.FINV", "FINV", 282, 282, 3, 3, V, { VR }, 0 }, + { "FISHER", "FISHER", 283, 283, 1, 1, V, { VR }, 0 }, + { "FISHERINV", "FISHERINV", 284, 284, 1, 1, V, { VR }, 0 }, + { "FLOOR", "FLOOR", 285, 285, 2, 2, V, { VR, VR, C }, 0 }, + { "GAMMADIST", "GAMMADIST", 286, 286, 4, 4, V, { VR }, 0 }, + { "GAMMAINV", "GAMMAINV", 287, 287, 3, 3, V, { VR }, 0 }, + { "CEILING", "CEILING", 288, 288, 2, 2, V, { VR, VR, C }, 0 }, + { "HYPGEOMDIST", "HYPGEOMDIST", 289, 289, 4, 4, V, { VR }, 0 }, + { "LOGNORMDIST", "LOGNORMDIST", 290, 290, 3, 3, V, { VR }, 0 }, + { "LOGINV", "LOGINV", 291, 291, 3, 3, V, { VR }, 0 }, + { "NEGBINOMDIST", "NEGBINOMDIST", 292, 292, 3, 3, V, { VR }, 0 }, + { "NORMDIST", "NORMDIST", 293, 293, 4, 4, V, { VR }, 0 }, + { "LEGACY.NORMSDIST", "NORMSDIST", 294, 294, 1, 1, V, { VR }, 0 }, + { "NORMINV", "NORMINV", 295, 295, 3, 3, V, { VR }, 0 }, + { "LEGACY.NORMSINV", "NORMSINV", 296, 296, 1, 1, V, { VR }, 0 }, + { "STANDARDIZE", "STANDARDIZE", 297, 297, 3, 3, V, { VR }, 0 }, + { "ODD", "ODD", 298, 298, 1, 1, V, { VR }, 0 }, + { "PERMUT", "PERMUT", 299, 299, 2, 2, V, { VR }, 0 }, + { "POISSON", "POISSON", 300, 300, 3, 3, V, { VR }, 0 }, + { "TDIST", "TDIST", 301, 301, 3, 3, V, { VR }, 0 }, + { "WEIBULL", "WEIBULL", 302, 302, 4, 4, V, { VR }, 0 }, + { "SUMXMY2", "SUMXMY2", 303, 303, 2, 2, V, { VA }, 0 }, + { "SUMX2MY2", "SUMX2MY2", 304, 304, 2, 2, V, { VA }, 0 }, + { "SUMX2PY2", "SUMX2PY2", 305, 305, 2, 2, V, { VA }, 0 }, + { "LEGACY.CHITEST", "CHITEST", 306, 306, 2, 2, V, { VA }, 0 }, + { "CORREL", "CORREL", 307, 307, 2, 2, V, { VA }, 0 }, + { "COVAR", "COVAR", 308, 308, 2, 2, V, { VA }, 0 }, + { "FORECAST", "FORECAST", 309, 309, 3, 3, V, { VR, VA }, 0 }, + { "FTEST", "FTEST", 310, 310, 2, 2, V, { VA }, 0 }, + { "INTERCEPT", "INTERCEPT", 311, 311, 2, 2, V, { VA }, 0 }, + { "PEARSON", "PEARSON", 312, 312, 2, 2, V, { VA }, 0 }, + { "RSQ", "RSQ", 313, 313, 2, 2, V, { VA }, 0 }, + { "STEYX", "STEYX", 314, 314, 2, 2, V, { VA }, 0 }, + { "SLOPE", "SLOPE", 315, 315, 2, 2, V, { VA }, 0 }, + { "TTEST", "TTEST", 316, 316, 4, 4, V, { VA, VA, VR }, 0 }, + { "PROB", "PROB", 317, 317, 3, 4, V, { VA, VA, VR }, 0 }, + { "DEVSQ", "DEVSQ", 318, 318, 1, MX, V, { RX }, 0 }, + { "GEOMEAN", "GEOMEAN", 319, 319, 1, MX, V, { RX }, 0 }, + { "HARMEAN", "HARMEAN", 320, 320, 1, MX, V, { RX }, 0 }, + { "SUMSQ", "SUMSQ", 321, 321, 0, MX, V, { RX }, 0 }, + { "KURT", "KURT", 322, 322, 1, MX, V, { RX }, 0 }, + { "SKEW", "SKEW", 323, 323, 1, MX, V, { RX }, 0 }, + { "ZTEST", "ZTEST", 324, 324, 2, 3, V, { RX, VR }, 0 }, + { "LARGE", "LARGE", 325, 325, 2, 2, V, { RX, VR }, 0 }, + { "SMALL", "SMALL", 326, 326, 2, 2, V, { RX, VR }, 0 }, + { "QUARTILE", "QUARTILE", 327, 327, 2, 2, V, { RX, VR }, 0 }, + { "PERCENTILE", "PERCENTILE", 328, 328, 2, 2, V, { RX, VR }, 0 }, + { "PERCENTRANK", "PERCENTRANK", 329, 329, 2, 3, V, { RX, VR, VR_E }, 0 }, + { "MODE", "MODE", 330, 330, 1, MX, V, { VA }, 0 }, + { "TRIMMEAN", "TRIMMEAN", 331, 331, 2, 2, V, { RX, VR }, 0 }, + { "TINV", "TINV", 332, 332, 2, 2, V, { VR }, 0 }, // *** Analysis add-in *** - { "HEX2BIN", "HEX2BIN", 384, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "HEX2DEC", "HEX2DEC", 385, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "HEX2OCT", "HEX2OCT", 386, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "DEC2BIN", "DEC2BIN", 387, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "DEC2HEX", "DEC2HEX", 388, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "DEC2OCT", "DEC2OCT", 389, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "OCT2BIN", "OCT2BIN", 390, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "OCT2HEX", "OCT2HEX", 391, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "OCT2DEC", "OCT2DEC", 392, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "BIN2DEC", "BIN2DEC", 393, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "BIN2OCT", "BIN2OCT", 394, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "BIN2HEX", "BIN2HEX", 395, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMSUB", "IMSUB", 396, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMDIV", "IMDIV", 397, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMPOWER", "IMPOWER", 398, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMABS", "IMABS", 399, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMSQRT", "IMSQRT", 400, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMLN", "IMLN", 401, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMLOG2", "IMLOG2", 402, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMLOG10", "IMLOG10", 403, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMSIN", "IMSIN", 404, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMCOS", "IMCOS", 405, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMEXP", "IMEXP", 406, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMARGUMENT", "IMARGUMENT", 407, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMCONJUGATE", "IMCONJUGATE", 408, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMAGINARY", "IMAGINARY", 409, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMREAL", "IMREAL", 410, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "COMPLEX", "COMPLEX", 411, NOID, 2, 3, V, { V }, FUNCFLAG_EXTERNAL }, - { "IMSUM", "IMSUM", 412, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL }, - { "IMPRODUCT", "IMPRODUCT", 413, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL }, - { "SERIESSUM", "SERIESSUM", 414, NOID, 4, 4, V, { V, V, V, R }, FUNCFLAG_EXTERNAL }, - { "FACTDOUBLE", "FACTDOUBLE", 415, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "SQRTPI", "SQRTPI", 416, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "QUOTIENT", "QUOTIENT", 417, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "DELTA", "DELTA", 418, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "GESTEP", "GESTEP", 419, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "ISEVEN", "ISEVEN", 420, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "ISODD", "ISODD", 421, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "MROUND", "MROUND", 422, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "ERF", "ERF", 423, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "ERFC", "ERFC", 424, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, - { "BESSELJ", "BESSELJ", 425, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "BESSELK", "BESSELK", 426, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "BESSELY", "BESSELY", 427, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "BESSELI", "BESSELI", 428, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "XIRR", "XIRR", 429, NOID, 2, 3, V, { A, R, V }, FUNCFLAG_EXTERNAL }, - { "XNPV", "XNPV", 430, NOID, 3, 3, V, { V, A, R }, FUNCFLAG_EXTERNAL }, - { "PRICEMAT", "PRICEMAT", 431, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL }, - { "YIELDMAT", "YIELDMAT", 432, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL }, - { "INTRATE", "INTRATE", 433, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL }, - { "RECEIVED", "RECEIVED", 434, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL }, - { "DISC", "DISC", 435, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL }, - { "PRICEDISC", "PRICEDISC", 436, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL }, - { "YIELDDISC", "YIELDDISC", 437, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL }, - { "TBILLEQ", "TBILLEQ", 438, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL }, - { "TBILLPRICE", "TBILLPRICE", 439, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL }, - { "TBILLYIELD", "TBILLYIELD", 440, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL }, - { "PRICE", "PRICE", 441, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL }, - { "YIELD", "YIELD", 442, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL }, - { "DOLLARDE", "DOLLARDE", 443, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "DOLLARFR", "DOLLARFR", 444, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "NOMINAL", "NOMINAL", 445, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "EFFECT", "EFFECT", 446, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "CUMPRINC", "CUMPRINC", 447, NOID, 6, 6, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "CUMIPMT", "CUMIPMT", 448, NOID, 6, 6, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "EDATE", "EDATE", 449, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "EOMONTH", "EOMONTH", 450, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "YEARFRAC", "YEARFRAC", 451, NOID, 2, 3, V, { V }, FUNCFLAG_EXTERNAL }, - { "COUPDAYBS", "COUPDAYBS", 452, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL }, - { "COUPDAYS", "COUPDAYS", 453, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL }, - { "COUPDAYSNC", "COUPDAYSNC", 454, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL }, - { "COUPNCD", "COUPNCD", 455, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL }, - { "COUPNUM", "COUPNUM", 456, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL }, - { "COUPPCD", "COUPPCD", 457, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL }, - { "DURATION", "DURATION", 458, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "MDURATION", "MDURATION", 459, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL }, - { "ODDLPRICE", "ODDLPRICE", 460, NOID, 7, 8, V, { V }, FUNCFLAG_EXTERNAL }, - { "ODDLYIELD", "ODDLYIELD", 461, NOID, 8, 9, V, { V }, FUNCFLAG_EXTERNAL }, - { "ODDFPRICE", "ODDFPRICE", 462, NOID, 8, 9, V, { V }, FUNCFLAG_EXTERNAL }, - { "ODDFYIELD", "ODDFYIELD", 463, NOID, 8, 9, V, { V }, FUNCFLAG_EXTERNAL }, - { "RANDBETWEEN", "RANDBETWEEN", 464, NOID, 2, 2, V, {}, FUNCFLAG_VOLATILE | FUNCFLAG_EXTERNAL }, - { "WEEKNUM", "WEEKNUM", 465, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL }, - { "AMORDEGRC", "AMORDEGRC", 466, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL }, - { "AMORLINC", "AMORLINC", 467, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL }, - { "CONVERT", "CONVERT", 468, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "ACCRINT", "ACCRINT", 469, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL }, - { "ACCRINTM", "ACCRINTM", 470, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL }, - { "WORKDAY", "WORKDAY", 471, NOID, 2, 3, V, { V, V, A, C, I }, FUNCFLAG_EXTERNAL }, - { "NETWORKDAYS", "NETWORKDAYS", 472, NOID, 2, 3, V, { V, V, A, C, I }, FUNCFLAG_EXTERNAL }, - { "GCD", "GCD", 473, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "MULTINOMIAL", "MULTINOMIAL", 474, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL }, - { "LCM", "LCM", 475, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in - { "FVSCHEDULE", "FVSCHEDULE", 476, NOID, 2, 2, V, { V, A }, FUNCFLAG_EXTERNAL }, + { "HEX2BIN", "HEX2BIN", 384, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "HEX2DEC", "HEX2DEC", 385, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "HEX2OCT", "HEX2OCT", 386, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DEC2BIN", "DEC2BIN", 387, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DEC2HEX", "DEC2HEX", 388, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DEC2OCT", "DEC2OCT", 389, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "OCT2BIN", "OCT2BIN", 390, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "OCT2HEX", "OCT2HEX", 391, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "OCT2DEC", "OCT2DEC", 392, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "BIN2DEC", "BIN2DEC", 393, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "BIN2OCT", "BIN2OCT", 394, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "BIN2HEX", "BIN2HEX", 395, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMSUB", "IMSUB", 396, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMDIV", "IMDIV", 397, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMPOWER", "IMPOWER", 398, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMABS", "IMABS", 399, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMSQRT", "IMSQRT", 400, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMLN", "IMLN", 401, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMLOG2", "IMLOG2", 402, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMLOG10", "IMLOG10", 403, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMSIN", "IMSIN", 404, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMCOS", "IMCOS", 405, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMEXP", "IMEXP", 406, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMARGUMENT", "IMARGUMENT", 407, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMCONJUGATE", "IMCONJUGATE", 408, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMAGINARY", "IMAGINARY", 409, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMREAL", "IMREAL", 410, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "COMPLEX", "COMPLEX", 411, NOID, 2, 3, V, { RR }, FUNCFLAG_EXTERNAL }, + { "IMSUM", "IMSUM", 412, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, + { "IMPRODUCT", "IMPRODUCT", 413, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, + { "SERIESSUM", "SERIESSUM", 414, NOID, 4, 4, V, { RR, RR, RR, RX }, FUNCFLAG_EXTERNAL }, + { "FACTDOUBLE", "FACTDOUBLE", 415, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "SQRTPI", "SQRTPI", 416, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "QUOTIENT", "QUOTIENT", 417, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DELTA", "DELTA", 418, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "GESTEP", "GESTEP", 419, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ISEVEN", "ISEVEN", 420, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "ISODD", "ISODD", 421, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "MROUND", "MROUND", 422, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ERF", "ERF", 423, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ERFC", "ERFC", 424, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, + { "BESSELJ", "BESSELJ", 425, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "BESSELK", "BESSELK", 426, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "BESSELY", "BESSELY", 427, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "BESSELI", "BESSELI", 428, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "XIRR", "XIRR", 429, NOID, 2, 3, V, { RX, RX, RR }, FUNCFLAG_EXTERNAL }, + { "XNPV", "XNPV", 430, NOID, 3, 3, V, { RR, RX, RX }, FUNCFLAG_EXTERNAL }, + { "PRICEMAT", "PRICEMAT", 431, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, + { "YIELDMAT", "YIELDMAT", 432, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, + { "INTRATE", "INTRATE", 433, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, + { "RECEIVED", "RECEIVED", 434, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DISC", "DISC", 435, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, + { "PRICEDISC", "PRICEDISC", 436, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, + { "YIELDDISC", "YIELDDISC", 437, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, + { "TBILLEQ", "TBILLEQ", 438, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, + { "TBILLPRICE", "TBILLPRICE", 439, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, + { "TBILLYIELD", "TBILLYIELD", 440, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, + { "PRICE", "PRICE", 441, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, + { "YIELD", "YIELD", 442, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DOLLARDE", "DOLLARDE", 443, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DOLLARFR", "DOLLARFR", 444, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "NOMINAL", "NOMINAL", 445, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "EFFECT", "EFFECT", 446, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "CUMPRINC", "CUMPRINC", 447, NOID, 6, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "CUMIPMT", "CUMIPMT", 448, NOID, 6, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "EDATE", "EDATE", 449, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "EOMONTH", "EOMONTH", 450, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "YEARFRAC", "YEARFRAC", 451, NOID, 2, 3, V, { RR }, FUNCFLAG_EXTERNAL }, + { "COUPDAYBS", "COUPDAYBS", 452, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, + { "COUPDAYS", "COUPDAYS", 453, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, + { "COUPDAYSNC", "COUPDAYSNC", 454, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, + { "COUPNCD", "COUPNCD", 455, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, + { "COUPNUM", "COUPNUM", 456, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, + { "COUPPCD", "COUPPCD", 457, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, + { "DURATION", "DURATION", 458, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "MDURATION", "MDURATION", 459, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ODDLPRICE", "ODDLPRICE", 460, NOID, 7, 8, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ODDLYIELD", "ODDLYIELD", 461, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ODDFPRICE", "ODDFPRICE", 462, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ODDFYIELD", "ODDFYIELD", 463, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL }, + { "RANDBETWEEN", "RANDBETWEEN", 464, NOID, 2, 2, V, { RR }, FUNCFLAG_VOLATILE | FUNCFLAG_EXTERNAL }, + { "WEEKNUM", "WEEKNUM", 465, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, + { "AMORDEGRC", "AMORDEGRC", 466, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, + { "AMORLINC", "AMORLINC", 467, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, + { "CONVERT", "CONVERT", 468, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "ACCRINT", "ACCRINT", 469, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, + { "ACCRINTM", "ACCRINTM", 470, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, + { "WORKDAY", "WORKDAY", 471, NOID, 2, 3, V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL }, + { "NETWORKDAYS", "NETWORKDAYS", 472, NOID, 2, 3, V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL }, + { "GCD", "GCD", 473, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "MULTINOMIAL", "MULTINOMIAL", 474, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, + { "LCM", "LCM", 475, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in + { "FVSCHEDULE", "FVSCHEDULE", 476, NOID, 2, 2, V, { RR, RX }, FUNCFLAG_EXTERNAL }, // *** macro sheet commands *** - { 0, "ACTIVATE.NEXT", 104, 104, 0, 1, V, { V }, FUNCFLAG_MACROCMD }, // BIFF2-3: 0, BIFF4: 0-1 - { 0, "ACTIVATE.PREV", 105, 105, 0, 1, V, { V }, FUNCFLAG_MACROCMD } // BIFF2-3: 0, BIFF4: 0-1 + { 0, "ACTIVATE.NEXT", 104, 104, 0, 1, V, { VR }, FUNCFLAG_MACROCMD }, // BIFF2-3: 0, BIFF4: 0-1 + { 0, "ACTIVATE.PREV", 105, 105, 0, 1, V, { VR }, FUNCFLAG_MACROCMD } // BIFF2-3: 0, BIFF4: 0-1 }; /** Functions new in BIFF5/BIFF7. */ static const FunctionData saFuncTableBiff5[] = { - { "WEEKDAY", "WEEKDAY", 70, 70, 1, 2, V, { V }, 0 }, // BIFF2-4: 1, BIFF5: 1-2 - { "HLOOKUP", "HLOOKUP", 101, 101, 3, 4, V, { V, R, R, V }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 - { "VLOOKUP", "VLOOKUP", 102, 102, 3, 4, V, { V, R, R, V }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 - { 0, "ADD.MENU", 152, 152, 2, 4, V, { V, R, R, V }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4 - { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { V, R, R, R, V }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5 - { "DAYS360", "DAYS360", 220, 220, 2, 3, V, { V }, 0 }, // BIFF3-4: 2, BIFF5: 2-3 - { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { ER, R }, FUNCFLAG_EXPORTONLY }, // MACRO or EXTERNAL - { "CONCATENATE", "CONCATENATE", 336, 336, 0, MX, V, { V }, 0 }, - { "POWER", "POWER", 337, 337, 2, 2, V, { V }, 0 }, - { "RADIANS", "RADIANS", 342, 342, 1, 1, V, { V }, 0 }, - { "DEGREES", "DEGREES", 343, 343, 1, 1, V, { V }, 0 }, - { "SUBTOTAL", "SUBTOTAL", 344, 344, 2, MX, V, { V, R }, 0 }, - { "SUMIF", "SUMIF", 345, 345, 2, 3, V, { R, V, R }, 0 }, - { "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { R, V }, 0 }, - { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { R }, 0 }, - { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { V }, 0 }, - { 0, "DATEDIF", 351, 351, 3, 3, V, { V }, FUNCFLAG_IMPORTONLY }, // not supported in Calc - { 0, "DATESTRING", 352, 352, 1, 1, V, { V }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOX spec - { 0, "NUMBERSTRING", 353, 353, 2, 2, V, { V }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOX spec - { "ROMAN", "ROMAN", 354, 354, 1, 2, V, { V }, 0 }, + { "WEEKDAY", "WEEKDAY", 70, 70, 1, 2, V, { VR }, 0 }, // BIFF2-4: 1, BIFF5: 1-2 + { "HLOOKUP", "HLOOKUP", 101, 101, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 + { "VLOOKUP", "VLOOKUP", 102, 102, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 + { 0, "ADD.MENU", 152, 152, 2, 4, V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4 + { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5 + { "DAYS360", "DAYS360", 220, 220, 2, 3, V, { VR }, 0 }, // BIFF3-4: 2, BIFF5: 2-3 + { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_EXPORTONLY }, // MACRO or EXTERNAL + { "CONCATENATE", "CONCATENATE", 336, 336, 0, MX, V, { VR }, 0 }, + { "POWER", "POWER", 337, 337, 2, 2, V, { VR }, 0 }, + { "RADIANS", "RADIANS", 342, 342, 1, 1, V, { VR }, 0 }, + { "DEGREES", "DEGREES", 343, 343, 1, 1, V, { VR }, 0 }, + { "SUBTOTAL", "SUBTOTAL", 344, 344, 2, MX, V, { VR, RO }, 0 }, + { "SUMIF", "SUMIF", 345, 345, 2, 3, V, { RO, VR, RO }, 0 }, + { "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { RO, VR }, 0 }, + { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { RO }, 0 }, + { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { VR }, 0 }, + { 0, "DATEDIF", 351, 351, 3, 3, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc + { 0, "DATESTRING", 352, 352, 1, 1, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOX spec + { 0, "NUMBERSTRING", 353, 353, 2, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOX spec + { "ROMAN", "ROMAN", 354, 354, 1, 2, V, { VR }, 0 }, // *** EuroTool add-in *** - { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { V }, FUNCFLAG_EUROTOOL }, + { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { VR }, FUNCFLAG_EUROTOOL }, // *** macro sheet commands *** - { 0, "ADD.CHART.AUTOFORMAT", 390, 390, 0, 2, V, { V }, FUNCFLAG_MACROCMD }, - { 0, "ADD.LIST.ITEM", 451, 451, 0, 2, V, { V }, FUNCFLAG_MACROCMD }, - { 0, "ACTIVE.CELL.FONT", 476, 476, 0, 14, V, { V }, FUNCFLAG_MACROCMD } + { 0, "ADD.CHART.AUTOFORMAT", 390, 390, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, + { 0, "ADD.LIST.ITEM", 451, 451, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, + { 0, "ACTIVE.CELL.FONT", 476, 476, 0, 14, V, { VR }, FUNCFLAG_MACROCMD } }; /** Functions new in BIFF8. */ static const FunctionData saFuncTableBiff8[] = { - { "GETPIVOTDATA", "GETPIVOTDATA", 358, 358, 2, MX, V, { V, R, V }, FUNCFLAG_IMPORTONLY }, - { "HYPERLINK", "HYPERLINK", 359, 359, 1, 2, V, { V }, 0 }, - { 0, "PHONETIC", 360, 360, 1, 1, V, { R }, FUNCFLAG_IMPORTONLY }, - { "AVERAGEA", "AVERAGEA", 361, 361, 1, MX, V, { R }, 0 }, - { "MAXA", "MAXA", 362, 362, 1, MX, V, { R }, 0 }, - { "MINA", "MINA", 363, 363, 1, MX, V, { R }, 0 }, - { "STDEVPA", "STDEVPA", 364, 364, 1, MX, V, { R }, 0 }, - { "VARPA", "VARPA", 365, 365, 1, MX, V, { R }, 0 }, - { "STDEVA", "STDEVA", 366, 366, 1, MX, V, { R }, 0 }, - { "VARA", "VARA", 367, 367, 1, MX, V, { R }, 0 }, - { "COM.MICROSOFT.BAHTTEXT", "BAHTTEXT", 368, 368, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "THAIDAYOFWEEK", 369, 369, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "THAIDIGIT", 370, 370, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "THAIMONTHOFYEAR", 371, 371, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "THAINUMSOUND", 372, 372, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "THAINUMSTRING", 373, 373, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "THAISTRINGLENGTH", 374, 374, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "ISTHAIDIGIT", 375, 375, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "ROUNDBAHTDOWN", 376, 376, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "ROUNDBAHTUP", 377, 377, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "THAIYEAR", 378, 378, 1, 1, V, { V }, FUNCFLAG_MACROCALL }, - { 0, "RTD", 379, 379, 3, 3, A, { V, V, R }, 0 } + { "GETPIVOTDATA", "GETPIVOTDATA", 358, 358, 2, MX, V, { RR, RR, VR, VR }, FUNCFLAG_IMPORTONLY | FUNCFLAG_PARAMPAIRS }, + { "HYPERLINK", "HYPERLINK", 359, 359, 1, 2, V, { VV, VO }, 0 }, + { 0, "PHONETIC", 360, 360, 1, 1, V, { RO }, FUNCFLAG_IMPORTONLY }, + { "AVERAGEA", "AVERAGEA", 361, 361, 1, MX, V, { RX }, 0 }, + { "MAXA", "MAXA", 362, 362, 1, MX, V, { RX }, 0 }, + { "MINA", "MINA", 363, 363, 1, MX, V, { RX }, 0 }, + { "STDEVPA", "STDEVPA", 364, 364, 1, MX, V, { RX }, 0 }, + { "VARPA", "VARPA", 365, 365, 1, MX, V, { RX }, 0 }, + { "STDEVA", "STDEVA", 366, 366, 1, MX, V, { RX }, 0 }, + { "VARA", "VARA", 367, 367, 1, MX, V, { RX }, 0 }, + { "COM.MICROSOFT.BAHTTEXT", "BAHTTEXT", 368, 368, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "THAIDAYOFWEEK", 369, 369, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "THAIDIGIT", 370, 370, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "THAIMONTHOFYEAR", 371, 371, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "THAINUMSOUND", 372, 372, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "THAINUMSTRING", 373, 373, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "THAISTRINGLENGTH", 374, 374, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "ISTHAIDIGIT", 375, 375, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "ROUNDBAHTDOWN", 376, 376, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "ROUNDBAHTUP", 377, 377, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "THAIYEAR", 378, 378, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, + { 0, "RTD", 379, 379, 3, 3, A, { VR, VR, RO }, 0 } }; /** Functions new in OOX. */ static const FunctionData saFuncTableOox[] = { - { 0, "IFERROR", 480, NOID, 2, 2, V, { V, R }, 0 }, - { 0, "COUNTIFS", 481, NOID, 3, MX, V, { R, V }, 0 }, - { 0, "SUMIFS", 482, NOID, 3, MX, V, { R, V }, 0 }, - { 0, "AVERAGEIF", 483, NOID, 2, 3, V, { R, V, R }, 0 }, - { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { R, V }, 0 }, - { 0, "CUBEKPIMEMBER", NOID, NOID, 3, 4, V, { V }, 0 }, - { 0, "CUBEMEMBER", NOID, NOID, 2, 3, V, { V, A, V }, 0 }, - { 0, "CUBEMEMBERPROPERTY", NOID, NOID, 3, 3, V, { V }, 0 }, - { 0, "CUBERANKEDMEMBER", NOID, NOID, 3, 4, V, { V }, 0 }, - { 0, "CUBESET", NOID, NOID, 2, 5, V, { V, R, V }, 0 }, - { 0, "CUBESETCOUNT", NOID, NOID, 1, 1, V, { V }, 0 }, - { 0, "CUBEVALUE", NOID, NOID, 2, 2, V, { V, R }, 0 } + { 0, "CUBEVALUE", 380, NOID, 1, MX, V, { VR, RX }, 0 }, + { 0, "CUBEMEMBER", 381, NOID, 2, 3, V, { VR, RX, VR }, 0 }, + { 0, "CUBEMEMBERPROPERTY", 382, NOID, 3, 3, V, { VR }, 0 }, + { 0, "CUBERANKEDMEMBER", 383, NOID, 3, 4, V, { VR }, 0 }, + { 0, "CUBEKPIMEMBER", 477, NOID, 3, 4, V, { VR }, 0 }, + { 0, "CUBESET", 478, NOID, 2, 5, V, { VR, RX, VR }, 0 }, + { 0, "CUBESETCOUNT", 479, NOID, 1, 1, V, { VR }, 0 }, + { 0, "IFERROR", 480, NOID, 2, 2, V, { VO, RO }, 0 }, + { 0, "COUNTIFS", 481, NOID, 2, MX, V, { RO, VR }, FUNCFLAG_PARAMPAIRS }, + { 0, "SUMIFS", 482, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS }, + { 0, "AVERAGEIF", 483, NOID, 2, 3, V, { RO, VR, RO }, 0 }, + { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { RO, RO, VR }, 0 } }; /** Functions defined by OpenFormula, but not supported by Calc or by Excel. */ static const FunctionData saFuncTableOdf[] = { - { "ARABIC", 0, NOID, NOID, 1, 1, V, { V }, 0 }, - { "B", 0, NOID, NOID, 3, 4, V, { V }, 0 }, - { "BASE", 0, NOID, NOID, 2, 3, V, { V }, 0 }, - { "BITAND", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "BITOR", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "BITXOR", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { V }, 0 }, - { "CHISQINV", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "COMBINA", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "DAYS", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "DDE", 0, NOID, NOID, 3, 4, V, { V }, 0 }, - { "DECIMAL", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "FDIST", 0, NOID, NOID, 3, 4, V, { V }, 0 }, - { "FINV", 0, NOID, NOID, 3, 3, V, { V }, 0 }, - { "FORMULA", 0, NOID, NOID, 1, 1, V, { R }, 0 }, - { "GAMMA", 0, NOID, NOID, 1, 1, V, { V }, 0 }, - { "GAUSS", 0, NOID, NOID, 1, 1, V, { V }, 0 }, - { "IFNA", 0, NOID, NOID, 2, 2, V, { V, R }, 0 }, - { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { R }, 0 }, - { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { V }, 0 }, - { "MULTIPLE.OPERATIONS", 0, NOID, NOID, 3, 5, V, { R }, 0 }, - { "MUNIT", 0, NOID, NOID, 1, 1, A, { V }, 0 }, - { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "PDURATION", 0, NOID, NOID, 3, 3, V, { V }, 0 }, - { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { V }, 0 }, - { "PHI", 0, NOID, NOID, 1, 1, V, { V }, 0 }, - { "RRI", 0, NOID, NOID, 3, 3, V, { V }, 0 }, - { "SHEET", 0, NOID, NOID, 1, 1, V, { R }, 0 }, - { "SHEETS", 0, NOID, NOID, 0, 1, V, { R }, 0 }, - { "SKEWP", 0, NOID, NOID, 1, MX, V, { R }, 0 }, - { "UNICHAR", 0, NOID, NOID, 1, 1, V, { V }, 0 }, - { "UNICODE", 0, NOID, NOID, 1, 1, V, { V }, 0 }, - { "XOR", 0, NOID, NOID, 1, MX, V, { R }, 0 } + { "ARABIC", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, + { "B", 0, NOID, NOID, 3, 4, V, { VR }, 0 }, + { "BASE", 0, NOID, NOID, 2, 3, V, { VR }, 0 }, + { "BITAND", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "BITOR", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, 0 }, + { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "DDE", 0, NOID, NOID, 3, 4, V, { VR }, 0 }, + { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, 0 }, + { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, 0 }, + { "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, 0 }, + { "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, + { "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, + { "IFNA", 0, NOID, NOID, 2, 2, V, { VR, RO }, 0 }, + { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { RO }, 0 }, + { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { VR }, 0 }, + { "MULTIPLE.OPERATIONS", 0, NOID, NOID, 3, 5, V, { RO }, 0 }, + { "MUNIT", 0, NOID, NOID, 1, 1, A, { VR }, 0 }, + { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "PDURATION", 0, NOID, NOID, 3, 3, V, { VR }, 0 }, + { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, + { "PHI", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, + { "RRI", 0, NOID, NOID, 3, 3, V, { VR }, 0 }, + { "SHEET", 0, NOID, NOID, 1, 1, V, { RO }, 0 }, + { "SHEETS", 0, NOID, NOID, 0, 1, V, { RO }, 0 }, + { "SKEWP", 0, NOID, NOID, 1, MX, V, { RX }, 0 }, + { "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, + { "UNICODE", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, + { "XOR", 0, NOID, NOID, 1, MX, V, { RX }, 0 } }; // ---------------------------------------------------------------------------- @@ -778,16 +793,46 @@ const sal_Unicode API_TOKEN_ARRAY_COLSEP = ';'; // function info parameter class iterator ===================================== -FuncInfoParamClassIterator::FuncInfoParamClassIterator( const FunctionInfo& rFuncInfo ) : - mpnParamClass( rFuncInfo.mpnParamClass ), - mpnParamClassEnd( rFuncInfo.mpnParamClass + FUNCINFO_CLASSCOUNT ) +FunctionParamInfoIterator::FunctionParamInfoIterator( const FunctionInfo& rFuncInfo ) : + mpParamInfo( rFuncInfo.mpParamInfos ), + mpParamInfoEnd( rFuncInfo.mpParamInfos + FUNCINFO_PARAMINFOCOUNT ), + mbParamPairs( rFuncInfo.mbParamPairs ) { + OSL_ENSURE( !mbParamPairs || (mpParamInfo + 1 < mpParamInfoEnd), + "FunctionParamInfoIterator::FunctionParamInfoIterator - expecting at least 2 infos for paired parameters" ); } -FuncInfoParamClassIterator& FuncInfoParamClassIterator::operator++() +const FunctionParamInfo& FunctionParamInfoIterator::getParamInfo() const { - if( (mpnParamClass + 1 < mpnParamClassEnd) && (mpnParamClass[ 1 ] != 0) ) - ++mpnParamClass; + static const FunctionParamInfo saInvalidInfo = { FUNC_PARAM_NONE, FUNC_PARAMCONV_ORG, false }; + return mpParamInfo ? *mpParamInfo : saInvalidInfo; +} + +bool FunctionParamInfoIterator::isCalcOnlyParam() const +{ + return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_CALCONLY); +} + +bool FunctionParamInfoIterator::isExcelOnlyParam() const +{ + return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_EXCELONLY); +} + +FunctionParamInfoIterator& FunctionParamInfoIterator::operator++() +{ + if( mpParamInfo ) + { + // move pointer to next entry, if something explicit follows + if( (mpParamInfo + 1 < mpParamInfoEnd) && (mpParamInfo[ 1 ].meValid != FUNC_PARAM_NONE) ) + ++mpParamInfo; + // points to last info, but parameter pairs expected, move to previous info + else if( mbParamPairs ) + --mpParamInfo; + // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it + else if( isExcelOnlyParam() || isCalcOnlyParam() ) + mpParamInfo = 0; + // otherwise: repeat last parameter class + } return *this; } @@ -876,7 +921,8 @@ void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nM xFuncInfo->mnMinParamCount = rFuncData.mnMinParamCount; xFuncInfo->mnMaxParamCount = (rFuncData.mnMaxParamCount == MX) ? nMaxParam : rFuncData.mnMaxParamCount; xFuncInfo->mnRetClass = rFuncData.mnRetClass; - xFuncInfo->mpnParamClass = rFuncData.mpnParamClass; + xFuncInfo->mpParamInfos = rFuncData.mpParamInfos; + xFuncInfo->mbParamPairs = getFlag( rFuncData.mnFlags, FUNCFLAG_PARAMPAIRS ); xFuncInfo->mbVolatile = getFlag( rFuncData.mnFlags, FUNCFLAG_VOLATILE ); xFuncInfo->mbExternal = getFlag( rFuncData.mnFlags, FUNCFLAG_EXTERNAL ); bool bMacroCmd = getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCMD ); diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index d2818ff9cb1a..f0ff482e5828 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -233,23 +233,23 @@ const ApiToken* FormulaFinalizer::processParameters( } // process all parameters - FuncInfoParamClassIterator aClassIt( *pRealFuncInfo ); + FunctionParamInfoIterator aParamInfoIt( *pRealFuncInfo ); size_t nLastValidSize = maTokens.size(); size_t nLastValidCount = 0; - for( size_t nParam = 0; nParam < nParamCount; ++nParam, ++aPosIt, ++aClassIt ) + for( size_t nParam = 0; nParam < nParamCount; ++nParam, ++aPosIt, ++aParamInfoIt ) { // add embedded Calc-only parameters - if( aClassIt.isCalcOnlyParam() ) + if( aParamInfoIt.isCalcOnlyParam() ) { appendCalcOnlyParameter( *pRealFuncInfo, nParam ); - while( aClassIt.isCalcOnlyParam() ) ++aClassIt; + while( aParamInfoIt.isCalcOnlyParam() ) ++aParamInfoIt; } const ApiToken* pParamBegin = *aPosIt + 1; const ApiToken* pParamEnd = *(aPosIt + 1); bool bIsEmpty = isEmptyParameter( pParamBegin, pParamEnd ); - if( !aClassIt.isExcelOnlyParam() ) + if( !aParamInfoIt.isExcelOnlyParam() ) { // replace empty second and third parameter in IF function with zeros if( (pRealFuncInfo->mnOobFuncId == OOBIN_FUNC_IF) && ((nParam == 1) || (nParam == 2)) && bIsEmpty ) @@ -279,7 +279,7 @@ const ApiToken* FormulaFinalizer::processParameters( maTokens.resize( nLastValidSize ); // add trailing Calc-only parameters - if( aClassIt.isCalcOnlyParam() ) + if( aParamInfoIt.isCalcOnlyParam() ) appendCalcOnlyParameter( *pRealFuncInfo, nLastValidCount ); // add optional parameters that are required in Calc @@ -1420,6 +1420,7 @@ bool OoxFormulaParserImpl::importAttrToken( RecordInputStream& rStrm ) // equal flags in BIFF and OOBIN switch( nType ) { + case 0: // sometimes, tAttrSkip tokens miss the type flag case OOBIN_TOK_ATTR_VOLATILE: case OOBIN_TOK_ATTR_IF: case OOBIN_TOK_ATTR_SKIP: @@ -2199,6 +2200,7 @@ bool BiffFormulaParserImpl::importAttrToken( BiffInputStream& rStrm ) rStrm >> nType; switch( nType ) { + case 0: // sometimes, tAttrSkip tokens miss the type flag case BIFF_TOK_ATTR_VOLATILE: case BIFF_TOK_ATTR_IF: case BIFF_TOK_ATTR_SKIP: From d96b6584a5da69ee35a9c1e19d1caec3172984a5 Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Wed, 16 Sep 2009 11:45:54 +0000 Subject: [PATCH 07/16] CWS-TOOLING: integrate CWS l10nframework01 --- filter/prj/build.lst | 5 +- filter/source/config/fragments/makefile.mk | 2 +- .../source/config/tools/merge/FCFGMerge.cfg | 125 - .../source/config/tools/merge/FCFGMerge.java | 128 - filter/source/config/tools/merge/Manifest.mf | 1 - filter/source/config/tools/merge/Merger.java | 362 --- filter/source/config/tools/merge/makefile.mk | 90 - .../config/tools/utils/AnalyzeStartupLog.java | 324 --- filter/source/config/tools/utils/Cache.java | 2444 ----------------- .../config/tools/utils/ConfigHelper.java | 297 -- .../source/config/tools/utils/FileHelper.java | 760 ----- filter/source/config/tools/utils/Logger.java | 172 -- .../utils/MalformedCommandLineException.java | 46 - .../source/config/tools/utils/XMLHelper.java | 820 ------ filter/source/config/tools/utils/makefile.mk | 63 - oox/util/makefile.mk | 3 +- unoxml/source/rdf/makefile.mk | 2 + xmerge/source/aportisdoc/makefile.mk | 2 + xmerge/source/bridge/makefile.mk | 2 + xmerge/source/htmlsoff/makefile.mk | 2 + xmerge/source/pexcel/makefile.mk | 2 + xmerge/source/pocketword/makefile.mk | 2 + xmerge/source/xmerge/makefile.mk | 2 + xmerge/util/makefile.mk | 2 + 24 files changed, 20 insertions(+), 5638 deletions(-) delete mode 100644 filter/source/config/tools/merge/FCFGMerge.cfg delete mode 100644 filter/source/config/tools/merge/FCFGMerge.java delete mode 100644 filter/source/config/tools/merge/Manifest.mf delete mode 100644 filter/source/config/tools/merge/Merger.java delete mode 100644 filter/source/config/tools/merge/makefile.mk delete mode 100644 filter/source/config/tools/utils/AnalyzeStartupLog.java delete mode 100644 filter/source/config/tools/utils/Cache.java delete mode 100644 filter/source/config/tools/utils/ConfigHelper.java delete mode 100644 filter/source/config/tools/utils/FileHelper.java delete mode 100644 filter/source/config/tools/utils/Logger.java delete mode 100644 filter/source/config/tools/utils/MalformedCommandLineException.java delete mode 100644 filter/source/config/tools/utils/XMLHelper.java delete mode 100644 filter/source/config/tools/utils/makefile.mk diff --git a/filter/prj/build.lst b/filter/prj/build.lst index 49083f538e8f..63b7e25c646b 100644 --- a/filter/prj/build.lst +++ b/filter/prj/build.lst @@ -16,9 +16,6 @@ fl filter\source\xsltdialog nmake - all fl_xsltdialog fl_flash fl_inc NULL fl filter\source\docbook nmake - all fl_docbook fl_inc NULL fl filter\source\t602 nmake - all fl_t602 fl_inc NULL fl filter\source\config\cache nmake - all fl_config fl_inc NULL -fl filter\source\config\tools\utils nmake - all fl_fcfg_utils fl_inc NULL -fl filter\source\config\tools\merge nmake - all fl_fcfg_merge fl_fcfg_utils fl_xsltvalidate fl_inc NULL fl filter\source\config\fragments\types nmake - all fl_fcfg_fragments_types fl_inc NULL fl filter\source\config\fragments\filters nmake - all fl_fcfg_fragments_filters fl_inc NULL -fl filter\source\config\fragments nmake - all fl_fcfg_fragments fl_fcfg_merge fl_fcfg_fragments_filters fl_inc NULL - +fl filter\source\config\fragments nmake - all fl_fcfg_fragments fl_fcfg_fragments_filters fl_inc NULL diff --git a/filter/source/config/fragments/makefile.mk b/filter/source/config/fragments/makefile.mk index 6f76c1d60d6b..d398e03e5a7d 100644 --- a/filter/source/config/fragments/makefile.mk +++ b/filter/source/config/fragments/makefile.mk @@ -187,7 +187,7 @@ $(ALL_FLAGS) : $(INCLUDE_FRAGMENTS) #cmc, hack to workaround the java build requirement MERGE:=python ../tools/merge/pyAltFCFGMerge .ELSE -MERGE := $(JAVAI) -jar $(CLASSDIR)$/FCFGMerge.jar +MERGE := $(JAVAI) -jar $(SOLARBINDIR)$/FCFGMerge.jar .ENDIF PACKLANG := $(XSLTPROC) --nonet diff --git a/filter/source/config/tools/merge/FCFGMerge.cfg b/filter/source/config/tools/merge/FCFGMerge.cfg deleted file mode 100644 index 46fcccafe7e4..000000000000 --- a/filter/source/config/tools/merge/FCFGMerge.cfg +++ /dev/null @@ -1,125 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2008 by Sun Microsystems, Inc. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# $RCSfile: FCFGMerge.cfg,v $ -# -# $Revision: 1.5 $ -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -#************************************************ -# Specify the verbose mode of this tool. -# 1 = show errors only -# 2 = show errors/warnings (default) -# 3 = show errors/warnings and some generic infos -# 4 = show anything (including detailed infos) -# -# [OPTIONAL] -#************************************************ - -loglevel = 2 - -#************************************************ -# This extension is used for all XML files. It doesnt -# matter if its used for reading fragments or writing -# XML packages. -# Must be given without any additional signes like "." -# or "*."! -# -# [REQUIRED] -#************************************************ - -extension_xcu=xcu - -#************************************************ -# This extension is used for all Package files. It doesnt -# matter if its used for reading such files or writing -# it. -# Must be given without any additional signes like "." -# or "*."! -# -# [REQUIRED] -#************************************************ - -extension_pkg=pkg - -#************************************************ -# These values are used to generate a correct XML -# header. -# Note: The property "xmlpackage" must be specified -# via command line. There exists more then one -# possible value. -# -# [REQUIRED] -#************************************************ - -xmlversion = 1.0 -xmlencoding = UTF-8 -xmlpath = org.openoffice.TypeDetection -#xmlpackage = - -#************************************************ -# These values are used to name the configuration -# sets inside the generated XCM file for different -# item groups like e.g. types, filters etcpp. -# -# [REQUIRED] -#************************************************ - -setname_types = Types -setname_filters = Filters -setname_frameloaders = FrameLoaders -setname_contenthandlers = ContentHandlers - -subdir_types = types -subdir_filters = filters -subdir_frameloaders = frameloaders -subdir_contenthandlers = contenthandlers - -#************************************************ -# This delimiter is used to split every -# item list of the package configuration files -# (which are temp. created by the make proccess) -# into its tokens. -# -# [REQUIRED] -#************************************************ -delimiter=, - -#************************************************ -# Enable/disable removing of leading/trailing withespaces -# during splitting stringlists. -# -# [REQUIRED] -#************************************************ -trim=true - -#************************************************ -# Enable/disable removing of leading/trailing "-signs -# during splitting stringlists. -# -# [REQUIRED] -#************************************************ -decode=false diff --git a/filter/source/config/tools/merge/FCFGMerge.java b/filter/source/config/tools/merge/FCFGMerge.java deleted file mode 100644 index 1b37bab0e89a..000000000000 --- a/filter/source/config/tools/merge/FCFGMerge.java +++ /dev/null @@ -1,128 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: FCFGMerge.java,v $ - * $Revision: 1.5 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -package com.sun.star.filter.config.tools.merge; - -//_______________________________________________ - -import com.sun.star.filter.config.tools.utils.*; - -//_______________________________________________ - -/** - * Its a simple command line tool, which can merge different XML fragments - * together. Such fragments must exist as files on disk, will be moved into - * one file together on disk. - * - * - */ -public class FCFGMerge -{ - //___________________________________________ - // const - - private static final java.lang.String CFGFILE = "com/sun/star/filter/config/tools/merge/FCFGMerge.cfg"; - private static final java.lang.String PROP_LOGLEVEL = "loglevel"; - - //___________________________________________ - // main - - public static void main(java.lang.String[] sCmdLine) - { - FCFGMerge.printCopyright(); - - // create log object in default mode "WARNINGS" - // If a command line parameter indicates another - // level - change it! - Logger aLog = new Logger(); - - try - { - // merge config file and overwrite properties - // via command line - ConfigHelper aCfg = null; - aCfg = new ConfigHelper(CFGFILE, sCmdLine); - - // update log level - int nLogLevel = aCfg.getInt(PROP_LOGLEVEL, Logger.LEVEL_WARNINGS); - aLog = new Logger(nLogLevel); - - // help requested? - if (aCfg.isHelp()) - { - FCFGMerge.printHelp(); - System.exit(-1); - } - - // create new merge object and start operation - Merger aMerger = new Merger(aCfg, aLog); - aMerger.merge(); - } - catch(java.lang.Throwable ex) - { - aLog.setException(ex); - System.exit(-1); - } - - System.exit(0); - } - - //___________________________________________ - - /** prints out a copyright message on stdout. - */ - private static void printCopyright() - { - java.lang.StringBuffer sOut = new java.lang.StringBuffer(256); - sOut.append("FCFGMerge\n"); - sOut.append("Copyright: 2003 by Sun Microsystems, Inc.\n"); - sOut.append("All Rights Reserved.\n"); - System.out.println(sOut.toString()); - } - - //___________________________________________ - - /** prints out a help message on stdout. - */ - private static void printHelp() - { - java.lang.StringBuffer sOut = new java.lang.StringBuffer(256); - sOut.append("____________________________________________________________\n"); - sOut.append("usage: FCFGMerge cfg=\n" ); - sOut.append("parameters:\n" ); - sOut.append("\tcfg=\n" ); - sOut.append("\t\tmust point to a system file, which contains\n" ); - sOut.append("\t\tall neccessary configuration data for the merge process.\n"); - sOut.append("\n\tFurther cou can specify every parameter allowed in the\n" ); - sOut.append("\n\tconfig file as command line parameter too, to overwrite\n" ); - sOut.append("\n\tthe value from the file.\n" ); - System.out.println(sOut.toString()); - } -} diff --git a/filter/source/config/tools/merge/Manifest.mf b/filter/source/config/tools/merge/Manifest.mf deleted file mode 100644 index 1337eaf4d39a..000000000000 --- a/filter/source/config/tools/merge/Manifest.mf +++ /dev/null @@ -1 +0,0 @@ -Main-Class: com.sun.star.filter.config.tools.merge.FCFGMerge diff --git a/filter/source/config/tools/merge/Merger.java b/filter/source/config/tools/merge/Merger.java deleted file mode 100644 index 34e27a3835da..000000000000 --- a/filter/source/config/tools/merge/Merger.java +++ /dev/null @@ -1,362 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: Merger.java,v $ - * $Revision: 1.8 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -package com.sun.star.filter.config.tools.merge; - -//_______________________________________________ - -import java.io.*; -import com.sun.star.filter.config.tools.utils.*; - -//_______________________________________________ - -/** can merge different xml fragments together. - * - * - */ -public class Merger -{ - //___________________________________________ - // const - - private static final java.lang.String PROP_XMLVERSION = "xmlversion" ; // <= global cfg file - private static final java.lang.String PROP_XMLENCODING = "xmlencoding" ; // <= global cfg file - private static final java.lang.String PROP_XMLPATH = "xmlpath" ; // <= global cfg file - private static final java.lang.String PROP_XMLPACKAGE = "xmlpackage" ; // <= global cfg file - - private static final java.lang.String PROP_SETNAME_TYPES = "setname_types" ; // <= global cfg file - private static final java.lang.String PROP_SETNAME_FILTERS = "setname_filters" ; // <= global cfg file - private static final java.lang.String PROP_SETNAME_LOADERS = "setname_frameloaders" ; // <= global cfg file - private static final java.lang.String PROP_SETNAME_HANDLERS = "setname_contenthandlers" ; // <= global cfg file - - private static final java.lang.String PROP_SUBDIR_TYPES = "subdir_types" ; // <= global cfg file - private static final java.lang.String PROP_SUBDIR_FILTERS = "subdir_filters" ; // <= global cfg file - private static final java.lang.String PROP_SUBDIR_LOADERS = "subdir_frameloaders" ; // <= global cfg file - private static final java.lang.String PROP_SUBDIR_HANDLERS = "subdir_contenthandlers" ; // <= global cfg file - - private static final java.lang.String PROP_EXTENSION_XCU = "extension_xcu" ; // <= global cfg file - private static final java.lang.String PROP_EXTENSION_PKG = "extension_pkg" ; // <= global cfg file - - private static final java.lang.String PROP_DELIMITER = "delimiter" ; // <= global cfg file - private static final java.lang.String PROP_TRIM = "trim" ; // <= global cfg file - private static final java.lang.String PROP_DECODE = "decode" ; // <= global cfg file - - private static final java.lang.String PROP_FRAGMENTSDIR = "fragmentsdir" ; // <= cmdline - private static final java.lang.String PROP_TEMPDIR = "tempdir" ; // <= cmdline - private static final java.lang.String PROP_OUTDIR = "outdir" ; // <= cmdline - private static final java.lang.String PROP_PKG = "pkg" ; // <= cmdline - private static final java.lang.String PROP_DEBUG = "debug" ; // <= cmdline - - private static final java.lang.String PROP_TCFG = "tcfg" ; // <= cmdline - private static final java.lang.String PROP_FCFG = "fcfg" ; // <= cmdline - private static final java.lang.String PROP_LCFG = "lcfg" ; // <= cmdline - private static final java.lang.String PROP_CCFG = "ccfg" ; // <= cmdline - private static final java.lang.String PROP_LANGUAGEPACK = "languagepack" ; // <= cmdline - - private static final java.lang.String PROP_ITEMS = "items" ; // <= pkg cfg files! - - //___________________________________________ - // member - - //------------------------------------------- - /** TODO */ - private ConfigHelper m_aCfg; - - //------------------------------------------- - /** TODO */ - private Logger m_aLog; - - //------------------------------------------- - /** TODO */ - private java.io.File m_aFragmentsDir; - - //------------------------------------------- - /** TODO */ - private java.io.File m_aTempDir; - - //------------------------------------------- - /** TODO */ - private java.io.File m_aOutDir; - - //------------------------------------------- - /** TODO */ - private java.util.Vector m_lTypes; - private java.util.Vector m_lFilters; - private java.util.Vector m_lLoaders; - private java.util.Vector m_lHandlers; - - //___________________________________________ - // interface - - //------------------------------------------- - /** initialize a new instance of this class and - * try to get all needed resources from the config module. - * - * @param aCfg - * provides access to all values of the global - * config file and to the command line. - * - * @param aLog - * can be used to print out log informations. - */ - public Merger(ConfigHelper aCfg, - Logger aLog) - throws java.lang.Exception - { - m_aCfg = aCfg; - m_aLog = aLog; - - m_aFragmentsDir = new java.io.File(m_aCfg.getString(PROP_FRAGMENTSDIR)); - m_aTempDir = new java.io.File(m_aCfg.getString(PROP_TEMPDIR )); -// m_aOutDir = new java.io.File(m_aCfg.getString(PROP_OUTDIR )); - - java.lang.String sDelimiter = m_aCfg.getString(PROP_DELIMITER); - boolean bTrim = m_aCfg.getBoolean(PROP_TRIM); - boolean bDecode = m_aCfg.getBoolean(PROP_DECODE); - - try - { - ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_TCFG), null); - m_lTypes = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); - } - catch(java.util.NoSuchElementException ex1) - { - m_lTypes = new java.util.Vector(); - //m_aLog.setWarning("Fragment list of types is missing. Parameter \"items\" seems to be invalid."); - } - - try - { - ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_FCFG), null); - m_lFilters = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); - } - catch(java.util.NoSuchElementException ex1) - { - m_lFilters = new java.util.Vector(); - //m_aLog.setWarning("Fragment list of filters is missing. Parameter \"items\" seems to be invalid."); - } - - try - { - ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_LCFG), null); - m_lLoaders = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); - } - catch(java.util.NoSuchElementException ex1) - { - m_lLoaders = new java.util.Vector(); - //m_aLog.setWarning("Fragment list of frame loader objects is missing. Parameter \"items\" seems to be invalid."); - } - - try - { - ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_CCFG), null); - m_lHandlers = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); - } - catch(java.util.NoSuchElementException ex1) - { - m_lHandlers = new java.util.Vector(); - //m_aLog.setWarning("Fragment list of content handler objects is missing. Parameter \"items\" seems to be invalid."); - } - } - - //------------------------------------------- - /** TODO */ - public synchronized void merge() - throws java.lang.Exception - { - java.lang.StringBuffer sBuffer = new java.lang.StringBuffer(1000000); - java.lang.String sPackage = m_aCfg.getString(PROP_PKG); - - m_aLog.setGlobalInfo("create package \""+sPackage+"\" ..."); - m_aLog.setDetailedInfo("generate package header ... "); - - sBuffer.append( - XMLHelper.generateHeader( - m_aCfg.getString (PROP_XMLVERSION ), - m_aCfg.getString (PROP_XMLENCODING ), - m_aCfg.getString (PROP_XMLPATH ), - m_aCfg.getString (PROP_XMLPACKAGE ), - m_aCfg.getBoolean(PROP_LANGUAGEPACK, false))); - - // counts all transfered fragments - // Can be used later to decide, if a generated package file - // contains "nothing"! - int nItemCount = 0; - - for (int i=0; i<4; ++i) - { - java.lang.String sSetName = null; - java.lang.String sSubDir = null; - java.util.Vector lFragments = null; - - try - { - switch(i) - { - case 0: // types - { - m_aLog.setDetailedInfo("generate set for types ... "); - sSetName = m_aCfg.getString(PROP_SETNAME_TYPES); - sSubDir = m_aCfg.getString(PROP_SUBDIR_TYPES ); - lFragments = m_lTypes; - } - break; - - case 1: // filters - { - m_aLog.setDetailedInfo("generate set for filter ... "); - sSetName = m_aCfg.getString(PROP_SETNAME_FILTERS); - sSubDir = m_aCfg.getString(PROP_SUBDIR_FILTERS ); - lFragments = m_lFilters; - } - break; - - case 2: // loaders - { - m_aLog.setDetailedInfo("generate set for frame loader ... "); - sSetName = m_aCfg.getString(PROP_SETNAME_LOADERS); - sSubDir = m_aCfg.getString(PROP_SUBDIR_LOADERS ); - lFragments = m_lLoaders; - } - break; - - case 3: // handlers - { - m_aLog.setDetailedInfo("generate set for content handler ... "); - sSetName = m_aCfg.getString(PROP_SETNAME_HANDLERS); - sSubDir = m_aCfg.getString(PROP_SUBDIR_HANDLERS ); - lFragments = m_lHandlers; - } - break; - } - - nItemCount += lFragments.size(); - - getFragments( - new java.io.File(m_aFragmentsDir, sSubDir), - sSetName, - lFragments, - 1, - sBuffer); - } - catch(java.util.NoSuchElementException exIgnore) - { continue; } - } - - m_aLog.setDetailedInfo("generate package footer ... "); - sBuffer.append(XMLHelper.generateFooter()); - - // Attention! - // If the package seem to be empty, it make no sense to generate a corresponding - // xml file. We should suppress writing of this file on disk completly ... - if (nItemCount < 1) - { - m_aLog.setWarning("Package is empty and will not result into a xml file on disk!? Please check configuration file."); - return; - } - m_aLog.setGlobalInfo("package contains "+nItemCount+" items"); - - java.io.File aPackage = new File(sPackage); - m_aLog.setGlobalInfo("write temp package \""+aPackage.getPath()); // TODO encoding must be readed from the configuration - FileHelper.writeEncodedBufferToFile(aPackage, "UTF-8", false, sBuffer); // check for success is done inside this method! - } - - //------------------------------------------- - /** TODO */ - private void getFragments(java.io.File aDir , - java.lang.String sSetName , - java.util.Vector lFragments , - int nPrettyTabs, - java.lang.StringBuffer sBuffer ) - throws java.lang.Exception - { - if (lFragments.size()<1) - { - m_aLog.setWarning("List of fragments is empty!? Will be ignored ..."); - return; - } - - java.util.Enumeration pFragments = lFragments.elements(); - java.lang.String sExtXcu = m_aCfg.getString(PROP_EXTENSION_XCU); - - for (int tabs=0; tabs\n"); - ++nPrettyTabs; - - // special mode for generating language packs. - // In such case we must live with some missing fragment files. - // Reason behind; Not all filters are realy localized. - // But we dont use a different fragment list. We try to locate - // any fragment file in its language-pack version ... - boolean bHandleLanguagePacks = m_aCfg.getBoolean(PROP_LANGUAGEPACK, false); - boolean bDebug = m_aCfg.getBoolean(PROP_DEBUG , false); - java.lang.String sEncoding = "UTF-8"; - if (bDebug) - sEncoding = "UTF-8Special"; - - while(pFragments.hasMoreElements()) - { - java.lang.String sFragment = (java.lang.String)pFragments.nextElement(); - java.io.File aFragment = new java.io.File(aDir, sFragment+"."+sExtXcu); - - // handle simple files only and check for existence! - if (!aFragment.exists()) - { - if (bHandleLanguagePacks) - { - m_aLog.setWarning("language fragment \""+aFragment.getPath()+"\" does not exist. Will be ignored."); - continue; - } - else - throw new java.io.IOException("fragment \""+aFragment.getPath()+"\" does not exists."); - } - - if (!aFragment.isFile()) - { - m_aLog.setWarning("fragment \""+aFragment.getPath()+"\" seem to be not a valid file."); - continue; - } - - // copy file content of original fragment - // Note: A FileNotFoundException will be thrown automaticly by the - // used reader objects. Let it break this method too. Our calli is interested - // on such errors :-) - m_aLog.setDetailedInfo("merge fragment \""+aFragment.getPath()+"\" ..."); - FileHelper.readEncodedBufferFromFile(aFragment, sEncoding, sBuffer); - - sBuffer.append("\n"); - } - - --nPrettyTabs; - for (int tabs=0; tabs\n"); - } -} diff --git a/filter/source/config/tools/merge/makefile.mk b/filter/source/config/tools/merge/makefile.mk deleted file mode 100644 index 84175ab43cfb..000000000000 --- a/filter/source/config/tools/merge/makefile.mk +++ /dev/null @@ -1,90 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2008 by Sun Microsystems, Inc. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# $RCSfile: makefile.mk,v $ -# -# $Revision: 1.9.102.1 $ -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ = ..$/..$/..$/.. -TARGET = FCFGMerge -PRJNAME = filter -PACKAGE = com$/sun$/star$/filter$/config$/tools$/merge - -# --- Settings ----------------------------------------------------- - -.INCLUDE: settings.mk - -#----- compile .java files ----------------------------------------- - -OWNCOPY = \ - $(MISC)$/$(TARGET)_copied.done - -JARFILES = \ - ridl.jar \ - unoil.jar \ - jurt.jar \ - juh.jar \ - java_uno.jar - -CFGFILES = \ - FCFGMerge.cfg - -JAVACLASSFILES = \ - $(CLASSDIR)$/$(PACKAGE)$/Merger.class \ - $(CLASSDIR)$/$(PACKAGE)$/FCFGMerge.class - -CUSTOMMANIFESTFILE = \ - Manifest.mf - -MAXLINELENGTH = 100000 - -#----- make a jar from compiled files ------------------------------ - -JARCLASSDIRS = \ - com$/sun$/star$/filter$/config$/tools$/utils \ - com$/sun$/star$/filter$/config$/tools$/merge - -JARTARGET = $(TARGET).jar - -JARCOMPRESS = TRUE - -# --- targets ----------------------------------------------------- - -.INCLUDE : target.mk - -.IF "$(SOLAR_JAVA)" != "" || "$(GUI)"=="OS2" -ALLTAR : $(OWNCOPY) - -.IF "$(JARTARGETN)" != "" -$(JARTARGETN) : $(OWNCOPY) -.ENDIF - -$(OWNCOPY) : $(CFGFILES) - -$(MKDIR) $(CLASSDIR)$/$(PACKAGE) - $(COPY) $? $(CLASSDIR)$/$(PACKAGE) && $(TOUCH) $@ - -.ENDIF # "$(SOLAR_JAVA)" != "" diff --git a/filter/source/config/tools/utils/AnalyzeStartupLog.java b/filter/source/config/tools/utils/AnalyzeStartupLog.java deleted file mode 100644 index 0d074d9aad0e..000000000000 --- a/filter/source/config/tools/utils/AnalyzeStartupLog.java +++ /dev/null @@ -1,324 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: AnalyzeStartupLog.java,v $ - * $Revision: 1.4 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -package com.sun.star.filter.config.tools.utils; - - -//_______________________________________________ -// implementation -public class AnalyzeStartupLog -{ - private class OperationTime - { - /** name the measured operation. */ - public java.lang.String sOperation; - - /** contains the time value, when this operation was started. */ - public long nStartTime; - - /** contains the time value, when this operation was finished. */ - public long nEndTime; - - /** text inside log file, which identifies the start time value. */ - public java.lang.String sStartMsg; - - /** text inside log file, which identifies the end time value. */ - public java.lang.String sEndMsg; - } - - //_________________________________ - // main - - public static void main(java.lang.String[] lCmdLine) - { - int nExit = 0; - try - { - // analyze command line - ConfigHelper aCmdLine = new ConfigHelper("", lCmdLine); - java.lang.String sLogDir = aCmdLine.getString("logdir" ); - java.lang.String sDataFile = aCmdLine.getString("datafile"); - - if (sLogDir == null || sDataFile == null) - { - System.err.println("AnalyzeStartupLog lodir= datafile="); - System.err.println("E.g.: AnalyzeStartupLog lodir=c:\\temp\\logs datafile=c:\\temp\\data.csv"); - System.exit(--nExit); - } - - // get list of all log files - boolean bRecursive = true; - java.util.Vector lLogs = FileHelper.getSystemFilesFromDir(new java.io.File(sLogDir), bRecursive); - if (lLogs == null || lLogs.isEmpty()) - { - System.err.println("log dir is empty"); - System.exit(--nExit); - } - - // analyze it - java.lang.StringBuffer sOut = new java.lang.StringBuffer(1000); - sOut.append("log;t_cfg_start;t_cfg_end;t_fwk_start;t_fwk_end;t_sfx_start;t_sfx_end;t_types_start;t_types_end;t_filters_start;t_filters_end;"); - sOut.append("t_filters_swriter_start;t_filters_swriter_end;t_filters_sweb_start;t_filters_sweb_end;t_filters_sglobal_start;t_filters_sglobal_end;t_filters_scalc_start;t_filters_scalc_end;t_filters_sdraw_start;t_filters_sdraw_end;t_filters_simpress_start;t_filters_simpress_end;t_filters_schart_start;t_filters_schart_end;t_filters_smath_start;t_filters_smath_end;"); - sOut.append("t_others_start;t_others_end;d_cfg;d_fwk;d_sfx;d_types;d_filters;d_others;d_complete\n"); - - java.util.Enumeration aIt = lLogs.elements(); - while (aIt.hasMoreElements()) - { - java.io.File aLog = (java.io.File)aIt.nextElement(); - java.io.FileReader aReader = new java.io.FileReader(aLog); - java.io.BufferedReader aBuffer = new java.io.BufferedReader(aReader); - - long t_cfg_start = 0; - long t_cfg_end = 0; - - long t_fwk_start = 0; - long t_fwk_end = 0; - - long t_sfx_start = 0; - long t_sfx_end = 0; - - long t_types_start = 0; - long t_types_end = 0; - - long t_filters_start = 0; - long t_filters_end = 0; - - long t_filters_swriter_start = 0; - long t_filters_swriter_end = 0; - - long t_filters_sweb_start = 0; - long t_filters_sweb_end = 0; - - long t_filters_sglobal_start = 0; - long t_filters_sglobal_end = 0; - - long t_filters_scalc_start = 0; - long t_filters_scalc_end = 0; - - long t_filters_sdraw_start = 0; - long t_filters_sdraw_end = 0; - - long t_filters_simpress_start = 0; - long t_filters_simpress_end = 0; - - long t_filters_schart_start = 0; - long t_filters_schart_end = 0; - - long t_filters_smath_start = 0; - long t_filters_smath_end = 0; - - long t_others_start = 0; - long t_others_end = 0; - - while (true) - { - java.lang.String sLine = aBuffer.readLine(); - if (sLine == null) - break; - - if (sLine.endsWith("| framework (as96863) ::FilterCache::FilterCache : { creation ConfigItem [file=standard, version=6, mode=3]")) - t_cfg_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("| framework (as96863) ::FilterCache::FilterCache : } creation ConfigItem")) - t_cfg_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("| framework (as96863) ::FilterCache::FilterCache : { reading TypeDetection.xml")) - t_fwk_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("| framework (as96863) ::FilterCache::FilterCache : } reading TypeDetection.xml")) - t_fwk_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ framework (as96863) ::FilterCFGAccess::impl_loadTypes")) - t_types_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} framework (as96863) ::FilterCFGAccess::impl_loadTypes")) - t_types_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ framework (as96863) ::FilterCFGAccess::impl_loadFilters")) - t_filters_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} framework (as96863) ::FilterCFGAccess::impl_loadFilters")) - t_filters_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [swriter]")) - t_filters_swriter_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [swriter]")) - t_filters_swriter_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [sweb]")) - t_filters_sweb_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [sweb]")) - t_filters_sweb_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [sglobal]")) - t_filters_sglobal_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [sglobal]")) - t_filters_sglobal_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [scalc]")) - t_filters_scalc_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [scalc]")) - t_filters_scalc_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [sdraw]")) - t_filters_sdraw_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [sdraw]")) - t_filters_sdraw_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [simpress]")) - t_filters_simpress_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [simpress]")) - t_filters_simpress_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [schart]")) - t_filters_schart_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [schart]")) - t_filters_schart_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ reading FilterGroup [smath]")) - t_filters_smath_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} reading FilterGroup [smath]")) - t_filters_smath_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("{ framework (as96863) ::FilterCFGAccess::impl_loadDetectors")) - t_others_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} framework (as96863) ::FilterCFGAccess::impl_loadContentHandlers")) - t_others_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} framework (as96863) ::FilterCache::FilterCache")) - t_sfx_start = new java.lang.Long(sLine.substring(0, 6)).longValue(); - else - if (sLine.endsWith("} desktop (lo119109) OfficeWrapper::OfficeWrapper")) - t_sfx_end = new java.lang.Long(sLine.substring(0, 6)).longValue(); - } - - sOut.append(aLog.getName() ); - sOut.append(";" ); - sOut.append(t_cfg_start ); - sOut.append(";" ); - sOut.append(t_cfg_end ); - sOut.append(";" ); - sOut.append(t_fwk_start ); - sOut.append(";" ); - sOut.append(t_fwk_end ); - sOut.append(";" ); - sOut.append(t_sfx_start ); - sOut.append(";" ); - sOut.append(t_sfx_end ); - sOut.append(";" ); - sOut.append(t_types_start ); - sOut.append(";" ); - sOut.append(t_types_end ); - sOut.append(";" ); - sOut.append(t_filters_start ); - sOut.append(";" ); - sOut.append(t_filters_end ); - sOut.append(";" ); - - sOut.append(t_filters_swriter_start ); - sOut.append(";" ); - sOut.append(t_filters_swriter_end ); - sOut.append(";" ); - sOut.append(t_filters_sweb_start ); - sOut.append(";" ); - sOut.append(t_filters_sweb_end ); - sOut.append(";" ); - sOut.append(t_filters_sglobal_start ); - sOut.append(";" ); - sOut.append(t_filters_sglobal_end ); - sOut.append(";" ); - sOut.append(t_filters_scalc_start ); - sOut.append(";" ); - sOut.append(t_filters_scalc_end ); - sOut.append(";" ); - sOut.append(t_filters_sdraw_start ); - sOut.append(";" ); - sOut.append(t_filters_sdraw_end ); - sOut.append(";" ); - sOut.append(t_filters_simpress_start ); - sOut.append(";" ); - sOut.append(t_filters_simpress_end ); - sOut.append(";" ); - sOut.append(t_filters_schart_start ); - sOut.append(";" ); - sOut.append(t_filters_schart_end ); - sOut.append(";" ); - sOut.append(t_filters_smath_start ); - sOut.append(";" ); - sOut.append(t_filters_smath_end ); - sOut.append(";" ); - - sOut.append(t_others_start ); - sOut.append(";" ); - sOut.append(t_others_end ); - sOut.append(";" ); - sOut.append(t_cfg_end -t_cfg_start ); - sOut.append(";" ); - sOut.append(t_fwk_end -t_fwk_start ); - sOut.append(";" ); - sOut.append(t_sfx_end -t_sfx_start ); - sOut.append(";" ); - sOut.append(t_types_end -t_types_start ); - sOut.append(";" ); - sOut.append(t_filters_end-t_filters_start); - sOut.append(";" ); - sOut.append(t_others_end -t_others_start ); - sOut.append(";" ); - sOut.append(t_others_end -t_cfg_start ); - sOut.append("\n" ); - - aBuffer.close(); - } - - java.io.FileWriter aCSV = new java.io.FileWriter(sDataFile); - java.lang.String sData = sOut.toString(); - aCSV.write(sData, 0, sData.length()); - aCSV.flush(); - aCSV.close(); - } - catch(java.lang.Throwable exAny) - { - System.err.println(exAny.getMessage()); - exAny.printStackTrace(); - System.exit(--nExit); - } - - System.exit(0); - } -} diff --git a/filter/source/config/tools/utils/Cache.java b/filter/source/config/tools/utils/Cache.java deleted file mode 100644 index fa87538a6565..000000000000 --- a/filter/source/config/tools/utils/Cache.java +++ /dev/null @@ -1,2444 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: Cache.java,v $ - * $Revision: 1.7 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -package com.sun.star.filter.config.tools.utils; - - -//_______________________________________________ - -/** - * It implements a container for all possible entries which are part of the type - * and filter mechanism of an office - means all items of the configuration file - * "TypeDetection". How these entries will be readed or written can be switch - * in different modes. That would make it possible to edit an xml directly or - * to contact a running office instance. - * - * - */ -public class Cache -{ - //___________________________________________ - // public const - - /** identifies a file type item of this cache. */ - public static final int E_TYPE = 0; - - /** identifies a filter item of this cache. */ - public static final int E_FILTER = 1; - - /** identifies a detect service item of this cache. */ - public static final int E_DETECTSERVICE = 2; - - /** identifies a frame loader item of this cache. */ - public static final int E_FRAMELOADER = 3; - - /** identifies a content handler item of this cache. */ - public static final int E_CONTENTHANDLER = 4; - - /** indicates an unsupported xml format => error! */ - public static final int FORMAT_UNSUPPORTED = -1; - - /** identify the configuration format of an office 6.0. - * The own formated data string is used. */ - public static final int FORMAT_60 = 0; - - /** identify the configuration format of an office 6.y. - * Properties are realy xml tags again. */ - public static final int FORMAT_6Y = 1; - - /** identify the configuration format which is used inside - * this tooling project. */ - public static final int FORMAT_INTERNAL = 2; - - /** right value for a command line parameter to define a 6.0 version. */ - public static final java.lang.String CMDVAL_FORMAT_60 = "6.0"; - - /** right value for a command line parameter to define a 6.Y version. */ - public static final java.lang.String CMDVAL_FORMAT_6Y = "6.Y"; - - /** right value for a command line parameter to define an internal xml version! */ - public static final java.lang.String CMDVAL_FORMAT_INTERNAL = "internal"; - - // general - public static final java.lang.String PROPNAME_DATA = "Data"; - public static final java.lang.String PROPNAME_NAME = "Name"; - public static final java.lang.String PROPNAME_UINAME = "UIName"; - public static final java.lang.String PROPNAME_UINAMES = "UINames"; - - // type 6.0 ... - public static final java.lang.String PROPNAME_MEDIATYPE = "MediaType"; - public static final java.lang.String PROPNAME_PREFERRED = "Preferred"; - public static final java.lang.String PROPNAME_CLIPBOARDFORMAT = "ClipboardFormat"; - public static final java.lang.String PROPNAME_DOCUMENTICONID = "DocumentIconID"; - public static final java.lang.String PROPNAME_URLPATTERN = "URLPattern"; - public static final java.lang.String PROPNAME_EXTENSIONS = "Extensions"; - // ... +6.y - public static final java.lang.String PROPNAME_UIORDER = "UIOrder"; - public static final java.lang.String PROPNAME_PREFERREDFILTER = "PreferredFilter"; - public static final java.lang.String PROPNAME_DETECTSERVICE = "DetectService"; - public static final java.lang.String PROPNAME_FRAMELOADER = "FrameLoader"; - public static final java.lang.String PROPNAME_CONTENTHANDLER = "ContentHandler"; - - // filter - public static final java.lang.String PROPNAME_DOCUMENTSERVICE = "DocumentService"; - public static final java.lang.String PROPNAME_FILEFORMATVERSION = "FileFormatVersion"; - public static final java.lang.String PROPNAME_FILTERSERVICE = "FilterService"; - public static final java.lang.String PROPNAME_FLAGS = "Flags"; - public static final java.lang.String PROPNAME_ORDER = "Order"; // -6.y - public static final java.lang.String PROPNAME_TEMPLATENAME = "TemplateName"; - public static final java.lang.String PROPNAME_TYPE = "Type"; - public static final java.lang.String PROPNAME_UICOMPONENT = "UIComponent"; - public static final java.lang.String PROPNAME_USERDATA = "UserData"; - - // frame loader / detect services / content handler - public static final java.lang.String PROPNAME_TYPES = "Types"; - - //___________________________________________ - // private const - - private static final java.lang.String FILTERSERVICE_NATIVEWARPPER = "com.sun.star.filter.NativeFilterWrapper"; - private static final java.lang.String GENERIC_DETECTSERVICE = "com.sun.star.comp.office.FrameLoader"; - - /** its the name of the cfg set, which contains all types. */ - private static final java.lang.String CFGNODE_TYPES = "Types"; - - /** its the name of the cfg set, which contains all filters. */ - private static final java.lang.String CFGNODE_FILTERS = "Filters"; - - /** its the name of the cfg set, which contains all detect services. */ - private static final java.lang.String CFGNODE_DETECTSERVICES = "DetectServices"; - - /** its the name of the cfg set, which contains all frame loaders. */ - private static final java.lang.String CFGNODE_FRAMELOADERS = "FrameLoaders"; - - /** its the name of the cfg set, which contains all content handlers. */ - private static final java.lang.String CFGNODE_CONTENTHANDLERS = "ContentHandlers"; - - // names for filter flags - private static final java.lang.String FLAGNAME_3RDPARTYFILTER = "3RDPARTYFILTER"; - private static final java.lang.String FLAGNAME_ALIEN = "ALIEN"; - private static final java.lang.String FLAGNAME_ASYNCHRON = "ASYNCHRON"; - private static final java.lang.String FLAGNAME_BROWSERPREFERRED = "BROWSERPREFERRED"; - private static final java.lang.String FLAGNAME_CONSULTSERVICE = "CONSULTSERVICE"; - private static final java.lang.String FLAGNAME_DEFAULT = "DEFAULT"; - private static final java.lang.String FLAGNAME_EXPORT = "EXPORT"; - private static final java.lang.String FLAGNAME_IMPORT = "IMPORT"; - private static final java.lang.String FLAGNAME_INTERNAL = "INTERNAL"; - private static final java.lang.String FLAGNAME_NOTINCHOOSER = "NOTINCHOOSER"; - private static final java.lang.String FLAGNAME_NOTINFILEDIALOG = "NOTINFILEDIALOG"; - private static final java.lang.String FLAGNAME_NOTINSTALLED = "NOTINSTALLED"; - private static final java.lang.String FLAGNAME_OWN = "OWN"; - private static final java.lang.String FLAGNAME_PACKED = "PACKED"; - private static final java.lang.String FLAGNAME_PREFERRED = "PREFERRED"; - private static final java.lang.String FLAGNAME_READONLY = "READONLY"; - private static final java.lang.String FLAGNAME_SILENTEXPORT = "SILENTEXPORT"; - private static final java.lang.String FLAGNAME_TEMPLATE = "TEMPLATE"; - private static final java.lang.String FLAGNAME_TEMPLATEPATH = "TEMPLATEPATH"; - private static final java.lang.String FLAGNAME_USESOPTIONS = "USESOPTIONS"; - - private static final java.lang.String FLAGNAME_COMBINED = "COMBINED"; - private static final java.lang.String FLAGNAME_SUPPORTSSELECTION= "SUPPORTSSELECTION"; - - // values for filter flags - private static final int FLAGVAL_3RDPARTYFILTER = 0x00080000; // 524288 - private static final int FLAGVAL_ALIEN = 0x00000040; // 64 - private static final int FLAGVAL_ALL = 0xffffffff; // 4294967295 - private static final int FLAGVAL_ASYNCHRON = 0x00004000; // 16384 - private static final int FLAGVAL_BROWSERPREFERRED = 0x00400000; // 4194304 - private static final int FLAGVAL_CONSULTSERVICE = 0x00040000; // 262144 - private static final int FLAGVAL_DEFAULT = 0x00000100; // 256 - private static final int FLAGVAL_EXPORT = 0x00000002; // 2 - private static final int FLAGVAL_IMPORT = 0x00000001; // 1 - private static final int FLAGVAL_INTERNAL = 0x00000008; // 8 - private static final int FLAGVAL_NOTINCHOOSER = 0x00002000; // 8192 - private static final int FLAGVAL_NOTINFILEDIALOG = 0x00001000; // 4096 - private static final int FLAGVAL_NOTINSTALLED = 0x00020000; // 131072 - private static final int FLAGVAL_OWN = 0x00000020; // 32 - private static final int FLAGVAL_PACKED = 0x00100000; // 1048576 - private static final int FLAGVAL_PREFERRED = 0x10000000; // 268435456 - private static final int FLAGVAL_READONLY = 0x00010000; // 65536 - private static final int FLAGVAL_SILENTEXPORT = 0x00200000; // 2097152 - private static final int FLAGVAL_TEMPLATE = 0x00000004; // 4 - private static final int FLAGVAL_TEMPLATEPATH = 0x00000010; // 16 - private static final int FLAGVAL_USESOPTIONS = 0x00000080; // 128 - - private static final int FLAGVAL_COMBINED = 0x00800000; // ... - private static final int FLAGVAL_SUPPORTSSELECTION = 0x00000400; // 1024 - - //___________________________________________ - // member - - /** list of all located types. - * Format: [string,HashMap] - */ - private java.util.HashMap m_lTypes; - - /** list of all located filters. - * Format: [string,HashMap] - */ - private java.util.HashMap m_lFilters; - - /** list of all located detect services. - * Format: [string,HashMap] - */ - private java.util.HashMap m_lDetectServices; - - /** list of all located frame loader. - * Format: [string,HashMap] - */ - private java.util.HashMap m_lFrameLoaders; - - /** list of all located content handler. - * Format: [string,HashMap] - */ - private java.util.HashMap m_lContentHandlers; - - /** contains all analyzed relations between - * filters and types. The key is an internal - * type name (can be used as reference into the - * list m_lTypes) and the value is a Vector of all - * internal filter names, which are registered for - * this type. - * Format: [string, Vector] - */ - private java.util.HashMap m_lFilterToTypeRegistrations; - - private int m_nDoubleRegisteredFilters; - private int m_nTypesForFilters; - private int m_nTypesForDetectServices; - private int m_nTypesForFrameLoaders; - private int m_nTypesForContentHandlers; - - /** can be used to log different informations. */ - private Logger m_aDebug; - - //___________________________________________ - // interface - - /** standard ctor. - * - * Initialize an empty cache instance. You have to use - * on of the fromXXX() methods to fill it from different - * sources with content. - */ - public Cache(Logger aDebug) - { - reset(); - m_aDebug = aDebug; - } - - //___________________________________________ - - /** free memory and set default values on all members. - */ - public synchronized void reset() - { - m_lTypes = new java.util.HashMap(); - m_lFilters = new java.util.HashMap(); - m_lFrameLoaders = new java.util.HashMap(); - m_lDetectServices = new java.util.HashMap(); - m_lContentHandlers = new java.util.HashMap(); - m_lFilterToTypeRegistrations = new java.util.HashMap(); - m_aDebug = new Logger(); - m_nDoubleRegisteredFilters = 0; - m_nTypesForFilters = 0; - m_nTypesForDetectServices = 0; - m_nTypesForFrameLoaders = 0; - m_nTypesForContentHandlers = 0; - } - - //___________________________________________ - - /** converts a string representation of an xml format - * to its int value, which must be used at some interface - * methods of this cache. - * - * If the given string does not match to any well known format, - * the return value will be FORMAT_UNSUPPORTED. The calli have to - * check that. Otherwhise a called interface method at this cache - * instance will be rejected by an exception! - * - * @param sFormat - * the string representation - * Must be one of our public const values from type CMDVAL_FORMAT_xxx. - * - * @return [int] - * the int representation. - * Will be one of our public const values from type FORMAT_xxx. - */ - public static int mapFormatString2Format(java.lang.String sFormat) - { - int nFormat = FORMAT_UNSUPPORTED; - if (sFormat.equalsIgnoreCase(CMDVAL_FORMAT_60)) - nFormat = FORMAT_60; - else - if (sFormat.equalsIgnoreCase(CMDVAL_FORMAT_6Y)) - nFormat = FORMAT_6Y; - else - if (sFormat.equalsIgnoreCase(CMDVAL_FORMAT_INTERNAL)) - nFormat = FORMAT_INTERNAL; - return nFormat; - } - - //___________________________________________ - - /** return some statistic values. - * - * Such values can be: - count of container items, - * - ... - * - * @return [java.lang.String] - * a formated string, which contains al statistic data. - */ - public synchronized java.lang.String getStatistics() - { - java.lang.StringBuffer sBuffer = new java.lang.StringBuffer(256); - - sBuffer.append("types = "+m_lTypes.size() +"\n"); - sBuffer.append("filters = "+m_lFilters.size() +"\n"); - sBuffer.append("detect services = "+m_lDetectServices.size() +"\n"); - sBuffer.append("frame loaders = "+m_lFrameLoaders.size() +"\n"); - sBuffer.append("content handler = "+m_lContentHandlers.size() +"\n"); - sBuffer.append("double registered filters = "+m_nDoubleRegisteredFilters+"\n"); - sBuffer.append("types used by filters = "+m_nTypesForFilters +"\n"); - sBuffer.append("types used by detect services = "+m_nTypesForDetectServices +"\n"); - sBuffer.append("types used by frame loaders = "+m_nTypesForFrameLoaders +"\n"); - sBuffer.append("types used by content handlers = "+m_nTypesForContentHandlers+"\n"); - - return sBuffer.toString(); - } - - //___________________________________________ - - /** reset this cache and fill it with new values using the given XML file. - * - * @param aXML - * must be a system file of a suitable XML file, which - * include all neccessary type/filter items. - * - * @param nFormat - * identifies the format of the specified xml file, - * which must be interpreted. - */ - public synchronized void fromXML(java.io.File aXML , - int nFormat) - throws java.lang.Exception - { - // clear this cache - reset(); - - // parse it - javax.xml.parsers.DocumentBuilderFactory aFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); - /* Attention: - * This call is important. It force right handling of entities during parsing and(!) - * writing. It let all possible signs for entities or it's quoted representations - * untouched. So this class don't change the original signs of the original file. - * Means: - *
    - *
  • (') => (')
  • - *
  • (") => (")
  • - *
  • (>) => (>)
  • - *
  • (<) => (<)
  • - *
  • (>) => (>)
  • - *
  • (&) => (&)
  • - *
  • ...
  • - *
- */ - - System.out.println("TODO: must be adapted to java 1.3 :-("); - System.exit(-1); -//TODO_JAVA aFactory.setExpandEntityReferences(false); - - javax.xml.parsers.DocumentBuilder aBuilder = aFactory.newDocumentBuilder(); - org.w3c.dom.Document aDOM = aBuilder.parse(aXML); - org.w3c.dom.Element aRoot = aDOM.getDocumentElement(); - - // step over all sets - java.util.Vector lSetNodes = XMLHelper.extractChildNodesByTagName(aRoot, XMLHelper.XMLTAG_NODE); - java.util.Enumeration it1 = lSetNodes.elements(); - while (it1.hasMoreElements()) - { - // try to find out, which set should be read - org.w3c.dom.Node aSetNode = (org.w3c.dom.Node)it1.nextElement(); - java.lang.String sSetName = XMLHelper.extractNodeAttribByName(aSetNode, XMLHelper.XMLATTRIB_OOR_NAME); - if (sSetName == null) - throw new java.io.IOException("unsupported format: could not extract set name on node ...\n"+aSetNode); - - // map some generic interfaces to the right members! - int eType = -1 ; - java.util.HashMap rMap = null; - - if (sSetName.equals(CFGNODE_TYPES)) - { - eType = E_TYPE; - rMap = m_lTypes; - } - else - if (sSetName.equals(CFGNODE_FILTERS)) - { - eType = E_FILTER; - rMap = m_lFilters; - } - else - if (sSetName.equals(CFGNODE_FRAMELOADERS)) - { - eType = E_FRAMELOADER; - rMap = m_lFrameLoaders; - } - else - if (sSetName.equals(CFGNODE_DETECTSERVICES)) - { - eType = E_DETECTSERVICE; - rMap = m_lDetectServices; - } - else - if (sSetName.equals(CFGNODE_CONTENTHANDLERS)) - { - eType = E_CONTENTHANDLER; - rMap = m_lContentHandlers; - } - else - throw new java.io.IOException("unsupported format: unknown set name [\""+sSetName+"\"] detected on node ...\n"+aSetNode); - - // load all set entries - java.util.Vector lChildNodes = XMLHelper.extractChildNodesByTagName(aSetNode, XMLHelper.XMLTAG_NODE); - java.util.Enumeration it2 = lChildNodes.elements(); - while (it2.hasMoreElements()) - { - org.w3c.dom.Node aChildNode = (org.w3c.dom.Node)it2.nextElement(); - java.lang.String sChildName = XMLHelper.extractNodeAttribByName(aChildNode, XMLHelper.XMLATTRIB_OOR_NAME); - if (sChildName == null) - throw new java.io.IOException("unsupported format: could not extract child node name on node ...\n"+aChildNode); - java.util.HashMap aPropSet = null; - - // Note: Our internal format is different from the source format! - java.util.HashMap aTempSet = XMLHelper.convertNodeToPropSet(aChildNode); - switch(eType) - { - case E_TYPE : - { - aPropSet = Cache.convertTypePropsToInternal(aTempSet, nFormat); - m_aDebug.setDetailedInfo("type [\""+sChildName+"\"] converted to internal format"); - } - break; - - case E_FILTER : - { - aPropSet = Cache.convertFilterPropsToInternal(aTempSet, nFormat); - m_aDebug.setDetailedInfo("filter [\""+sChildName+"\"] converted to internal format"); - } - break; - - case E_DETECTSERVICE : - { - aPropSet = Cache.convertDetectServicePropsToInternal(aTempSet, nFormat); - m_aDebug.setDetailedInfo("detect service [\""+sChildName+"\"] converted to internal format"); - } - break; - - case E_FRAMELOADER : - { - aPropSet = Cache.convertFrameLoaderPropsToInternal(aTempSet, nFormat); - m_aDebug.setDetailedInfo("frame loader [\""+sChildName+"\"] converted to internal format"); - } - break; - - case E_CONTENTHANDLER : - { - aPropSet = Cache.convertContentHandlerPropsToInternal(aTempSet, nFormat); - m_aDebug.setDetailedInfo("content handler [\""+sChildName+"\"] converted to internal format"); - } - break; - } - m_aDebug.setDetailedInfo("props = "+aTempSet); - rMap.put(sChildName, aPropSet); - } - } - } - - //___________________________________________ - - /** create some hml views of the current content of this cache. - * - * The given directory is used to create different html files - * there. Every of them show another aspect of this cache. - * E.g.: - all type/filter properties - * - relation ships between types/filters/loaders etc. - * - * @param aDirectory - * points to a system directory, which - * can be used completely(!) to generate - * the results there. - * - * @param nFormat - * specify in which context the cache items should be - * interpreted. - */ - public synchronized void toHTML(java.io.File aDirectory, - int nFormat , - java.lang.String sEncoding ) - throws java.lang.Exception - { - if (nFormat != FORMAT_6Y) - throw new java.lang.Exception("HTML views are supported for the new 6.y format only yet."); - - java.lang.StringBuffer sRelationView = new java.lang.StringBuffer(1000); - sRelationView.append("
Relation View
"); - sRelationView.append(""); - sRelationView.append(""); - - java.util.Iterator aIt = m_lTypes.keySet().iterator(); - while (aIt.hasNext()) - { - java.lang.String sType = (java.lang.String)aIt.next(); - java.util.HashMap aType = (java.util.HashMap)m_lTypes.get(sType); - - sRelationView.append(""); - sRelationView.append(""); - - java.lang.String sVal = (java.lang.String)aType.get(PROPNAME_DETECTSERVICE); - if (sVal == null || sVal.length()<1) - sRelationView.append(""); - else - sRelationView.append(""); - - sVal = (java.lang.String)aType.get(PROPNAME_PREFERREDFILTER); - if (sVal == null || sVal.length()<1) - sRelationView.append(""); - else - sRelationView.append(""); - - sVal = (java.lang.String)aType.get(PROPNAME_FRAMELOADER); - if (sVal == null || sVal.length()<1) - sRelationView.append(""); - else - sRelationView.append(""); - - sVal = (java.lang.String)aType.get(PROPNAME_CONTENTHANDLER); - if (sVal == null || sVal.length()<1) - sRelationView.append(""); - else - sRelationView.append(""); - - sRelationView.append(""); - } - - sRelationView.append("
typedetect servicepreferred filterframe loadercontent handler
"+sType+" - "+sVal+" - "+sVal+" - "+sVal+" - "+sVal+"
"); - sRelationView.append(""); - - FileHelper.writeEncodedBufferToFile(new java.io.File(aDirectory, "relation_view.html"), sEncoding, false, sRelationView); - - java.util.HashMap lFilters2TypeRegistration = new java.util.HashMap(); - aIt = m_lFilters.keySet().iterator(); - while (aIt.hasNext()) - { - java.lang.String sFilter = (java.lang.String)aIt.next(); - java.util.HashMap aFilter = (java.util.HashMap)m_lFilters.get(sFilter); - java.lang.String sType = (java.lang.String)aFilter.get(PROPNAME_TYPE); - - java.util.Vector lFilters = (java.util.Vector)lFilters2TypeRegistration.get(sType); - if (lFilters == null) - lFilters = new java.util.Vector(); - lFilters.add(sFilter); - lFilters2TypeRegistration.put(sType, lFilters); - } - - java.lang.StringBuffer sType2FiltersView = new java.lang.StringBuffer(1000); - sType2FiltersView.append("
Type2Filters View
"); - sType2FiltersView.append(""); - sType2FiltersView.append(""); - - aIt = lFilters2TypeRegistration.keySet().iterator(); - while (aIt.hasNext()) - { - java.lang.String sType = (java.lang.String)aIt.next(); - java.util.Vector lFilters = (java.util.Vector)lFilters2TypeRegistration.get(sType); - - sType2FiltersView.append(""); - } - - sType2FiltersView.append("
typefilters
"+sType+""); - java.util.Enumeration aEn = lFilters.elements(); - while(aEn.hasMoreElements()) - sType2FiltersView.append(aEn.nextElement()+"
"); - sType2FiltersView.append("
"); - sType2FiltersView.append(""); - - FileHelper.writeEncodedBufferToFile(new java.io.File(aDirectory, "type2filters_view.html"), sEncoding, false, sType2FiltersView); - } - - //___________________________________________ - - /** converts all items of this cache to its xml representation - * and write it to the given file. - * - * @param aXML - * the target file for output. - * - * @param nFormat - * the requested xml format. - * see const values FORMAT_xxx too. - * - * @param sEncoding - * specify the file encoding for the generated xml file. - * - * @throws [java.lang.Exception] - * if something fail during convertion. - */ - public synchronized void toXML(java.io.File aXML , - int nFormat , - java.lang.String sEncoding) - throws java.lang.Exception - { - java.lang.StringBuffer sXML = new java.lang.StringBuffer(500000); - - for (int i=0; i<5; ++i) - { - // define right sub container - java.lang.String sSetName = null; - java.util.HashMap rMap = null; - int eType = -1; - - switch(i) - { - case 0 : - { - sSetName = CFGNODE_TYPES; - rMap = m_lTypes; - eType = E_TYPE; - } - break; - - case 1 : - { - sSetName = CFGNODE_FILTERS; - rMap = m_lFilters; - eType = E_FILTER; - } - break; - - case 2 : - { - sSetName = CFGNODE_DETECTSERVICES; - rMap = m_lDetectServices; - eType = E_DETECTSERVICE; - } - break; - - case 3 : - { - sSetName = CFGNODE_FRAMELOADERS; - rMap = m_lFrameLoaders; - eType = E_FRAMELOADER; - } - break; - - case 4 : - { - sSetName = CFGNODE_CONTENTHANDLERS; - rMap = m_lContentHandlers; - eType = E_CONTENTHANDLER; - } - break; - } - - // generate set - sXML.append("\n"); - java.util.Iterator it = rMap.keySet().iterator(); - while(it.hasNext()) - { - java.lang.String sItem = (java.lang.String)it.next(); - sXML.append("\n"); - sXML.append(getItemAsXML(eType, sItem, nFormat)); - sXML.append("\n"); - } - sXML.append("\n"); - } - - java.io.FileOutputStream aStream = new java.io.FileOutputStream(aXML.getAbsolutePath(), false); - java.io.OutputStreamWriter aWriter = new java.io.OutputStreamWriter(aStream, sEncoding); - java.lang.String sOut = sXML.toString(); - aWriter.write(sOut, 0, sOut.length()); - aWriter.flush(); - aWriter.close(); - } - - //___________________________________________ - - /** converts a type property set from internal format - * to an external one. - * - * @param aMap - * points to the item, which should be converted. - * - * @param nFormat - * specify the requested output format. - * - * @return [java.util.HashMap] - * contains the properties in the requested format. - * - * @throws [java.lang.Exception - * if something fail during convertion. - */ - private static java.util.HashMap convertTypePropsToExternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - java.util.HashMap aResultMap = new java.util.HashMap(); - // copy Name property ... if it exists! - if (aMap.containsKey(PROPNAME_NAME)) - aResultMap.put(PROPNAME_NAME, aMap.get(PROPNAME_NAME)); - switch(nFormat) - { - //----------------------------------- - case FORMAT_60 : - { - // copy UIName property unchanged - aResultMap.put(PROPNAME_UINAME, aMap.get(PROPNAME_UINAME)); - - // ignore properties "UIOrder", "PreferredFilter", "DetectService" - // They are not supported for 6.0 types. - - // pack all other properties to one "Data" string value - java.lang.StringBuffer sData = new java.lang.StringBuffer(256); - - sData.append(aMap.get(PROPNAME_PREFERRED)); - sData.append(","); - sData.append(aMap.get(PROPNAME_MEDIATYPE)); - sData.append(","); - sData.append(aMap.get(PROPNAME_CLIPBOARDFORMAT)); - sData.append(","); - - java.util.Vector lList = (java.util.Vector)aMap.get(PROPNAME_URLPATTERN); - int c = lList.size(); - int i = 0; - for (i=0; i aExpandedMap["UIName"] - * aMap["Data" ] => aExpandedMap["Preferred" ], aExpandedMap["MediaType"] etc. ... - * - * @param aMap - * points to the item, which should be converted. - - * @param nFormat - * specify the external format. - * - * @return [java.util.HashMap] - * The new map in internal format. - */ - private static java.util.HashMap convertTypePropsToInternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - java.util.HashMap aResultMap = new java.util.HashMap(); - // copy Name property ... if it exists! - if (aMap.containsKey(PROPNAME_NAME)) - aResultMap.put(PROPNAME_NAME, aMap.get(PROPNAME_NAME)); - switch(nFormat) - { - //----------------------------------- - case FORMAT_60 : - { - // copy UIName property unchanged! - aResultMap.put(PROPNAME_UINAME, aMap.get(PROPNAME_UINAME)); - - // generate new property "UIOrder" - // Its the moved property "Order" of filters for versions >= 6.y! - aResultMap.put(PROPNAME_UIORDER, new java.lang.Integer(0)); - - // generate new property "PreferredFilter" - // Its a the moved filter flag "Preferred" for versions >= 6.y! - aResultMap.put(PROPNAME_PREFERREDFILTER, new java.lang.String()); - - // generate new property "DetectService" - // Every type know its detector diretcly from now. No search - // will be neccessary any longer. - aResultMap.put(PROPNAME_DETECTSERVICE, new java.lang.String()); - - // analyze the Data property of the original map - // and copy its results (means all expanded properties) - // to the result map. - java.lang.String sDataVal = (java.lang.String)aMap.get(PROPNAME_DATA); - java.util.Vector lTokens = Cache.splitTokenString(sDataVal, ","); - - int t = 0; - java.util.Enumeration it = lTokens.elements(); - while (it.hasMoreElements()) - { - java.lang.String sToken = (java.lang.String)it.nextElement(); - switch(t) - { - case 0 : - aResultMap.put(PROPNAME_PREFERRED, new java.lang.Boolean(sToken)); - break; - case 1 : - aResultMap.put(PROPNAME_MEDIATYPE, sToken); - break; - case 2 : - { - /*HACK ersetze %20 mit " " ...*/ - int ni = sToken.indexOf("%20"); - if (ni!=-1) - { - java.lang.String sPatch = sToken.substring(0,ni) + " " + sToken.substring(ni+3); - sToken = sPatch; - } - aResultMap.put(PROPNAME_CLIPBOARDFORMAT, sToken); - } - break; - case 3 : - aResultMap.put(PROPNAME_URLPATTERN, Cache.splitTokenString(sToken, ";")); - break; - case 4 : - aResultMap.put(PROPNAME_EXTENSIONS, Cache.splitTokenString(sToken, ";")); - break; - case 5 : - aResultMap.put(PROPNAME_DOCUMENTICONID, new java.lang.Integer(sToken)); - break; - default : - throw new java.lang.Exception("unsupported format for data value of a type \""+aMap.get(PROPNAME_NAME)+"\" detected."); - } - ++t; - } - } - break; - - //----------------------------------- - case FORMAT_6Y : - { - // copy all supported properties directly - aResultMap.put(PROPNAME_PREFERRED , aMap.get(PROPNAME_PREFERRED )); - aResultMap.put(PROPNAME_MEDIATYPE , aMap.get(PROPNAME_MEDIATYPE )); - aResultMap.put(PROPNAME_CLIPBOARDFORMAT, aMap.get(PROPNAME_CLIPBOARDFORMAT)); - aResultMap.put(PROPNAME_URLPATTERN , aMap.get(PROPNAME_URLPATTERN )); - aResultMap.put(PROPNAME_EXTENSIONS , aMap.get(PROPNAME_EXTENSIONS )); - aResultMap.put(PROPNAME_DOCUMENTICONID , aMap.get(PROPNAME_DOCUMENTICONID )); - aResultMap.put(PROPNAME_UINAME , aMap.get(PROPNAME_UINAME )); - aResultMap.put(PROPNAME_UIORDER , aMap.get(PROPNAME_UIORDER )); - aResultMap.put(PROPNAME_PREFERREDFILTER, aMap.get(PROPNAME_PREFERREDFILTER)); - aResultMap.put(PROPNAME_DETECTSERVICE , aMap.get(PROPNAME_DETECTSERVICE )); - } - break; - - //----------------------------------- - default : - throw new java.lang.Exception("unknown format"); - } - - return aResultMap; - } - - //___________________________________________ - - /** converts a filter property set (using an external format) to - * our internal cache format. - * - * Especialy the data format string will be expanded - * to its real properties. - * - * Schema: - * aMap["UIName"] => aExpandedMap["UIName"] - * aMap["Data" ] => aExpandedMap["Order" ], aExpandedMap["Flags"] etc. ... - * - * @param aMap - * points to the item, which should be converted. - * - * @param nFormat - * specify the external format. - * - * @return [java.util.HashMap] - * The new map in internal format. - */ - private static java.util.HashMap convertFilterPropsToInternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - java.util.HashMap aResultMap = new java.util.HashMap(); - // copy Name property ... if it exists! - if (aMap.containsKey(PROPNAME_NAME)) - aResultMap.put(PROPNAME_NAME, aMap.get(PROPNAME_NAME)); - switch(nFormat) - { - //----------------------------------- - case FORMAT_60 : - { - // copy UIName property - aResultMap.put(PROPNAME_UINAME, aMap.get(PROPNAME_UINAME)); - - // analyze the Data property of the original map - // and copy its results (means all expanded properties) - // to the result map. - java.lang.String sDataVal = (java.lang.String)aMap.get(PROPNAME_DATA); - java.util.Vector lTokens = Cache.splitTokenString(sDataVal, ","); - - int t = 0; - java.util.Enumeration it = lTokens.elements(); - while (it.hasMoreElements()) - { - java.lang.String sToken = (java.lang.String)it.nextElement(); - switch(t) - { - case 0 : - aResultMap.put(PROPNAME_ORDER, new java.lang.Integer(sToken)); - break; - case 1 : - aResultMap.put(PROPNAME_TYPE, sToken); - break; - case 2 : - aResultMap.put(PROPNAME_DOCUMENTSERVICE, sToken); - break; - case 3 : - aResultMap.put(PROPNAME_FILTERSERVICE, sToken); - break; - case 4 : - aResultMap.put(PROPNAME_FLAGS, new java.lang.Integer(sToken)); - break; - case 5 : - aResultMap.put(PROPNAME_USERDATA, Cache.splitTokenString(sToken, ";")); - break; - case 6 : - aResultMap.put(PROPNAME_FILEFORMATVERSION, new java.lang.Integer(sToken)); - break; - case 7 : - aResultMap.put(PROPNAME_TEMPLATENAME, sToken); - break; - case 8 : - aResultMap.put(PROPNAME_UICOMPONENT, sToken); - break; - default : - throw new java.lang.Exception("unsupported format for data value of a filter detected."); - } - ++t; - } - - // its an optional property :-) - if (!aResultMap.containsKey(PROPNAME_TEMPLATENAME)) - aResultMap.put(PROPNAME_TEMPLATENAME, new java.lang.String("")); - - // its an optional property :-) - if (!aResultMap.containsKey(PROPNAME_UICOMPONENT)) - aResultMap.put(PROPNAME_UICOMPONENT, new java.lang.String("")); - } - break; - - //----------------------------------- - case FORMAT_6Y : - { - // "Order" does not exist for 6.y versions! Use default. - aResultMap.put(PROPNAME_ORDER, new java.lang.Integer(0)); - - // "UIName" property does not exist for 6.y versions! use default. - /* TODO make it configurable :-) */ - aResultMap.put(PROPNAME_UINAME, aMap.get(PROPNAME_UINAME)); - //aResultMap.put(PROPNAME_UINAME, new java.util.HashMap()); - - // "Flags" must be converted from names to its values - java.util.Vector lFlags = (java.util.Vector)aMap.get(PROPNAME_FLAGS); - java.lang.Integer nFlags = Cache.convertFilterFlagNames2Values(lFlags); - aResultMap.put(PROPNAME_FLAGS, nFlags); - - // copy all direct supported properties - aResultMap.put(PROPNAME_TYPE , aMap.get(PROPNAME_TYPE )); - aResultMap.put(PROPNAME_DOCUMENTSERVICE , aMap.get(PROPNAME_DOCUMENTSERVICE )); - aResultMap.put(PROPNAME_FILTERSERVICE , aMap.get(PROPNAME_ORDER )); - aResultMap.put(PROPNAME_USERDATA , aMap.get(PROPNAME_USERDATA )); - aResultMap.put(PROPNAME_FILEFORMATVERSION, aMap.get(PROPNAME_FILEFORMATVERSION)); - aResultMap.put(PROPNAME_TEMPLATENAME , aMap.get(PROPNAME_TEMPLATENAME )); - aResultMap.put(PROPNAME_UICOMPONENT , aMap.get(PROPNAME_UICOMPONENT )); - } - break; - - //----------------------------------- - default : - throw new java.lang.Exception("unknown format"); - } - - return aResultMap; - } - - private static java.util.HashMap convertDetectServicePropsToInternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - /*FIXME*/ - java.util.HashMap aResultMap = aMap; - return aResultMap; - } - - private static java.util.HashMap convertFrameLoaderPropsToInternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - /*FIXME*/ - java.util.HashMap aResultMap = aMap; - return aResultMap; - } - - private static java.util.HashMap convertContentHandlerPropsToInternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - /*FIXME*/ - java.util.HashMap aResultMap = aMap; - return aResultMap; - } - - //___________________________________________ - - /** converts filter flag names to its int representation. - * - * @param lFlags - * a list of flag names. - * - * @return [java.lang.Integer] - * an integer field of all set flags. - * - * @throws [java.lang.Exception] - * for unsupported flags or empty flag fields! - */ - private static java.lang.Integer convertFilterFlagNames2Values(java.util.Vector lFlags) - throws java.lang.Exception - { - int nFlags = 0; - java.util.Enumeration it = lFlags.elements(); - while(it.hasMoreElements()) - { - java.lang.String sFlagName = (java.lang.String)it.nextElement(); - - if (sFlagName.equals(FLAGNAME_3RDPARTYFILTER)) - nFlags |= FLAGVAL_3RDPARTYFILTER; - else - if (sFlagName.equals(FLAGNAME_ALIEN)) - nFlags |= FLAGVAL_ALIEN; - else - if (sFlagName.equals(FLAGNAME_ASYNCHRON)) - nFlags |= FLAGVAL_ASYNCHRON; - else - if (sFlagName.equals(FLAGNAME_BROWSERPREFERRED)) - nFlags |= FLAGVAL_BROWSERPREFERRED; - else - if (sFlagName.equals(FLAGNAME_CONSULTSERVICE)) - nFlags |= FLAGVAL_CONSULTSERVICE; - else - if (sFlagName.equals(FLAGNAME_DEFAULT)) - nFlags |= FLAGVAL_DEFAULT; - else - if (sFlagName.equals(FLAGNAME_EXPORT)) - nFlags |= FLAGVAL_EXPORT; - else - if (sFlagName.equals(FLAGNAME_IMPORT)) - nFlags |= FLAGVAL_IMPORT; - else - if (sFlagName.equals(FLAGNAME_INTERNAL)) - nFlags |= FLAGVAL_INTERNAL; - else - if (sFlagName.equals(FLAGNAME_NOTINCHOOSER)) - nFlags |= FLAGVAL_NOTINCHOOSER; - else - if (sFlagName.equals(FLAGNAME_NOTINFILEDIALOG)) - nFlags |= FLAGVAL_NOTINFILEDIALOG; - else - if (sFlagName.equals(FLAGNAME_NOTINSTALLED)) - nFlags |= FLAGVAL_NOTINSTALLED; - else - if (sFlagName.equals(FLAGNAME_OWN)) - nFlags |= FLAGVAL_OWN; - else - if (sFlagName.equals(FLAGNAME_PACKED)) - nFlags |= FLAGVAL_PACKED; - else - if (sFlagName.equals(FLAGNAME_PREFERRED)) - nFlags |= FLAGVAL_PREFERRED; - else - if (sFlagName.equals(FLAGNAME_READONLY)) - nFlags |= FLAGVAL_READONLY; - else - if (sFlagName.equals(FLAGNAME_SILENTEXPORT)) - nFlags |= FLAGVAL_SILENTEXPORT; - else - if (sFlagName.equals(FLAGNAME_TEMPLATE)) - nFlags |= FLAGVAL_TEMPLATE; - else - if (sFlagName.equals(FLAGNAME_TEMPLATEPATH)) - nFlags |= FLAGVAL_TEMPLATEPATH; - else - if (sFlagName.equals(FLAGNAME_USESOPTIONS)) - nFlags |= FLAGVAL_USESOPTIONS; - else - if (sFlagName.equals(FLAGNAME_COMBINED)) - nFlags |= FLAGVAL_COMBINED; - else - throw new java.lang.Exception("unsupported filter flag detected: \""+sFlagName+"\""); - } - - if (nFlags == 0) - throw new java.lang.Exception("no filter flags?"); - - return new java.lang.Integer(nFlags); - } - - //___________________________________________ - - /** converts filter flag values to its string representation. - * - * @param nFlags - * the flag field as int value. - * - * @return [java.util.Vector] - * a list of flag names. - * - * @throws [java.lang.Exception] - * for unsupported flags or empty flag fields! - */ - private static java.util.Vector convertFilterFlagValues2Names(java.lang.Integer nFlags) - throws java.lang.Exception - { - java.util.Vector lFlags = new java.util.Vector(); - int field = nFlags.intValue(); - - if (field == 0) - throw new java.lang.Exception("no filter flags?"); - - if((field & FLAGVAL_IMPORT) == FLAGVAL_IMPORT) - lFlags.add(FLAGNAME_IMPORT); - - if((field & FLAGVAL_EXPORT) == FLAGVAL_EXPORT) - lFlags.add(FLAGNAME_EXPORT); - - if((field & FLAGVAL_TEMPLATE) == FLAGVAL_TEMPLATE) - lFlags.add(FLAGNAME_TEMPLATE); - - if((field & FLAGVAL_INTERNAL) == FLAGVAL_INTERNAL) - lFlags.add(FLAGNAME_INTERNAL); - - if((field & FLAGVAL_TEMPLATEPATH) == FLAGVAL_TEMPLATEPATH) - lFlags.add(FLAGNAME_TEMPLATEPATH); - - if((field & FLAGVAL_OWN) == FLAGVAL_OWN) - lFlags.add(FLAGNAME_OWN); - - if((field & FLAGVAL_ALIEN) == FLAGVAL_ALIEN) - lFlags.add(FLAGNAME_ALIEN); - - if((field & FLAGVAL_USESOPTIONS) == FLAGVAL_USESOPTIONS) - lFlags.add(FLAGNAME_USESOPTIONS); - - if((field & FLAGVAL_DEFAULT) == FLAGVAL_DEFAULT) - lFlags.add(FLAGNAME_DEFAULT); - - if((field & FLAGVAL_NOTINFILEDIALOG) == FLAGVAL_NOTINFILEDIALOG) - lFlags.add(FLAGNAME_NOTINFILEDIALOG); - - if((field & FLAGVAL_NOTINCHOOSER) == FLAGVAL_NOTINCHOOSER) - lFlags.add(FLAGNAME_NOTINCHOOSER); - - if((field & FLAGVAL_ASYNCHRON) == FLAGVAL_ASYNCHRON) - lFlags.add(FLAGNAME_ASYNCHRON); - - if((field & FLAGVAL_READONLY) == FLAGVAL_READONLY) - lFlags.add(FLAGNAME_READONLY); - - if((field & FLAGVAL_NOTINSTALLED) == FLAGVAL_NOTINSTALLED) - lFlags.add(FLAGNAME_NOTINSTALLED); - - if((field & FLAGVAL_CONSULTSERVICE) == FLAGVAL_CONSULTSERVICE) - lFlags.add(FLAGNAME_CONSULTSERVICE); - - if((field & FLAGVAL_3RDPARTYFILTER) == FLAGVAL_3RDPARTYFILTER) - lFlags.add(FLAGNAME_3RDPARTYFILTER); - - if((field & FLAGVAL_PACKED) == FLAGVAL_PACKED) - lFlags.add(FLAGNAME_PACKED); - - if((field & FLAGVAL_SILENTEXPORT) == FLAGVAL_SILENTEXPORT) - lFlags.add(FLAGNAME_SILENTEXPORT); - - if((field & FLAGVAL_BROWSERPREFERRED) == FLAGVAL_BROWSERPREFERRED) - lFlags.add(FLAGNAME_BROWSERPREFERRED); - - if((field & FLAGVAL_PREFERRED) == FLAGVAL_PREFERRED) - lFlags.add(FLAGNAME_PREFERRED); - - if((field & FLAGVAL_COMBINED) == FLAGVAL_COMBINED) - lFlags.add(FLAGNAME_COMBINED); - - if((field & FLAGVAL_COMBINED) == FLAGVAL_SUPPORTSSELECTION) - lFlags.add(FLAGNAME_SUPPORTSSELECTION); - - return lFlags; - } - - //___________________________________________ - - /** return a reference to one of our member - * lists for types/filters etc ... - * - * @param eItemType - * specify, which item map is required. - * - * @return [java.util.HashMap] - * a reference(!) to the right member. - * - * @throws [java.lang.Exception] - * if the specified map does not exist. - */ - private java.util.HashMap getItemMap(int eItemType) - throws java.lang.Exception - { - java.util.HashMap rMap = null; - switch(eItemType) - { - case E_TYPE : - rMap = m_lTypes; - break; - - case E_FILTER : - rMap = m_lFilters; - break; - - case E_DETECTSERVICE : - rMap = m_lDetectServices; - break; - - case E_FRAMELOADER : - rMap = m_lFrameLoaders; - break; - - case E_CONTENTHANDLER : - rMap = m_lContentHandlers; - break; - - default: - throw new java.lang.Exception("Invalid item map specified."); - } - return rMap; - } - - //___________________________________________ - - /** return the count of items inside a sub container - * of this cache. - * - * @param eItemType - * specify, which item map is required. - * - * @throws [java.lang.Exception] - * if the specified map does not exist. - */ - public synchronized int getItemCount(int eItemType) - throws java.lang.Exception - { - java.util.HashMap rMap = getItemMap(eItemType); - return rMap.size(); - } - - //___________________________________________ - - /** get a list of all item names of the specified - * sub container. - * - * @param eItemType - * specify, which item map is required. - * - * @throws [java.lang.Exception] - * if the specified map does not exist. - */ - public synchronized java.util.Vector getItemNames(int eItemType) - throws java.lang.Exception - { - java.util.Vector lNames = new java.util.Vector(); - java.util.HashMap rMap = getItemMap(eItemType); - java.util.Iterator it = rMap.keySet().iterator(); - while(it.hasNext()) - lNames.add(it.next()); - return lNames; - } - - //___________________________________________ - - /** get a list of all item names of the specified - * sub coontainer, where items match to given property set. - * - * Note: The given property set must exist at all - * returned items as minimum and every checked property - * value must be equals! Using of reg expressions or - * similar mechanism will not be supported here. - * - * @param eItemType - * specify, which item map is required. - * - * @param aPropSet - * the set of properties, which must - * exist at the returned item as minimum. - * - * @throws [java.lang.Exception] - * if the specified map does not exist. - */ - public synchronized java.util.Vector getMatchedItemNames(int eItemType, - java.util.HashMap aPropSet ) - throws java.lang.Exception - { - java.util.Vector lNames = new java.util.Vector(); - java.util.HashMap rMap = getItemMap(eItemType); - java.util.Iterator it = rMap.keySet().iterator(); - while(it.hasNext()) - { - java.lang.String sItemName = (java.lang.String)it.next(); - java.util.HashMap rItemProps = (java.util.HashMap)rMap.get(sItemName); - - boolean bMatch = Cache.matchPropSet(rItemProps, aPropSet); - if (bMatch) - lNames.add(sItemName); - else - { - java.lang.StringBuffer sBuffer = new java.lang.StringBuffer(1000); - sBuffer.append("entry ["+eItemType+"] \""+sItemName+"\" does not match.\n"); - sBuffer.append("\torg items = {"+rItemProps+"}\n"); - sBuffer.append("\treq items = {"+aPropSet+"}\n"); - - m_aDebug.setDetailedInfo(sBuffer.toString()); - } - } - return lNames; - } - - //___________________________________________ - - /** check if two property sets are equals in its - * shared properties. - * - * Note: Only set properties of the match set will be searched - * inside the original set. And its values must be equals. - * Using of reg expressions or similar mechanism will not - * be supported here. - * - * @param rOrgProps - * the original property set, which should be checked. - * - * @param rMatchProps - * contains the properties, which must be searched - * inside rOrgProps. - * - * @return TRUE if all properties of rMatchProps could be located - * inside rOrgProps. - */ - private static boolean matchPropSet(java.util.HashMap rOrgProps , - java.util.HashMap rMatchProps) - { - java.util.Iterator it = rMatchProps.keySet().iterator(); - while(it.hasNext()) - { - java.lang.String sMatchName = (java.lang.String)it.next(); - java.lang.Object aMatchValue = rMatchProps.get(sMatchName); - - if ( - (!rOrgProps.containsKey(sMatchName) ) || - (!rOrgProps.get(sMatchName).equals(aMatchValue)) - ) - { - return false; - } - } - return true; - } - - //___________________________________________ - - /** return a property set for the queried container item. - * - * @param eItemType - * specify, which item map is required. - * - * @param sItemName - * must be a valid item name of the specified item map. - * - * @return [java.util.HashMap] - * the property set of the queried item. - * Always different from null! - * - * @throws [java.lang.Exception] - * if the specified item does not exists or - * seems to be invalid in general (means null!). - */ - public synchronized java.util.HashMap getItem(int eItemType, - java.lang.String sItemName) - throws java.lang.Exception - { - java.util.HashMap rMap = getItemMap(eItemType); - java.util.HashMap rItem = (java.util.HashMap)rMap.get(sItemName); - if (rItem == null) - throw new java.lang.Exception("Queried item \""+sItemName+"\" does not exist inside this cache."); - return rItem; - } - - //___________________________________________ - - /** return a requested item in XML format. - * - * @param eItemType - * identify the right sub set of this cache - * inside which the requested item should exist. - * e.g. E_TYPE, E_FILTER, ... - * - * @param sItemName - * the name of the request item - * - * @param nXMLFormat - * means the format of the generated xml source. - * - * @return [java.lang.String] - * a xml formated string, which contains all properties - * for this container item. - */ - public synchronized java.lang.String getItemAsXML(int eItemType , - java.lang.String sItemName , - int nXMLFormat) - throws java.lang.Exception - { - // Note: Our internal format must be converted to the target format! - java.util.HashMap rItem = getItem(eItemType, sItemName); - java.util.HashMap rFormatedItem = null; - switch(eItemType) - { - case E_TYPE : - { - rFormatedItem = Cache.convertTypePropsToExternal(rItem, nXMLFormat); - m_aDebug.setGlobalInfo("type to external \""+sItemName+"\""); - } - break; - - case E_FILTER : - { - rFormatedItem = Cache.convertFilterPropsToExternal(rItem, nXMLFormat); - m_aDebug.setGlobalInfo("filter to external \""+sItemName+"\""); - } - break; - - case E_DETECTSERVICE : - { - rFormatedItem = Cache.convertDetectServicePropsToExternal(rItem, nXMLFormat); - m_aDebug.setGlobalInfo("detect service to external \""+sItemName+"\""); - } - break; - - case E_FRAMELOADER : - { - rFormatedItem = Cache.convertFrameLoaderPropsToExternal(rItem, nXMLFormat); - m_aDebug.setGlobalInfo("frame loader to external \""+sItemName+"\""); - } - break; - - case E_CONTENTHANDLER : - { - rFormatedItem = Cache.convertContentHandlerPropsToExternal(rItem, nXMLFormat); - m_aDebug.setGlobalInfo("content handler to external \""+sItemName+"\""); - } - break; - } - - java.lang.StringBuffer sXML = new java.lang.StringBuffer(1000); - int nPrettyTabs = 1; - for (int t=0; t\n"); - sXML.append(XMLHelper.convertPropSetToXML(rFormatedItem, nPrettyTabs+1)); - for (int t=0; t\n"); - - return sXML.toString(); - } - - //___________________________________________ - - /** split the given string (using the specified delimiter) - * and return alist of found string tokens. - * - * Note: Against the normal behaviour of the StringTokenizer class - * this method returns empty tokens too. - * E.g: "0,,1" will return "0" - "" - "1" - * - * @param sTokenString - * the string value, which should be analyzed. - * - * @param sDelim - * the delimiter, which will be used to differe between tokens. - * - * @return [java.util.Vector] - * a list of string tokens. Can be empty - but not null! - */ - private static java.util.Vector splitTokenString(java.lang.String sTokenString, - java.lang.String sDelim ) - { - java.util.Vector lTokens = new java.util.Vector(); - java.util.StringTokenizer aTokenizer = new java.util.StringTokenizer(sTokenString, sDelim, true); - boolean bLastWasDelim = false; - - while (aTokenizer.hasMoreTokens()) - { - java.lang.String sToken = aTokenizer.nextToken(); - if (sToken.equals(sDelim)) - { - if (bLastWasDelim) - { - // last token was a delimiter - new one too - // => an empty token must be placed between these - // two delimiters! Add this empty value to the return list. - lTokens.add(""); - } - else - { - // last token was not a delimiter - new one is such delim - // => ignore this delimiter - but save the information, that - // it occured - bLastWasDelim = true; - } - } - else - { - // new token is no delim - // => Add it to the return list. - lTokens.add(sToken); - // Dont forget to reset this information - so next loop - // will do the right things! - bLastWasDelim = false; - } - } - - return lTokens; - } - - //___________________________________________ - - /** - */ - public synchronized void analyze() - { - m_nDoubleRegisteredFilters = 0; - m_nTypesForFilters = 0; - m_nTypesForDetectServices = 0; - m_nTypesForFrameLoaders = 0; - m_nTypesForContentHandlers = 0; - - // create table of types and all registered filters for such types - // By the way: count all double registrations, where a filter - // uses the same type then another filter. - m_lFilterToTypeRegistrations = new java.util.HashMap(); - java.util.Iterator aIt1 = m_lFilters.keySet().iterator(); - while (aIt1.hasNext()) - { - java.lang.String sFilter = (java.lang.String)aIt1.next(); - java.util.HashMap aFilter = (java.util.HashMap)m_lFilters.get(sFilter); - java.lang.String sType = (java.lang.String)aFilter.get(PROPNAME_TYPE); - - java.util.Vector lFilters = (java.util.Vector)m_lFilterToTypeRegistrations.get(sType); - if (lFilters == null) - lFilters = new java.util.Vector(); - else - ++m_nDoubleRegisteredFilters; - lFilters.add(sFilter); - m_lFilterToTypeRegistrations.put(sType, lFilters); - } - - // count, how many types are used by filters, frame loaders or content handlers - aIt1 = m_lTypes.keySet().iterator(); - while (aIt1.hasNext()) - { - java.lang.String sType = (java.lang.String)aIt1.next(); - - java.util.Iterator aIt2 = m_lFilters.keySet().iterator(); - while (aIt2.hasNext()) - { - java.lang.String sItem = (java.lang.String)aIt2.next(); - java.util.HashMap aItem = (java.util.HashMap)m_lFilters.get(sItem); - java.lang.String sTypeReg = (java.lang.String)aItem.get(PROPNAME_TYPE); - - if (sTypeReg.equals(sType)) - { - ++m_nTypesForFilters; - break; - } - } - - aIt2 = m_lDetectServices.keySet().iterator(); - while (aIt2.hasNext()) - { - java.lang.String sItem = (java.lang.String)aIt2.next(); - java.util.HashMap aItem = (java.util.HashMap)m_lDetectServices.get(sItem); - java.util.Vector lTypeReg = (java.util.Vector)aItem.get(PROPNAME_TYPES); - - if (lTypeReg.contains(sType)) - { - ++m_nTypesForDetectServices; - break; - } - } - - aIt2 = m_lFrameLoaders.keySet().iterator(); - while (aIt2.hasNext()) - { - java.lang.String sItem = (java.lang.String)aIt2.next(); - java.util.HashMap aItem = (java.util.HashMap)m_lFrameLoaders.get(sItem); - java.util.Vector lTypeReg = (java.util.Vector)aItem.get(PROPNAME_TYPES); - - if (lTypeReg.contains(sType)) - { - ++m_nTypesForFrameLoaders; - break; - } - } - - aIt2 = m_lContentHandlers.keySet().iterator(); - while (aIt2.hasNext()) - { - java.lang.String sItem = (java.lang.String)aIt2.next(); - java.util.HashMap aItem = (java.util.HashMap)m_lContentHandlers.get(sItem); - java.util.Vector lTypeReg = (java.util.Vector)aItem.get(PROPNAME_TYPES); - - if (lTypeReg.contains(sType)) - { - ++m_nTypesForContentHandlers; - break; - } - } - } - } - - //___________________________________________ - - /** validate all cache entries. - * - * It checks if all made registrations are valid; - * try to repair some simple problems; - * create missing informations on demand ... - * - * @param nFormat - * specify, which configuration format - * must be checked. - * - * @throws [java.lang.Exception] - * if an unrecoverable problem occure. - */ - public synchronized void validate(int nFormat) - throws java.lang.Exception - { - validateTypes(nFormat); - validateFilters(nFormat); - } - - //___________________________________________ - - /** validate all type entries of this cache. - * - * @param nFormat - * specify, which configuration format - * must be checked. - * - * @throws [java.lang.Exception] - * if an unrecoverable problem occure. - */ - private void validateTypes(int nFormat) - throws java.lang.Exception - { - java.util.Iterator aIt1 = m_lTypes.keySet().iterator(); - while(aIt1.hasNext()) - { - java.lang.String sType = (java.lang.String)aIt1.next(); - java.util.HashMap aType = (java.util.HashMap)m_lTypes.get(sType); - if (aType == null) - throw new java.lang.Exception("type ["+sType+"] dos not exist realy?!"); - - if ( - (!aType.containsKey(PROPNAME_MEDIATYPE )) || - (!aType.containsKey(PROPNAME_PREFERRED )) || - (!aType.containsKey(PROPNAME_CLIPBOARDFORMAT)) || - (!aType.containsKey(PROPNAME_DOCUMENTICONID )) || - (!aType.containsKey(PROPNAME_URLPATTERN )) || - (!aType.containsKey(PROPNAME_EXTENSIONS )) || - (!aType.containsKey(PROPNAME_UINAME )) - ) - { - throw new java.lang.Exception("Type \""+sType+"\" does not contain all neccessary properties for a 6.0/6.Y format."); - } - - if ( - (((java.util.Vector)aType.get(PROPNAME_EXTENSIONS)).isEmpty()) && - (((java.util.Vector)aType.get(PROPNAME_URLPATTERN)).isEmpty()) - ) - { - throw new java.lang.Exception("Type \""+sType+"\" does not contain any extension nor an url pattern."); - } - - if (((java.util.HashMap)aType.get(PROPNAME_UINAME)).isEmpty()) - throw new java.lang.Exception("Type \""+sType+"\" is not localized."); - - if (nFormat == FORMAT_6Y) - { - if ( - (!aType.containsKey(PROPNAME_UIORDER )) || - (!aType.containsKey(PROPNAME_PREFERREDFILTER)) || - (!aType.containsKey(PROPNAME_DETECTSERVICE )) - ) - { - throw new java.lang.Exception("Type \""+sType+"\" does not contain all neccessary properties for a 6.Y format."); - } - - if (((java.lang.Integer)aType.get(PROPNAME_UIORDER)).intValue() < 0) - throw new java.lang.Exception("Type \""+sType+"\" has invalid value for prop UIOrder."); - - if (((java.lang.String)aType.get(PROPNAME_DETECTSERVICE)).length() < 1) - m_aDebug.setWarning("Type \""+sType+"\" has no detect service registered."); - - java.lang.String sPreferredReg = (java.lang.String)aType.get(PROPNAME_PREFERREDFILTER); - if ( - (sPreferredReg == null) || - (sPreferredReg.length() < 1 ) - ) - { - m_aDebug.setWarning("Type \""+sType+"\" has no preferred filter ..."); - /*FIXME - * OK - not every type has a filter registered .. but the - * a frame loader MUST(!) exist! Check it. - */ - } - else - { - if (!m_lFilters.containsKey(sPreferredReg)) - throw new java.lang.Exception("Type \""+sType+"\" has no valid preferred filter registration [\""+sPreferredReg+"\"]."); - } - } - } - } - - //___________________________________________ - - /** validate all filter entries of this cache. - * - * @param nFormat - * specify, which configuration format - * must be checked. - * - * @throws [java.lang.Exception] - * if an unrecoverable problem occure. - */ - public synchronized void validateFilters(int nFormat) - throws java.lang.Exception - { - java.util.Iterator aIt1 = m_lFilters.keySet().iterator(); - while(aIt1.hasNext()) - { - java.lang.String sFilter = (java.lang.String)aIt1.next(); - java.util.HashMap aFilter = (java.util.HashMap)m_lFilters.get(sFilter); - if (aFilter == null) - throw new java.lang.Exception("filter ["+sFilter+"] dos not exist realy?!"); - - if ( - (!aFilter.containsKey(PROPNAME_DOCUMENTSERVICE )) || - (!aFilter.containsKey(PROPNAME_FILEFORMATVERSION)) || - (!aFilter.containsKey(PROPNAME_FILTERSERVICE )) || - (!aFilter.containsKey(PROPNAME_FLAGS )) || - (!aFilter.containsKey(PROPNAME_TEMPLATENAME )) || - (!aFilter.containsKey(PROPNAME_TYPE )) || - (!aFilter.containsKey(PROPNAME_UICOMPONENT )) || - (!aFilter.containsKey(PROPNAME_USERDATA )) - ) - { - throw new java.lang.Exception("Filter \""+sFilter+"\" does not contain all neccessary properties for a 6.0/6.Y format."); - } - - if (((java.lang.Integer)aFilter.get(PROPNAME_FLAGS)).intValue() < 1) - throw new java.lang.Exception("Filter \""+sFilter+"\" does not have a valid flag field."); - - if (!m_lTypes.containsKey(aFilter.get(PROPNAME_TYPE))) - throw new java.lang.Exception("Filter \""+sFilter+"\" is not registered for a well known type."); - - if (nFormat == FORMAT_60) - { - if ( - (!aFilter.containsKey(PROPNAME_ORDER )) || - (!aFilter.containsKey(PROPNAME_UINAME)) - ) - { - throw new java.lang.Exception("Filter \""+sFilter+"\" does not contain all neccessary properties for a 6.0 format."); - } - - if (((java.lang.Integer)aFilter.get(PROPNAME_ORDER)).intValue() < 0) - throw new java.lang.Exception("Filter \""+sFilter+"\" does not have a valid Order value."); - - if (((java.util.HashMap)aFilter.get(PROPNAME_UINAME)).isEmpty()) - throw new java.lang.Exception("Filter \""+sFilter+"\" is not localized."); - } -/*TODO - depends from the configuration item "remove_filter_flag_preferred" ... - - if (nFormat == FORMAT_6Y) - { - int flags = ((java.lang.Integer)aFilter.get(PROPNAME_FLAGS)).intValue(); - if ((flags & FLAGVAL_PREFERRED) == FLAGVAL_PREFERRED) - throw new java.lang.Exception("Filter \""+sFilter+"\" has superflous Preferred flag set. Please remove this flag. ["+flags+"]"); - } -*/ - } - } - - /*TODO - * - remove graphic filters! - * - move detect services to types - */ - - public synchronized void transform60to6Y(boolean bCreateCombineFilterFlag , - boolean bRemoveFilterFlagBrowserPreferred, - boolean bRemoveFilterFlagPreferred , - boolean bRemoveFilterFlag3rdparty , - boolean bRemoveFilterUINames , - boolean bRemoveGraphicFilters , - boolean bSetDefaultDetector ) - throws java.lang.Exception - { - // remove some superflous cache entries ... - // everything related to "load macros" - // Macros should be dispatched instead of loaded! - if (m_lTypes.containsKey("macro")) - { - m_lTypes.remove("macro"); - m_aDebug.setDetailedInfo("superflous type \"macro\" was removed"); - } - if (m_lFrameLoaders.containsKey("com.sun.star.comp.sfx2.SfxMacroLoader")) - { - m_lFrameLoaders.remove("com.sun.star.comp.sfx2.SfxMacroLoader"); - m_aDebug.setDetailedInfo("superflous frame loader \"com.sun.star.comp.sfx2.SfxMacroLoader\" was removed"); - } - - // step over all filters and check her properties and references - java.util.Vector lPreferredFilters = new java.util.Vector(); - java.util.Vector lNoRealFilters = new java.util.Vector(); - java.util.Iterator aIt1 = m_lFilters.keySet().iterator(); - while(aIt1.hasNext()) - { - java.lang.String sFilter = (java.lang.String)aIt1.next(); - java.util.HashMap aFilter = (java.util.HashMap)m_lFilters.get(sFilter); - - // remove the "graphic helper filters" used by draw and impress - // They dont have any valid document service name set and cant be handled - // by our generic FrameLoader! - // They must be moved to her own configuration ... - - if ( - (bRemoveGraphicFilters ) && - (((java.lang.String)aFilter.get(PROPNAME_DOCUMENTSERVICE)).length() < 1) - ) - { - lNoRealFilters.add(sFilter); - continue; - } - - java.lang.String sTypeReg = (java.lang.String)aFilter.get(PROPNAME_TYPE); - java.util.HashMap aType = (java.util.HashMap)m_lTypes.get(sTypeReg); - - // move UINames of filters to types - java.util.HashMap lFilterUINames = (java.util.HashMap)aFilter.get(PROPNAME_UINAME); - java.util.HashMap lTypeUINames = (java.util.HashMap)aType.get(PROPNAME_UINAME); - java.util.HashMap lPatchUINames = new java.util.HashMap(); - - java.util.Iterator pUINames = lTypeUINames.keySet().iterator(); - while(pUINames.hasNext()) - { - java.lang.String sLocale = (java.lang.String)pUINames.next(); - java.lang.String sValue = (java.lang.String)lTypeUINames.get(sLocale); - lPatchUINames.put(sLocale, sValue); - } - - pUINames = lFilterUINames.keySet().iterator(); - while(pUINames.hasNext()) - { - java.lang.String sLocale = (java.lang.String)pUINames.next(); - java.lang.String sValue = (java.lang.String)lFilterUINames.get(sLocale); - lPatchUINames.put(sFilter+":"+sLocale, sValue); - } - aType.put(PROPNAME_UINAME, lPatchUINames); - - // set generic filter service wrapper for our own native filters! - // By the way: The format types of such filters can be detected by our - // generic detector too. - if ( - (bSetDefaultDetector ) && - (((java.lang.String)aFilter.get(PROPNAME_FILTERSERVICE)).length() < 1) - ) - { - /*ME_THINKING aFilter.put(PROPNAME_FILTERSERVICE, FILTERSERVICE_NATIVEWARPPER);*/ - aType.put(PROPNAME_DETECTSERVICE, GENERIC_DETECTSERVICE); - } - - // move the preferred filter information to any type - // Set the filter name to the type for which the filter is registered. - // If this type already have a set PreferredFilter value, check if the current filter - // has the preferred flag set. If not ignore it - otherwhise overwrite the - // current information at the type. But look for multiple preferred filter relations ... - // means: look if more the one filter has set the preferred flag for the same type! - - /* Attention! - * - * Dont remove the preferred flag from any filter! ... not here. - * Otherwhise next loop can't detect ambigous preferred registrations! - * Add filter to a temp. list, which can be used later to remove the preferred - * flag ... - */ - - int flags1 = ((java.lang.Integer)aFilter.get(PROPNAME_FLAGS)).intValue(); - java.lang.String sDocSrv = (java.lang.String)aFilter.get(PROPNAME_DOCUMENTSERVICE); - if (sDocSrv.length()>0)// without a doc service its not a real filter - its a graphic filter! - { - boolean preferred1 = ((flags1 & FLAGVAL_PREFERRED) == FLAGVAL_PREFERRED); - if (preferred1) - lPreferredFilters.add(aFilter); - - java.lang.String sAlreadyRegisteredFilter = (java.lang.String)aType.get(PROPNAME_PREFERREDFILTER); - // no registration => set this filter as "any possible one"! - if (sAlreadyRegisteredFilter.length() < 1) - aType.put(PROPNAME_PREFERREDFILTER, sFilter); - else - { - java.util.HashMap aAlreadyRegisteredFilter = (java.util.HashMap)m_lFilters.get(sAlreadyRegisteredFilter); - int flags2 = ((java.lang.Integer)aAlreadyRegisteredFilter.get(PROPNAME_FLAGS)).intValue(); - boolean preferred2 = ((flags2 & FLAGVAL_PREFERRED) == FLAGVAL_PREFERRED); - - // two preferred filters for the same type! => error - if (preferred1 && preferred2) - { - java.lang.StringBuffer sMsg = new java.lang.StringBuffer(256); - sMsg.append("More the one preferred filter detected for the same type.\n"); - sMsg.append("\ttype = \""+sTypeReg+"\"\n"); - sMsg.append("\tfilter[1] = \""+sAlreadyRegisteredFilter+"\"\n"); - sMsg.append("\tfilter[2] = \""+sFilter+"\"\n"); - throw new java.lang.Exception(sMsg.toString()); - } - else - // overwrite the "any possible" filter with a real preferred one - if (preferred1 && !preferred2) - aType.put(PROPNAME_PREFERREDFILTER, sFilter); - } - } - - // create the new combined filter flag if required - if (bCreateCombineFilterFlag) - { - if ( - ((flags1 & FLAGVAL_IMPORT) == FLAGVAL_IMPORT) && - ((flags1 & FLAGVAL_EXPORT) == FLAGVAL_EXPORT) - ) - { - flags1 |= FLAGVAL_COMBINED; - flags1 &= ~FLAGVAL_IMPORT ; - flags1 &= ~FLAGVAL_EXPORT ; - aFilter.put(PROPNAME_FLAGS, new java.lang.Integer(flags1)); - } - } - - // remove some obsolete filter flags - if (bRemoveFilterFlagBrowserPreferred) - { - flags1 &= ~FLAGVAL_BROWSERPREFERRED; - aFilter.put(PROPNAME_FLAGS, new java.lang.Integer(flags1)); - } - - if (bRemoveFilterFlag3rdparty) - { - flags1 &= ~FLAGVAL_3RDPARTYFILTER; - aFilter.put(PROPNAME_FLAGS, new java.lang.Integer(flags1)); - } - - // if its a filter with an UI order ... - // move this information to the registered type. - // Note: Because more then one filter can be registered for the same type. - // Handle it as an error ... till we find a better transformation! - java.lang.Integer nOrder = (java.lang.Integer)aFilter.get(PROPNAME_ORDER); - java.lang.Integer nUIOrder = (java.lang.Integer)aType.get(PROPNAME_UIORDER); - int order = nOrder.intValue(); - int uiorder = nUIOrder.intValue(); - - if (order > 0) - { - if ( - (uiorder < 1 ) || - (uiorder > order) - ) - { - aType.put(PROPNAME_UIORDER, nOrder); - m_aDebug.setDetailedInfo("moved order value "+nOrder+" from filter \""+sFilter+"\" to type \""+sTypeReg+"\""); - } - else - m_aDebug.setDetailedInfo("ignore order value [order="+nOrder+",uiorder="+nUIOrder+"] for filter \""+sFilter+"\" and type \""+sTypeReg+"\""); - } - } - - // NOW ... remove the preferred flags from every filter, which it has set. - java.util.Enumeration aIt2 = null; - if (bRemoveFilterFlagPreferred) - { - aIt2 = lPreferredFilters.elements(); - while (aIt2.hasMoreElements()) - { - java.util.HashMap aFilter = (java.util.HashMap)aIt2.nextElement(); - int flags = ((java.lang.Integer)aFilter.get(PROPNAME_FLAGS)).intValue(); - flags &= ~FLAGVAL_PREFERRED; - aFilter.put(PROPNAME_FLAGS, new java.lang.Integer(flags)); - } - } - - // NOW ... remove all "no real filters" like the graphich helper filters of - // draw and impress! - aIt2 = lNoRealFilters.elements(); - while (aIt2.hasMoreElements()) - m_lFilters.remove(aIt2.nextElement()); - - // step over all detect services and move this information directly to - // the corresponding types - // Overwrite possibel default registrations with a real existing one! - aIt1 = m_lDetectServices.keySet().iterator(); - while(aIt1.hasNext()) - { - java.lang.String sDetector = (java.lang.String)aIt1.next(); - java.util.HashMap aDetector = (java.util.HashMap)m_lDetectServices.get(sDetector); - java.util.Vector lTypeReg = (java.util.Vector)aDetector.get(PROPNAME_TYPES); - aIt2 = lTypeReg.elements(); - while(aIt2.hasMoreElements()) - { - java.lang.String sTypeReg = (java.lang.String)aIt2.nextElement(); - java.util.HashMap aType = (java.util.HashMap)m_lTypes.get(sTypeReg); - - if (aType == null) - { - m_aDebug.setWarning("Detector \""+sDetector+"\" seem to be registered for unknown type \""+sTypeReg+"\""); - continue; - } - - java.lang.Object aAlreadyRegisteredDetector = aType.get(PROPNAME_DETECTSERVICE); - if (aAlreadyRegisteredDetector != null && ((java.lang.String)aAlreadyRegisteredDetector).length() > 0) - { - java.lang.StringBuffer sMsg = new java.lang.StringBuffer(256); - sMsg.append("type \""+sTypeReg+"\" has ambigous registrations of a detect service\n"); - sMsg.append("\tdetect service[1] = \""+(java.lang.String)aAlreadyRegisteredDetector+"\"\n"); - sMsg.append("\tdetect service[2] = \""+sDetector+"\"\n"); - m_aDebug.setWarning(sMsg.toString()); - } - aType.put(PROPNAME_DETECTSERVICE, sDetector); - m_aDebug.setGlobalInfo("move detector \""+sDetector+"\" to type \""+sTypeReg+"\""); - } - } - - // because all detect service was registered as type properties directly ... - // remove all detect service objects of this cache! - m_lDetectServices.clear(); - - // step over all frame loader and move this information directly to - // the corresponding types - // Overwrite possibel default registrations with a real existing one! - aIt1 = m_lFrameLoaders.keySet().iterator(); - while(aIt1.hasNext()) - { - java.lang.String sLoader = (java.lang.String)aIt1.next(); - java.util.HashMap aLoader = (java.util.HashMap)m_lFrameLoaders.get(sLoader); - java.util.Vector lTypeReg = (java.util.Vector)aLoader.get(PROPNAME_TYPES); - aIt2 = lTypeReg.elements(); - while(aIt2.hasMoreElements()) - { - java.lang.String sTypeReg = (java.lang.String)aIt2.nextElement(); - java.util.HashMap aType = (java.util.HashMap)m_lTypes.get(sTypeReg); - java.lang.String sAlreadyRegisteredLoader = (java.lang.String)aType.get(PROPNAME_FRAMELOADER); - if (sAlreadyRegisteredLoader != null && sAlreadyRegisteredLoader.length() > 0) - { - java.lang.StringBuffer sMsg = new java.lang.StringBuffer(256); - sMsg.append("type \""+sTypeReg+"\" has ambigous registrations of a frame loader\n"); - sMsg.append("\tframe loader[1] = \""+sAlreadyRegisteredLoader+"\"\n"); - sMsg.append("\tframe loader[2] = \""+sLoader+"\"\n"); - m_aDebug.setWarning(sMsg.toString()); - } - aType.put(PROPNAME_FRAMELOADER, sLoader); - System.out.println("move loader \""+sLoader+"\" to type \""+sTypeReg+"\""); - } - } - - m_lFrameLoaders.clear(); - - // step over all content handler and move this information directly to - // the corresponding types - // Overwrite possibel default registrations with a real existing one! - aIt1 = m_lContentHandlers.keySet().iterator(); - while(aIt1.hasNext()) - { - java.lang.String sHandler = (java.lang.String)aIt1.next(); - java.util.HashMap aHandler = (java.util.HashMap)m_lContentHandlers.get(sHandler); - java.util.Vector lTypeReg = (java.util.Vector)aHandler.get(PROPNAME_TYPES); - aIt2 = lTypeReg.elements(); - while(aIt2.hasMoreElements()) - { - java.lang.String sTypeReg = (java.lang.String)aIt2.nextElement(); - java.util.HashMap aType = (java.util.HashMap)m_lTypes.get(sTypeReg); - java.lang.String sAlreadyRegisteredHandler = (java.lang.String)aType.get(PROPNAME_CONTENTHANDLER); - if (sAlreadyRegisteredHandler != null && sAlreadyRegisteredHandler.length() > 0) - { - java.lang.StringBuffer sMsg = new java.lang.StringBuffer(256); - sMsg.append("type \""+sTypeReg+"\" has ambigous registrations of a content handler\n"); - sMsg.append("\tcontent handler[1] = \""+sAlreadyRegisteredHandler+"\"\n"); - sMsg.append("\tcontent handler[2] = \""+sHandler+"\"\n"); - m_aDebug.setWarning(sMsg.toString()); - } - aType.put(PROPNAME_CONTENTHANDLER, sHandler); - System.out.println("move handler \""+sHandler+"\" to type \""+sTypeReg+"\""); - } - } - - m_lContentHandlers.clear(); - -/* - int c = m_lTypes.size(); - java.lang.String[] lT1 = new java.lang.String[c]; - java.lang.String[] lT2 = new java.lang.String[c]; - long nUPS = 0; - - int i = 0; - aIt1 = m_lTypes.keySet().iterator(); - while(aIt1.hasNext()) - { - lT1[i] = (java.lang.String)aIt1.next(); - lT2[i] = lT1[i]; - ++i; - } - - for (int i1=0; i1 search from left to right - int len = lCommandLineArgs[arg].length(); - int pos = lCommandLineArgs[arg].indexOf('='); - if (pos != -1) - { - java.lang.String sArg = lCommandLineArgs[arg].substring(0,pos); - java.lang.String sValue = lCommandLineArgs[arg].substring(pos+1); - setProperty(sArg, sValue); - continue; - } - - // is it a boolean argument? - // Note: Because "--" and "-" will be interpreted as the same - // we search from right to left! - pos = lCommandLineArgs[arg].lastIndexOf('-'); - if (pos == -1) - pos = lCommandLineArgs[arg].lastIndexOf('/'); - if (pos != -1) - { - java.lang.String sArg = lCommandLineArgs[arg].substring(pos+1); - setProperty(sArg, java.lang.String.valueOf(true)); - continue; - } - - // There is an unknown format used by this argument ... - throw new MalformedCommandLineException("Invalid command line detected. The argument \""+lCommandLineArgs[arg]+"\" use an unsupported format."); - } - } - - //------------------------------------------- - /** indicates if the given command line includes - * a help request. - * - * @return True if there was an explicit help request. - */ - public synchronized boolean isHelp() - { - return ( - (containsKey("help")) || - (containsKey("?") ) || - (containsKey("h") ) - ); - } - - //------------------------------------------- - /** indicates if the gioven command line was empty. - * - * @return True if there was an empty command line. - */ - public synchronized boolean isEmpty() - { - return m_bEmpty; - } - - //------------------------------------------- - /** returns the value of sProp as boolean value. - * - * @param sProp - * the name of the parameter. - * - * @return The boolean value of the requested property. - * - * @throw [NoSuchElementException] - * if the requested property does not exists. - */ - public synchronized boolean getBoolean(java.lang.String sProp) - throws java.util.NoSuchElementException - { - java.lang.String sValue = getProperty(sProp); - if (sValue == null) - throw new java.util.NoSuchElementException("The requested config value \""+sProp+"\" does not exists!"); - return new java.lang.Boolean(sValue).booleanValue(); - } - - public synchronized boolean getBoolean(java.lang.String sProp , - boolean bDefault) - { - java.lang.String sDefault = java.lang.String.valueOf(bDefault); - java.lang.String sValue = getProperty(sProp, sDefault); - return new java.lang.Boolean(sValue).booleanValue(); - } - - //------------------------------------------- - /** returns the value of sProp as int value. - * - * @param sProp - * the name of the parameter. - * - * @return The int value of the requested property. - * - * @throw [NoSuchElementException] - * if the requested property does not exists. - */ - public synchronized int getInt(java.lang.String sProp) - throws java.util.NoSuchElementException - { - java.lang.String sValue = getProperty(sProp); - if (sValue == null) - throw new java.util.NoSuchElementException("The requested config value \""+sProp+"\" does not exists!"); - return new java.lang.Integer(sValue).intValue(); - } - - public synchronized int getInt(java.lang.String sProp , - int nDefault) - { - java.lang.String sDefault = java.lang.String.valueOf(nDefault); - java.lang.String sValue = getProperty(sProp, sDefault); - return new java.lang.Integer(sValue).intValue(); - } - - //------------------------------------------- - /** returns the value of sProp as string value. - * - * @param sProp - * the name of the parameter. - * - * @return The string value of the requested property. - * - * @throw [NoSuchElementException] - * if the requested property does not exists. - */ - public synchronized java.lang.String getString(java.lang.String sProp) - throws java.util.NoSuchElementException - { - java.lang.String sValue = getProperty(sProp); - if (sValue == null) - throw new java.util.NoSuchElementException("The requested config value \""+sProp+"\" does not exists!"); - return sValue; - } - - //------------------------------------------- - /** returns the value of sProp as string list value! - * - * @descr The delimiter must be well known and - * it must be clear if trailing/leading - * whitespaces must be ignored or not. - * - * @param sProp - * the name of the parameter. - * - * @param sDelim - * the delimiter, which must be used to split - * the config string value into an array. - * - * @param bTrim - * if its set to true, trailing and leading whitespace - * characters will be ommited. - * - * @param bDecode - * if its set to TRUE all liste items will be - * interpreted as "" and converted to ! - * - * @return The string list value of the requested property. - * - * @throw [NoSuchElementException] - * if the requested property does not exists. - */ - public synchronized java.util.Vector getStringList(java.lang.String sProp , - java.lang.String sDelimiter, - boolean bTrim , - boolean bDecode ) - throws java.util.NoSuchElementException - { - java.lang.String sValue = getProperty(sProp); - if (sValue == null) - throw new java.util.NoSuchElementException("The requested config value \""+sProp+"\" does not exists!"); - - java.util.Vector lValue = new java.util.Vector(); - try - { - java.util.StringTokenizer lTokens = new java.util.StringTokenizer(sValue, sDelimiter); - while(lTokens.hasMoreTokens()) - { - java.lang.String sToken = lTokens.nextToken(); - // remove trailing/leading whitespaces - if (bTrim) - sToken = sToken.trim(); - // remove "" - if ( - (bDecode ) && - (sToken.indexOf("\"") == 0 ) && - (sToken.lastIndexOf("\"") == sToken.length()-1) - ) - { - sToken = sToken.substring(1, sToken.length()-1); - } - lValue.add(sToken); - } - } - catch(java.lang.Throwable ex) - { lValue.clear(); } - - return lValue; - } -} diff --git a/filter/source/config/tools/utils/FileHelper.java b/filter/source/config/tools/utils/FileHelper.java deleted file mode 100644 index 1086876f5d4e..000000000000 --- a/filter/source/config/tools/utils/FileHelper.java +++ /dev/null @@ -1,760 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: FileHelper.java,v $ - * $Revision: 1.13 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -package com.sun.star.filter.config.tools.utils; - - -// __________ Implementation __________ - -/** - * It collects some static helper functons to handle file system specific problems. - * Sometimes it's neccessary to convert URL from/to system pathes; - * or from string notation to structural versions (e.g. com.sun.star.util.URL). - * And sometimes java had another notation then the office it has. - * Further it provides functionality to work easiear with the java.io.File class of java. - * - * - */ -public class FileHelper -{ - // ____________________ - - /** - * Because the office need URLs for loading/saving documents - * we must convert used system pathes. - * And java use another notation for file URLs ... correct it. - * - * @param aSystemPath - * represent the file in system notation - * - * @return [String] - * a file url which represent the given system path - */ - public static java.lang.String getFileURLFromSystemPath(java.io.File aSystemPath) - { - System.out.println("TODO: must be adapted to java 1.3 :-("); - System.exit(-1); -/*TODO_JAVA - try - { - sFileURL = aSystemPath.toURI().toURL().toString(); - } - catch( MalformedURLException exWrong ) - { - sFileURL = null; - } -*/ - java.lang.String sFileURL = null; - - // problem of java: file URL's are coded with 1 slash instead of 2 or 3 ones! - // => correct this problem first, otherwise office can't use these URL's - if( - (sFileURL != null ) && - (sFileURL.startsWith("file:/") == true ) && - (sFileURL.startsWith("file://") == false) - ) - { - java.lang.StringBuffer sWorkBuffer = new java.lang.StringBuffer(sFileURL); - sWorkBuffer.insert(6,"//"); - sFileURL = sWorkBuffer.toString(); - } - - return sFileURL; - } - - // ____________________ - - /** - * The same as getFileURLFromSystemPath() before but uses string parameter instead - * of a java.io.File type. It exist to supress converting of neccessary parameters in the - * outside code. But of course getFileURLFromSystemPath(File) will be a little bit faster - * then this method ... - * - * @param sSystemPath - * represent the file in system notation - * - * @return [String] - * a file url which represent the given system path - */ - public static java.lang.String getFileURLFromSystemPath(java.lang.String sSystemPath) - { - return getFileURLFromSystemPath(new java.io.File(sSystemPath)); - } - - // ____________________ - - /** - * Does the same as getFileURLFromSystemPath() before ... but uses - * the given protocol string (e.g."http://") insted of "file:///". - * - * @param aSystemPath - * represent the file in system notation - * - * @param aBasePath - * define the base path of the aSystemPath value, - * which must be replaced with the value of "sServerPath". - * - * @param sServerURL - * Will be used to replace sBasePath. - * - * @example - * System Path = "d:\test\file.txt" - * Base Path = "d:\test" - * Server Path = "http://alaska:8000" - * => "http://alaska:8000/file.txt" - * - * @return [String] - * an url which represent the given system path - * and uses the given protocol - */ - public static java.lang.String getURLWithProtocolFromSystemPath(java.io.File aSystemPath, - java.io.File aBasePath , - java.lang.String sServerURL ) - { - System.out.println("TODO: must be adapted to java 1.3 :-("); - System.exit(-1); - - java.lang.String sFileURL = FileHelper.getFileURLFromSystemPath(aSystemPath); - java.lang.String sBaseURL = FileHelper.getFileURLFromSystemPath(aBasePath ); - - // cut last '/'! - if (sBaseURL.lastIndexOf('/')==(sBaseURL.length()-1)) - sBaseURL = sBaseURL.substring(0,sBaseURL.length()-1); - - // cut last '/'! - if (sServerURL.lastIndexOf('/')==(sServerURL.length()-1)) - sServerURL = sServerURL.substring(0,sServerURL.length()-1); - -//TODO_JAVA java.lang.String sURL = sFileURL.replaceFirst(sBaseURL,sServerURL); - java.lang.String sURL = null; - return sURL; - } - - // ____________________ - - /** - * The same as getURLWithProtocolFromSystemPath() before but uses string parameter instead - * of a java.io.File types. It exist to supress converting of neccessary parameters in the - * outside code. But of course getURLWithProtocolFromSystemPath(File,File,String) will be - * a little bit faster then this method ... - * - * @param sSystemPath - * represent the file in system notation - * - * @param sBasePath - * define the base path of the aSystemPath value, - * which must be replaced with the value of "sServerPath". - * - * @param sServerPath - * Will be used to replace sBasePath. - * - * @example - * System Path = "d:\test\file.txt" - * Base Path = "d:\test" - * Server Path = "http://alaska:8000" - * => "http://alaska:8000/file.txt" - * - * @return [String] - * an url which represent the given system path - * and uses the given protocol - */ - public static java.lang.String getURLWithProtocolFromSystemPath(java.lang.String sSystemPath, - java.lang.String sBasePath , - java.lang.String sServerPath) - { - return getURLWithProtocolFromSystemPath(new java.io.File(sSystemPath), new java.io.File(sBasePath), sServerPath); - } - - //_________________________________ - - /** - * Return a list of all available files of a directory. - * We filter sub directories. All other files - * are returned. So they can be used for further purposes. - * One parameter define the start directory, - * another one enable/disable recursive search into sub directories. - * - * @param aRoot - * the start directory, which should be analyzed. - * - * @param bRecursive - * enable/disable search in sub directories. - * - * @return [Vector] - * a filtered list of java java.io.File objects of all available files - * of the start dir (and may of its sub directories). - */ - public static java.util.Vector getSystemFilesFromDir(java.io.File aRoot , - boolean bRecursive) - { - java.io.File[] lAllFiles = aRoot.listFiles(); - if (lAllFiles == null) - return null; - - int c = lAllFiles.length; - java.util.Vector lFilteredFiles = new java.util.Vector(c); - for (int i=0; i=48 && c<=57 // 0-9 - && - c>=97 && c<=122 // a-z - && - c>=65 && c<=90 // A-Z - ) - { - sNewName.append(c); - } - else - { - sNewName.append("_"); - } - } - - return sNewName.toString(); - } - - //___________________________________________ - - /** it removes all child nodes of a file system directory. - * - * @param aDirectory - * points to the directory, which should be made empty. - * - * @param bFilesOnly - * force deletion of files only. If its set to TRUE, - * no subdirectory will be removed. - * - * @throw [java.io.IOException] - * if some of the child nodes couldn't be removed. - */ - public static void makeDirectoryEmpty(java.io.File aDirectory, - boolean bFilesOnly) - throws java.io.IOException - { - if (!aDirectory.isDirectory()) - throw new java.io.FileNotFoundException("\""+aDirectory.toString()+"\" is not a directory."); - - java.io.File[] lChilds = aDirectory.listFiles(); - for (int f=0; f0) - sBuffer.append(aEncodedBuffer, 0, nReadCount); - - aEncodedReader.close(); - } - - //___________________________________________ - private static void logEncodingData(java.lang.StringBuffer sLog , - int nUTF8 , - int nByteOrg1 , - int nByteOrg2 , - int nByteOrg3 , - int nByteOrg4 , - int nByte1 , - int nByte2 , - int nByte3 , - int nByte4 , - int nEncodingType) - { - sLog.append("["+nEncodingType+"]\t"); - sLog.append((int)nUTF8+"\t="); - sLog.append("\t"+nByteOrg1+"/"+nByte1); - sLog.append("\t"+nByteOrg2+"/"+nByte2); - sLog.append("\t"+nByteOrg3+"/"+nByte3); - sLog.append("\t"+nByteOrg4+"/"+nByte4); - sLog.append("\n"); - } - - //___________________________________________ - private static char impl_convertBytesToChar(int nByte1, int nByte2, int nByte3, int nByte4) - { - return (char)((nByte1*0x40000)+(nByte2*0x1000)+(nByte3*0x40)+nByte4); - } - - //___________________________________________ - private static int impl_readAndCheckNextByte(byte[] aBuffer , - int nBufPos , - int nBufLength , - int nMinRange , - int nMaxRange ) - throws java.lang.Exception - { - if (nBufPos>=nBufLength) - throw new java.lang.Exception("impl_readAndCheckNextByte()\nEnd of buffer reached."); - - int nByte = aBuffer[nBufPos] & 0xFF; - if ( - (nByte < nMinRange) || - (nByte > nMaxRange) - ) - { - throw new java.lang.Exception("impl_readAndCheckNextByte()\nByte does not fit the specified range."); - } - - return nByte; - } - - //___________________________________________ - public static void readAndCheckUTF8File(java.io.File aFile , - java.lang.StringBuffer sBuffer) - throws java.io.IOException - { - java.io.FileInputStream aByteStream = new java.io.FileInputStream(aFile.getAbsolutePath()); - byte[] aBuffer = new byte[4096]; - int nReadCount = 0; - int nByteOrg_1 = 0; - int nByteOrg_2 = 0; - int nByteOrg_3 = 0; - int nByteOrg_4 = 0; - int nByte_1 = 0; - int nByte_2 = 0; - int nByte_3 = 0; - int nByte_4 = 0; - char nUTF8 = 0; - int i = 0; - int nEncodingType = 0; - java.lang.StringBuffer sLog = new java.lang.StringBuffer(); - - try - { - - while((nReadCount=aByteStream.read(aBuffer))>0) - { - i=0; - while (i= 0x00) && - (nByteOrg_1 <= 0x7F) - ) - { - nEncodingType = 1; - nUTF8 = (char)nByte_1; - } - // ------------------------------------------------------------ - // 02 - // 1 byte: 110xxxxx - // 2 byte: 101xxxxx - // ------------------------------------------------------------ - else - if ( - (nByteOrg_1 >= 0xC2) && - (nByteOrg_1 <= 0xDF) - ) - { - nEncodingType = 2; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_1 = nByteOrg_1-0xC2; - nByte_2 = nByteOrg_2-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(0,0,nByte_1, nByte_2); - } - // ------------------------------------------------------------ - // 03 - // 1 byte: 11100000 - // 2 byte: 101xxxxx - // 3 byte: 10xxxxxx - // ------------------------------------------------------------ - else - if (nByteOrg_1 == 0xE0) - { - nEncodingType = 3; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0xA0, 0xBF); - nByteOrg_3 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_2 = nByteOrg_2-0xA0; - nByte_3 = nByteOrg_3-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(0,0,nByte_2, nByte_3); - } - // ------------------------------------------------------------ - // 04 - // 1 byte: 111xxxxx - // 2 byte: 10xxxxxx - // 3 byte: 10xxxxxx - // ------------------------------------------------------------ - else - if ( - (nByteOrg_1 >= 0xE1) && - (nByteOrg_1 <= 0xEC) - ) - { - nEncodingType = 4; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByteOrg_3 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_1 = nByteOrg_1-0xE1; - nByte_2 = nByteOrg_2-0x80; - nByte_3 = nByteOrg_3-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(0,nByte_1, nByte_2, nByte_3); - } - // ------------------------------------------------------------ - // 05 - // 1 byte: 11101101 - // 2 byte: 10xxxxxx - // 3 byte: 10xxxxxx - // ------------------------------------------------------------ - else - if (nByteOrg_1 == 0xED) - { - nEncodingType = 5; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0x9F); - nByteOrg_3 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_2 = nByteOrg_2-0x80; - nByte_3 = nByteOrg_3-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(0,0, nByte_2, nByte_3); - } - // ------------------------------------------------------------ - // 06 - // 1 byte: 1110111x - // 2 byte: 10xxxxxx - // 3 byte: 10xxxxxx - // ------------------------------------------------------------ - else - if ( - (nByteOrg_1 >= 0xEE) && - (nByteOrg_1 <= 0xEF) - ) - { - nEncodingType = 6; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByteOrg_3 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_1 = nByteOrg_1-0xEE; - nByte_2 = nByteOrg_2-0x80; - nByte_3 = nByteOrg_3-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(0,nByte_1, nByte_2, nByte_3); - } - // ------------------------------------------------------------ - // 07 - // 1 byte: 11110000 - // 2 byte: 1001xxxx - // 3 byte: 10xxxxxx - // 4 byte: 10xxxxxx - // ------------------------------------------------------------ - else - if (nByteOrg_1 == 0xF0) - { - nEncodingType = 7; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x90, 0xBF); - nByteOrg_3 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByteOrg_4 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_2 = nByteOrg_2-0x90; - nByte_3 = nByteOrg_3-0x80; - nByte_4 = nByteOrg_4-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(0, nByte_2, nByte_3, nByte_4); - } - // ------------------------------------------------------------ - // 08 - // 1 byte: 111100xx - // 2 byte: 10xxxxxx - // 3 byte: 10xxxxxx - // 3 byte: 10xxxxxx - // ------------------------------------------------------------ - else - if ( - (nByteOrg_1 >= 0xF1) && - (nByteOrg_1 <= 0xF3) - ) - { - nEncodingType = 8; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByteOrg_3 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByteOrg_4 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_1 = nByteOrg_1-0xF1; - nByte_2 = nByteOrg_2-0x80; - nByte_3 = nByteOrg_3-0x80; - nByte_4 = nByteOrg_4-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(nByte_1, nByte_2, nByte_3, nByte_4); - } - // ------------------------------------------------------------ - // 09 - // 1 byte: 11110100 - // 2 byte: 10xxxxxx - // 3 byte: 10xxxxxx - // 4 byte: 10xxxxxx - // ------------------------------------------------------------ - else - if (nByteOrg_1 == 0xF0) - { - nEncodingType = 9; - nByteOrg_2 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByteOrg_3 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByteOrg_4 = FileHelper.impl_readAndCheckNextByte(aBuffer, i++, nReadCount, 0x80, 0xBF); - nByte_2 = nByteOrg_2-0x80; - nByte_3 = nByteOrg_3-0x80; - nByte_4 = nByteOrg_4-0x80; - nUTF8 = FileHelper.impl_convertBytesToChar(0, nByte_2, nByte_3, nByte_4); - } - // wrong encoding ? - else - { - throw new java.lang.Exception("Non well formed UTF-8 encoding."); - } - - sBuffer.append(nUTF8); - // -> DEBUG ! - FileHelper.logEncodingData(sLog, nUTF8, nByteOrg_1, nByteOrg_2, nByteOrg_3, nByteOrg_4, nByte_1, nByte_2, nByte_3, nByte_4, nEncodingType); - // <- DEBUG ! - } - } - - } - catch(java.lang.Throwable ex) - { - // -> DEBUG ! - FileHelper.logEncodingData(sLog, nUTF8, nByteOrg_1, nByteOrg_2, nByteOrg_3, nByteOrg_4, nByte_1, nByte_2, nByte_3, nByte_4, nEncodingType); - - java.io.File aDir = new java.io.File(aFile.getParent()); - java.lang.String sDump = aFile.getName(); - java.io.File aDump = FileHelper.createUniqueFile(aDir, sDump, "dump"); - FileHelper.writeEncodedBufferToFile(aDump, "UTF-8", false, sLog); - // <- DEBUG ! - - java.lang.String sMsg = "File '"+aFile.getPath()+"' is not encoded right as UTF-8."; - throw new java.io.IOException(sMsg); - } - - aByteStream.close(); - } - - //___________________________________________ - - /** writes the given string buffer into the specified file - * using the specified encoding. - * - * Further it can be set, if the file should be expanded - * or replaced by this new string buffer. - * - * @param aFile - * must point to a system file. It can already exist! - * e.g.: "c:\temp\test.txt" - * "/tmp/test.txt" - * - * @param sEncoding - * will be used to encode the string content inside the file. - * e.g.: "UTF8" - * - * @param bAppend - * specify if an already existing file will be - * expanded or replaced. - * - * @param sBuffer - * the new string content for this file. - */ - public static void writeEncodedBufferToFile(java.io.File aFile , - java.lang.String sEncoding, - boolean bAppend , - java.lang.StringBuffer sBuffer ) - throws java.io.IOException - { - java.io.FileOutputStream aByteStream = new java.io.FileOutputStream(aFile.getAbsolutePath(), bAppend); - java.io.OutputStreamWriter aEncodedWriter = new java.io.OutputStreamWriter(aByteStream, sEncoding); - - java.lang.String sTemp = sBuffer.toString(); - aEncodedWriter.write(sTemp, 0, sTemp.length()); - - aEncodedWriter.flush(); - aEncodedWriter.close(); - - if (!aFile.exists()) - throw new java.io.IOException("File \""+aFile.getAbsolutePath()+"\" not written correctly."); - } -} diff --git a/filter/source/config/tools/utils/Logger.java b/filter/source/config/tools/utils/Logger.java deleted file mode 100644 index 699bbfcd443d..000000000000 --- a/filter/source/config/tools/utils/Logger.java +++ /dev/null @@ -1,172 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: Logger.java,v $ - * $Revision: 1.8 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -package com.sun.star.filter.config.tools.utils; - - -//_______________________________________________ -// definition - -/** can be used to print out some debug messages - * and group it into warnings/errors or info statements. - * - * - */ -public class Logger -{ - //___________________________________________ - // const - - /** only error message will be shown. */ - public static final int LEVEL_ERRORS = 1; - - /** only errors and warnings will be shown. */ - public static final int LEVEL_WARNINGS = 2; - - /** enable errors/warnings and some global info - * message. */ - public static final int LEVEL_GLOBALINFOS = 3; - - /** enable anything! */ - public static final int LEVEL_DETAILEDINFOS = 4; - - //___________________________________________ - // member - - /** enable/disable different output level. - * e.g. warnings/errors/infos */ - private int m_nLevel; - - //___________________________________________ - // ctor - - /** initialize new debug object with the specified - * debug level. - * - * @param nLevel - * the new debug level. - * See const values LEVEL_xxx too. - */ - public Logger(int nLevel) - { - m_nLevel = nLevel; - } - - //___________________________________________ - // interface - - /** initialize new debug object with a default - * debug level. - */ - public Logger() - { - m_nLevel = LEVEL_DETAILEDINFOS; - } - - //___________________________________________ - // interface - - /** prints out an exception ... if the right level is set. - * - * @param ex - * the exception object - */ - public synchronized void setException(java.lang.Throwable ex) - { - if (m_nLevel >= LEVEL_ERRORS) - { - System.err.println("Exception:\n"); - ex.printStackTrace(); - } - } - - //___________________________________________ - // interface - - /** prints out an error ... if the right level is set. - * - * @param sError - * the error message. - */ - public synchronized void setError(java.lang.String sError) - { - if (m_nLevel >= LEVEL_ERRORS) - System.err.println("Error :\t\""+sError+"\""); - } - - //___________________________________________ - // interface - - /** prints out a warning ... if the right level is set. - * - * @param sWarning - * the warning message. - */ - public synchronized void setWarning(java.lang.String sWarning) - { - if (m_nLevel >= LEVEL_WARNINGS) - System.err.println("Warning :\t\""+sWarning+"\""); - } - - //___________________________________________ - // interface - - /** prints out a global info message ... if the right level is set. - * - * Global infos should be used to describe a complex operation. - * E.g.: loading of a document. - * But not for every sub operation like e.g. analyzing lines - * during loading the document! - * - * @param sInfo - * the info message. - */ - public synchronized void setGlobalInfo(java.lang.String sInfo) - { - if (m_nLevel >= LEVEL_GLOBALINFOS) - System.out.println("Info :\t\""+sInfo+"\""); - } - - //___________________________________________ - // interface - - /** prints out a mode detailed info message ... if the right level is set. - * - * Such detailed message are e.g. "analyze line [n] of file ...". - * - * @param sInfo - * the info message. - */ - public synchronized void setDetailedInfo(java.lang.String sInfo) - { - if (m_nLevel >= LEVEL_DETAILEDINFOS) - System.out.println("Detail :\t\""+sInfo+"\""); - } -} diff --git a/filter/source/config/tools/utils/MalformedCommandLineException.java b/filter/source/config/tools/utils/MalformedCommandLineException.java deleted file mode 100644 index f6f33246a1f3..000000000000 --- a/filter/source/config/tools/utils/MalformedCommandLineException.java +++ /dev/null @@ -1,46 +0,0 @@ -/*_*********************************************************************** - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: MalformedCommandLineException.java,v $ - * $Revision: 1.4 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - **********************************************************************_*/ - -package com.sun.star.filter.config.tools.utils; - - -//___________________________________________ -// types - -/** indicates a malformed command line. - * - * E.g. it must be thrown if the command line contains one item more then once, - * or use unsupported format. - */ -public class MalformedCommandLineException extends java.lang.Exception -{ - public MalformedCommandLineException() {} - public MalformedCommandLineException(java.lang.String sMsg) { super(sMsg); } -} diff --git a/filter/source/config/tools/utils/XMLHelper.java b/filter/source/config/tools/utils/XMLHelper.java deleted file mode 100644 index fecb4c4348d3..000000000000 --- a/filter/source/config/tools/utils/XMLHelper.java +++ /dev/null @@ -1,820 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: XMLHelper.java,v $ - * $Revision: 1.7 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -package com.sun.star.filter.config.tools.utils; - - -//_______________________________________________ - -/** - * It provides some constant values and some static helper routines - * which are neccessary to work with a xml file - especialy - * the filter configuration. - * - * - */ -public class XMLHelper -{ - //___________________________________________ - // public const - - /** its a possible value of the xml attribute "oor:type" and identify an integer type. */ - public static final java.lang.String XMLTYPE_INTEGER = "xs:int"; - - /** its a possible value of the xml attribute "oor:type" and identify an boolean type. */ - public static final java.lang.String XMLTYPE_BOOLEAN = "xs:boolean"; - - /** its a possible value of the xml attribute "oor:type" and identify an string type. */ - public static final java.lang.String XMLTYPE_STRING = "xs:string"; - - /** its a possible value of the xml attribute "oor:type" and identify an string list type. */ - public static final java.lang.String XMLTYPE_STRINGLIST = "oor:string-list"; - - /** its a xml attribute, which specify a property name. */ - public static final java.lang.String XMLATTRIB_OOR_NAME = "oor:name"; - - /** its a xml attribute, which specify a property type. */ - public static final java.lang.String XMLATTRIB_OOR_TYPE = "oor:type"; - - /** its a xml attribute, which specify a list separator. */ - public static final java.lang.String XMLATTRIB_OOR_SEPARATOR = "oor:separator"; - - /** its a xml attribute, which specify a localized value. */ - public static final java.lang.String XMLATTRIB_OOR_LOCALIZED = "oor:localized"; - - /** its a xml attribute, which specify a merge operation for cfg layering. */ - public static final java.lang.String XMLATTRIB_OOR_OP = "oor:op"; - - /** can be used as value for XMLATTRIB_OOR_OP. */ - public static final java.lang.String XMLATTRIB_OP_REPLACE = "replace"; - - /** its a xml attribute, which specify a locale value. */ - public static final java.lang.String XMLATTRIB_XML_LANG = "xml:lang"; - - /** its the tag name of a entry. */ - public static final java.lang.String XMLTAG_VALUE = "value"; - - /** its the tag name of a entry. */ - public static final java.lang.String XMLTAG_PROP = "prop"; - - /** its the tag name of a entry. */ - public static final java.lang.String XMLTAG_NODE = "node"; - - //___________________________________________ - // private const - - /** a static list of all possible separators, which can be used for configuration type string-list. */ - private static final java.lang.String[] DELIMS = {" ", ",", ";", ".", ":", "-", "_", "#", "'", "+", "*", "~", "=", "?"}; - - /** index of the default separator inside list DELIMS. - * Its neccessary to know such default separator; because it can - * be supressed as xml attribute of the corresponding value tag. */ - private static final int DEFAULT_SEPARATOR = 0; - - //___________________________________________ - - /** analyze the structures of the given XML node and - * return a property set of all found sub nodes. - * - * Such properties are organized as [name, value] pairs. - * The type of a xml node will be detected automaticly. - * Following types are supported: - * xs:int => java.lang.Integer - * xs:bool => java.lang.Boolean - * xs:string => java.lang.String - * oor:string-list => java.util.LinkedList[java.lang.String] - * oor:set => java.util.Vector[java.lang.Object] - * oor:localized => java.util.HashMap[java.lang.Object] - * - * @param aNode - * points directly to the xml node, where we should analyze - * the children nodes. - * - * @return [java.util.HashMap] - * contains every node name as key and its string(!) as value. - */ - public static java.util.HashMap convertNodeToPropSet(org.w3c.dom.Node aNode) - throws java.lang.Exception - { - java.util.HashMap aPropSet = new java.util.HashMap(); - - // get all child nodes, which seems to be properties - java.util.Vector lChildNodes = XMLHelper.extractChildNodesByTagName(aNode, XMLTAG_PROP); - java.util.Enumeration en1 = lChildNodes.elements(); - while(en1.hasMoreElements()) - { - org.w3c.dom.Node aChildNode = (org.w3c.dom.Node)en1.nextElement(); - - // read its name - java.lang.String sChildName = XMLHelper.extractNodeAttribByName(aChildNode, XMLATTRIB_OOR_NAME); - if (sChildName == null) - throw new java.io.IOException("unsupported format: could not extract child node name"); - - // read its type info - java.lang.String sChildType = XMLHelper.extractNodeAttribByName(aChildNode, XMLATTRIB_OOR_TYPE); - if (sChildType == null) - { - /** Special patch: - * If an xml tag has no type information set ... we can restore it - * by analyzing the already readed tag name :-) - * Not very nice - but it can help to read stripped xml files too. */ - sChildType = XMLHelper.getTypeForTag(sChildName); - if (sChildType == null) - throw new java.io.IOException("unsupported format: could not extract child node type"); - } - - // read its value(s?) - java.util.Vector lChildValues = XMLHelper.extractChildNodesByTagName(aChildNode, XMLTAG_VALUE); - java.util.Enumeration en2 = lChildValues.elements(); - int nValue = 0; - java.lang.Object aValue = null; - while(en2.hasMoreElements()) - { - org.w3c.dom.Node aValueNode = (org.w3c.dom.Node)en2.nextElement(); - java.lang.String sChildLocale = XMLHelper.extractNodeAttribByName(aValueNode, XMLATTRIB_XML_LANG); - boolean bLocalized = (sChildLocale != null); - - ++nValue; - - if (sChildType.equals(XMLTYPE_INTEGER)) - { - if (!bLocalized && nValue > 1) - throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); - java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); - aValue = new java.lang.Integer(sData); - } - else - if (sChildType.equals(XMLTYPE_BOOLEAN)) - { - if (!bLocalized && nValue > 1) - throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); - java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); - aValue = new java.lang.Boolean(sData); - } - else - if (sChildType.equals(XMLTYPE_STRING)) - { - if (!bLocalized && nValue > 1) - throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); - - java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); - - java.util.HashMap lLocalized = null; - if (bLocalized) - { - if (aValue == null) - aValue = new java.util.HashMap(); - lLocalized = (java.util.HashMap)aValue; - lLocalized.put(sChildLocale, sData); - } - else - aValue = sData; - } - else - if (sChildType.equals(XMLTYPE_STRINGLIST)) - { - if (!bLocalized && nValue > 1) - throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); - - java.lang.String sSeparator = XMLHelper.extractNodeAttribByName(aChildNode, XMLATTRIB_OOR_SEPARATOR); - if (sSeparator == null) - sSeparator = " "; - - java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); - sData = sData.replace('\t', ' '); - sData = sData.replace('\n', ' '); - java.util.StringTokenizer aTokenizer = new java.util.StringTokenizer(sData, sSeparator); - java.util.Vector lList = new java.util.Vector(); - while(aTokenizer.hasMoreTokens()) - { - java.lang.String sToken = (java.lang.String)aTokenizer.nextToken(); - sToken.trim(); - if (sToken.length() < 1) - continue; - lList.add(sToken); - } - aValue = lList; - } - - aPropSet.put(sChildName, aValue); - } - } - - return aPropSet; - } - - //___________________________________________ - - private static java.lang.String getTypeForTag(java.lang.String sTag) - { - java.lang.String sType = null; - - if ( - (sTag.equals(Cache.PROPNAME_DATA )) || - (sTag.equals(Cache.PROPNAME_NAME )) || - (sTag.equals(Cache.PROPNAME_UINAME )) || - (sTag.equals(Cache.PROPNAME_MEDIATYPE )) || - (sTag.equals(Cache.PROPNAME_CLIPBOARDFORMAT )) || - (sTag.equals(Cache.PROPNAME_PREFERREDFILTER )) || - (sTag.equals(Cache.PROPNAME_DETECTSERVICE )) || - (sTag.equals(Cache.PROPNAME_FRAMELOADER )) || - (sTag.equals(Cache.PROPNAME_CONTENTHANDLER )) || - (sTag.equals(Cache.PROPNAME_DOCUMENTSERVICE )) || - (sTag.equals(Cache.PROPNAME_FILTERSERVICE )) || - (sTag.equals(Cache.PROPNAME_TEMPLATENAME )) || - (sTag.equals(Cache.PROPNAME_TYPE )) || - (sTag.equals(Cache.PROPNAME_UICOMPONENT )) - ) - sType = XMLTYPE_STRING; - else - if ( - (sTag.equals(Cache.PROPNAME_PREFERRED )) || - (sTag.equals("Installed" )) - ) - sType = XMLTYPE_BOOLEAN; - else - if ( - (sTag.equals(Cache.PROPNAME_UIORDER )) || - (sTag.equals(Cache.PROPNAME_DOCUMENTICONID )) || - (sTag.equals(Cache.PROPNAME_FILEFORMATVERSION)) - ) - sType = XMLTYPE_INTEGER; - else - if ( - (sTag.equals(Cache.PROPNAME_URLPATTERN )) || - (sTag.equals(Cache.PROPNAME_EXTENSIONS )) || - (sTag.equals(Cache.PROPNAME_USERDATA )) || - (sTag.equals(Cache.PROPNAME_FLAGS )) || - (sTag.equals(Cache.PROPNAME_TYPES )) - ) - sType = XMLTYPE_STRINGLIST; - - if (sType == null) - System.err.println("getTypeForTag("+sTag+") = "+sType); - - return sType; - } - - //___________________________________________ - - /** return a xml representation of the given property set. - * - * @param aPropSet - * a set of pairs, which should be translated to xml - * - * @return [java.lang.String] - * the xml string representation. - * - * @throws [java.lang.Exception] - * if anything during convertion fill fail. - */ - public static java.lang.String convertPropSetToXML(java.util.HashMap aPropSet , - int nPrettyTabs) - throws java.lang.Exception - { - java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); - - java.util.Iterator it1 = aPropSet.keySet().iterator(); - while(it1.hasNext()) - { - java.lang.String sProp = (java.lang.String)it1.next(); - java.lang.Object aVal = aPropSet.get(sProp); - - sProp = encodeHTMLSigns(sProp); - - // is it a simple type? - if ( - (aVal instanceof java.lang.Integer) || - (aVal instanceof java.lang.Boolean) || - (aVal instanceof java.lang.String ) - ) - { - sXML.append(XMLHelper.convertSimpleObjectToXML(sProp, aVal, nPrettyTabs)); - continue; - } - - // no! - // is it a list value? - if (aVal instanceof java.util.Vector) - { - java.util.Vector lVal = (java.util.Vector)aVal; - sXML.append(XMLHelper.convertListToXML(sProp, lVal, nPrettyTabs)); - continue; - } - - // its a localized value? - if (aVal instanceof java.util.HashMap) - { - java.util.HashMap lVal = (java.util.HashMap)aVal; - sXML.append(XMLHelper.convertLocalizedValueToXML(sProp, lVal, nPrettyTabs)); - continue; - } - - // unknown type! - java.lang.StringBuffer sMsg = new java.lang.StringBuffer(256); - sMsg.append("unsupported object type detected."); - sMsg.append("\ttype ? : \""+sProp+"\" = "+aVal); - sMsg.append("\tprop set: \""+aPropSet ); - throw new java.lang.Exception(sMsg.toString()); - } - - return sXML.toString(); - } - - public static java.lang.String encodeHTMLSigns(java.lang.String sValue) - { - java.lang.StringBuffer sSource = new java.lang.StringBuffer(sValue); - java.lang.StringBuffer sDestination = new java.lang.StringBuffer(1000 ); - - for (int i=0; i \""+sReturn+"\""); - - return sReturn; - } - - //___________________________________________ - - /** return a xml representation of an atomic property. - * - * Atomic property types are e.g. Integer, Boolean, String. - * - * @param sName - * the name of the property. - - * @param aValue - * the value of the property. - * - * @param nPrettyTabs - * count of tab signs for pretty format the xml code :-) - * - * @return [java.lang.String] - * the xml string representation. - * - * @throws [java.lang.Exception] - * if anything during convertion fill fail. - */ - private static java.lang.String convertSimpleObjectToXML(java.lang.String sName , - java.lang.Object aValue , - int nPrettyTabs) - throws java.lang.Exception - { - java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); - for (int t=0; t"); - sXML.append(""+aValue.toString()+""); - sXML.append("\n"); - } - else - if (aValue instanceof java.lang.Boolean) - { - sXML.append(""); - sXML.append(""+aValue.toString()+""); - sXML.append("\n"); - } - else - if (aValue instanceof java.lang.String) - { - sXML.append("\n"); - else - { - sXML.append(">"+sValue+""); - sXML.append("\n"); - } - } - else - { - System.err.println("name = "+sName); - System.err.println("value = "+aValue); - // ! can be used outside to detect - that it was not a simple type :-) - throw new java.lang.Exception("not an atomic type."); - } - - return sXML.toString(); - } - - //___________________________________________ - - /** return a xml representation of a string-list property. - * - * @param sName - * the name of the property. - - * @param aValue - * the value of the property. - * - * @param nPrettyTabs - * count of tab signs for pretty format the xml code :-) - * - * @return [java.lang.String] - * the xml string representation. - * - * @throws [java.lang.Exception] - * if anything during convertion fill fail. - */ - private static java.lang.String convertListToXML(java.lang.String sName , - java.util.Vector aValue , - int nPrettyTabs) - throws java.lang.Exception - { - java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); - - for (int t=0; t\n"); - return sXML.toString(); - } - - // step over all list items and add it to a string buffer - // Every item will be separated by a default separator "\n" first. - // Because "\n" is not a valid separator at all and can`t occure inside - // our list items. During we step over all items, we check if our current separator - // (we use a list of possible ones!) clash with an item. - // If it clash - we step to the next possible separator. - // If our list of possible separator values runs out of range we throw - // an exception :-) Its better then generating of wrong values - // If we found a valid seperator - we use it to replace our "\n" place holder - // at the end of the following loop ... - - int d = 0; - java.lang.StringBuffer sValBuff = new java.lang.StringBuffer(256); - for (int i=0; i= DELIMS.length) - throw new java.lang.Exception("No valid separator found for a string list item."); - if (sValue.length() < 1 && DELIMS[d].equals(" ")) - { - ++d; - continue; - } - if (sValue.indexOf(DELIMS[d]) != -1) - { - ++d; - continue; - } - break; - } - } - - // replace default separator with right one - System.out.println("TODO: must be adapted to java 1.3 :-("); - System.exit(-1); -//TODO_JAVA java.lang.String sListVal = sValBuff.toString().replaceAll("\n", DELIMS[d]); - java.lang.String sListVal = null; - - sXML.append(""); - if (d == DEFAULT_SEPARATOR) - sXML.append(""); - else - sXML.append(""); - sXML.append(sListVal); - sXML.append(""); - sXML.append("\n"); - - return sXML.toString(); - } - - //___________________________________________ - - /** return a xml representation of a localized property. - * - * @param sName - * the name of the property. - - * @param aValue - * the value of the property. - * - * @param nPrettyTabs - * count of tab signs for pretty format the xml code :-) - * - * @return [java.lang.String] - * the xml string representation. - * - * @throws [java.lang.Exception] - * if anything during convertion fill fail. - */ - private static java.lang.String convertLocalizedValueToXML(java.lang.String sName , - java.util.HashMap aValue , - int nPrettyTabs) - throws java.lang.Exception - { - java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); - - int c = aValue.size(); - if (c < 1) - throw new java.lang.Exception("Cant detect type of localized values. Because the given list is empty."); - - for (int t=0; t\n"); - java.util.Iterator it = aValue.keySet().iterator(); -// boolean bTypeKnown = false; - while(it.hasNext()) - { - java.lang.String sLocale = (java.lang.String)it.next(); - java.lang.Object aLocalizedValue = aValue.get(sLocale); -/* - if (!bTypeKnown) - { - bTypeKnown = true; - if (aLocalizedValue instanceof java.lang.Integer) - sXML.append(" "+XMLATTRIB_OOR_TYPE+"=\""+XMLTYPE_INTEGER+"\">\n"); - else - if (aLocalizedValue instanceof java.lang.Boolean) - sXML.append(" "+XMLATTRIB_OOR_TYPE+"=\""+XMLTYPE_BOOLEAN+"\">\n"); - else - if (aLocalizedValue instanceof java.lang.String) - sXML.append(" "+XMLATTRIB_OOR_TYPE+"=\""+XMLTYPE_STRING+"\">\n"); - else - throw new java.lang.Exception("Unsupported type for localized value detected."); - } -*/ - java.lang.String sLocValue = aLocalizedValue.toString(); - java.lang.String sValue = encodeHTMLSigns(sLocValue); - - for (int t=0; t"+sValue+"\n"); - } - --nPrettyTabs; - for (int t=0; t\n"); - - return sXML.toString(); - } - - //___________________________________________ - - /** returns the value of an attribute of the given node. - * - * If the given node represent an lement node, may it supports some attributes. - * Then this method search for an attribute with the specified name and return it's value. - * If nothing could be found ... or the given node isn't a suitable node ... it returns null. - * - * @param aNode - * the node, which should be analyzed. - * - * @param sAttrib - * name of the attribute, which should be searched. - * - * @return The value of the specified attribute if it could be found at the given node. - * Can be null if node doesn't support attributes or the searched one does not exist there. - */ - public static java.lang.String extractNodeAttribByName(org.w3c.dom.Node aNode , - java.lang.String sAttrib) - throws java.lang.Exception - { - // We can get valid attributes for element nodes only! - if (aNode.getNodeType() != org.w3c.dom.Node.ELEMENT_NODE) - { -// System.err.println("not an element node"); - return null; - } - - // may it supports attributes in general ... but doesn't have anyone realy. - org.w3c.dom.NamedNodeMap lAttribs = aNode.getAttributes(); - if (lAttribs==null) - { -// System.err.println("no attributes at all"); - return null; - } - - // step over the attribute list and search for the requested one - for (int i=0; i\n"); - sHeader.append("\n"); - } - else - { - sHeader.append("\n\n"); - sHeader.append("\n"); - } - - return sHeader.toString(); - } - - public static java.lang.String generateFooter() - { - return "\n"; - } -} diff --git a/filter/source/config/tools/utils/makefile.mk b/filter/source/config/tools/utils/makefile.mk deleted file mode 100644 index 0b2b89efeb7a..000000000000 --- a/filter/source/config/tools/utils/makefile.mk +++ /dev/null @@ -1,63 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2008 by Sun Microsystems, Inc. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# $RCSfile: makefile.mk,v $ -# -# $Revision: 1.9.98.2 $ -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ = ..$/..$/..$/.. -TARGET = FCFGUtils -PRJNAME = filter -PACKAGE = com$/sun$/star$/filter$/config$/tools$/utils - -# --- Settings ----------------------------------------------------- - -.INCLUDE: settings.mk - -#----- compile .java files ----------------------------------------- - -JARFILES = \ - ridl.jar \ - unoil.jar \ - jurt.jar \ - juh.jar \ - java_uno.jar - -JAVACLASSFILES = \ - $(CLASSDIR)$/$(PACKAGE)$/AnalyzeStartupLog.class \ - $(CLASSDIR)$/$(PACKAGE)$/ConfigHelper.class \ - $(CLASSDIR)$/$(PACKAGE)$/Logger.class \ - $(CLASSDIR)$/$(PACKAGE)$/FileHelper.class \ - $(CLASSDIR)$/$(PACKAGE)$/MalformedCommandLineException.class \ - $(CLASSDIR)$/$(PACKAGE)$/Cache.class \ - $(CLASSDIR)$/$(PACKAGE)$/XMLHelper.class - -MAXLINELENGTH = 100000 - -# --- targets ----------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/util/makefile.mk b/oox/util/makefile.mk index 93669d2d40b1..bf12b1addf1b 100644 --- a/oox/util/makefile.mk +++ b/oox/util/makefile.mk @@ -39,7 +39,7 @@ ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk - +.IF "$(L10N_framework)"=="" # --- Allgemein ---------------------------------------------------- LIB1TARGET= $(SLB)$/$(TARGET).lib @@ -94,5 +94,6 @@ DEF1NAME =$(SHL1TARGET) DEFLIB1NAME =$(TARGET) # --- Targets ---------------------------------------------------------- +.ENDIF # L10N_framework .INCLUDE : target.mk diff --git a/unoxml/source/rdf/makefile.mk b/unoxml/source/rdf/makefile.mk index 4ff9e4fdfeab..298c1dcdae25 100644 --- a/unoxml/source/rdf/makefile.mk +++ b/unoxml/source/rdf/makefile.mk @@ -46,6 +46,7 @@ CFLAGS+=-DSYSTEM_REDLAND $(REDLAND_CFLAGS) .ENDIF # --- Files -------------------------------------------------------- +.IF "$(L10N_framework)"=="" SLOFILES = \ $(SLO)$/CBlankNode.obj \ @@ -71,6 +72,7 @@ SHL1STDLIBS= \ $(CPPULIB) \ $(SALLIB) \ +.ENDIF # --- Targets ------------------------------------------------------ diff --git a/xmerge/source/aportisdoc/makefile.mk b/xmerge/source/aportisdoc/makefile.mk index ff417c0800ef..67d763faa344 100644 --- a/xmerge/source/aportisdoc/makefile.mk +++ b/xmerge/source/aportisdoc/makefile.mk @@ -34,4 +34,6 @@ PRJ=../.. PRJNAME=xmerge .INCLUDE : ant.mk +.IF "$(L10N_framework)"=="" ALLTAR: ANTBUILD +.ENDIF diff --git a/xmerge/source/bridge/makefile.mk b/xmerge/source/bridge/makefile.mk index e5d84bcd5683..b0dc37169a4b 100644 --- a/xmerge/source/bridge/makefile.mk +++ b/xmerge/source/bridge/makefile.mk @@ -34,4 +34,6 @@ PRJ=../.. PRJNAME=xmerge .INCLUDE : ant.mk +.IF "$(L10N_framework)"=="" ALLTAR: ANTBUILD +.ENDIF diff --git a/xmerge/source/htmlsoff/makefile.mk b/xmerge/source/htmlsoff/makefile.mk index c98aa939c8c6..d164ccdf78c2 100644 --- a/xmerge/source/htmlsoff/makefile.mk +++ b/xmerge/source/htmlsoff/makefile.mk @@ -34,4 +34,6 @@ PRJ=../.. PRJNAME=xmerge .INCLUDE : ant.mk +.IF "$(L10N_framework)"=="" ALLTAR: ANTBUILD +.ENDIF diff --git a/xmerge/source/pexcel/makefile.mk b/xmerge/source/pexcel/makefile.mk index 08767f848978..c0fdb53a676c 100644 --- a/xmerge/source/pexcel/makefile.mk +++ b/xmerge/source/pexcel/makefile.mk @@ -34,4 +34,6 @@ PRJ=../.. PRJNAME=xmerge .INCLUDE : ant.mk +.IF "$(L10N_framework)"=="" ALLTAR: ANTBUILD +.ENDIF diff --git a/xmerge/source/pocketword/makefile.mk b/xmerge/source/pocketword/makefile.mk index 51385e8a4afb..24f6e45cfd24 100644 --- a/xmerge/source/pocketword/makefile.mk +++ b/xmerge/source/pocketword/makefile.mk @@ -34,4 +34,6 @@ PRJ=../.. PRJNAME=xmerge .INCLUDE : ant.mk +.IF "$(L10N_framework)"=="" ALLTAR: ANTBUILD +.ENDIF diff --git a/xmerge/source/xmerge/makefile.mk b/xmerge/source/xmerge/makefile.mk index f1ca30f5d0a8..7420f886ed38 100644 --- a/xmerge/source/xmerge/makefile.mk +++ b/xmerge/source/xmerge/makefile.mk @@ -33,4 +33,6 @@ TARGET=xmerge PRJ=../.. .INCLUDE : ant.mk +.IF "$(L10N_framework)"=="" ALLTAR: ANTBUILD +.ENDIF diff --git a/xmerge/util/makefile.mk b/xmerge/util/makefile.mk index cbb13db595a9..61ee7d712eb5 100644 --- a/xmerge/util/makefile.mk +++ b/xmerge/util/makefile.mk @@ -33,4 +33,6 @@ TARGET=xmrg_util PRJ=.. .INCLUDE : ant.mk +.IF "$(L10N_framework)"=="" ALLTAR: ANTBUILD +.ENDIF From 1df173a6bd8fe83b77c3e92ea0a3c5ce6a26e483 Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Wed, 16 Sep 2009 12:38:01 +0000 Subject: [PATCH 08/16] CWS-TOOLING: integrate CWS impressnotes02 --- filter/source/pdf/impdialog.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src index d9bcfebc2008..00abf5b5ebd4 100644 --- a/filter/source/pdf/impdialog.src +++ b/filter/source/pdf/impdialog.src @@ -208,7 +208,7 @@ TabPage RID_PDF_TAB_GENER Pos = MAP_APPFONT ( 12 , 193 ) ; Size = MAP_APPFONT ( 158 , 10 ) ; TabStop = TRUE ; - Text[ en-US ] = "~Export notes"; + Text[ en-US ] = "~Export comments"; }; CheckBox CB_EXPORTEMPTYPAGES { From ff30491fc477a39f8f5509298fbd84449f7665b3 Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Thu, 17 Sep 2009 11:09:25 +0000 Subject: [PATCH 10/16] CWS-TOOLING: integrate CWS dr69 2009-09-09 11:45:28 +0200 dr r275979 : suncc failure 2009-09-09 11:33:34 +0200 dr r275977 : gcc warning 2009-09-09 11:09:02 +0200 er r275976 : #i87171# reworked name check for creating defined names 2009-09-09 10:38:02 +0200 dr r275973 : adapt changes in oox base class 2009-09-09 10:21:03 +0200 dr r275969 : remove faulty pagesize stuff 2009-09-09 10:20:13 +0200 dr r275968 : remove faulty pagesize stuff 2009-09-08 20:24:39 +0200 nn r275958 : #i104899# interpret cells when creating chart listener after loading 2009-09-08 16:05:37 +0200 er r275937 : ScXMLDDELinkContext::EndElement: Excel writes bad ODF without 's table:number-columns-repeated attribute; be lenient ... 2009-09-08 13:14:54 +0200 er r275925 : #i103315# handle external references in Excel's ODF msoxl namespace 2009-09-07 17:37:18 +0200 dr r275907 : #i104753# crash when deleting cell with note 2009-09-07 14:02:29 +0200 dr r275896 : #i103520# reworked sheet name buffer to resolve internal hyperlinks, fix almost all remaining problems with external links in BIFF, fix auto color import for BIFF 2009-09-06 20:01:05 +0200 er r275862 : #i35913# fix regression introduced by integration of CWS fhawfixes1; patch from 2009-09-05 18:32:00 +0200 er r275847 : #i104156# merge #i103918# from uncloned dr68ooo311 2009-09-05 18:19:23 +0200 er r275846 : #i104156# merge #i103317# from uncloned dr68ooo311 2009-09-05 17:32:12 +0200 er r275844 : #i104484# glueState: correct casts in range bounds; patch from slightly modified 2009-09-03 17:26:38 +0200 dr r275764 : #i103520# handle apostrophs in sheet names in internal URLs 2009-09-03 17:21:26 +0200 dr r275763 : #i95271# show text formatting in temp notes 2009-09-03 12:24:52 +0200 dr r275747 : unused declaration 2009-09-02 21:33:03 +0200 dr r275727 : #i96438# cleanup color handling in xls filter, extend VML color parser 2009-09-02 15:39:57 +0200 dr r275715 : #158571# #i96438# accept also VML colors in the form '#RRGGBB [xyz]' 2009-09-02 15:16:36 +0200 dr r275714 : #158571# #i96438# set note text 2009-09-02 14:59:33 +0200 dr r275713 : #158571# #i96438# load custom line dashes from DrawingML and VML 2009-09-02 11:53:35 +0200 dr r275702 : #158571# #i96438# import VML fill gradients 2009-08-31 19:28:10 +0200 dr r275632 : #158571# #i96438# more vml formatting 2009-08-31 14:29:30 +0200 dr r275606 : #158571# #i96438# changed handling of xml token ids/names 2009-08-28 18:25:26 +0200 dr r275545 : #158571# #i96438# preparations for and basic support of VML shape formatting, load spreadsheet cell notes position, formatting, and visibility 2009-08-25 19:08:31 +0200 dr r275378 : #i103390# dump BIFF STYLEEXT 2009-08-25 18:28:50 +0200 dr r275377 : #i103390# improve built-in style handling 2009-08-25 18:27:38 +0200 dr r275376 : #i103390# improve built-in style handling 2009-08-04 18:49:40 +0200 dr r274629 : CWS-TOOLING: rebase CWS dr69 to trunk@274622 (milestone: DEV300:m54) --- oox/inc/oox/core/fasttokenhandler.hxx | 30 +- oox/inc/oox/core/filterbase.hxx | 7 +- oox/inc/oox/core/xmlfilterbase.hxx | 3 - oox/inc/oox/drawingml/color.hxx | 34 +- .../oox/drawingml/customshapeproperties.hxx | 2 +- oox/inc/oox/drawingml/drawingmltypes.hxx | 8 + oox/inc/oox/drawingml/fillproperties.hxx | 22 +- oox/inc/oox/drawingml/lineproperties.hxx | 17 +- oox/inc/oox/helper/containerhelper.hxx | 33 +- oox/inc/oox/helper/helper.hxx | 3 +- oox/inc/oox/helper/propertymap.hxx | 14 +- oox/inc/oox/ole/axcontrolhelper.hxx | 2 - oox/inc/oox/ppt/pptimport.hxx | 5 +- oox/inc/oox/token/propertylist.hxx | 53 ++ oox/inc/oox/token/tokenmap.hxx | 84 +++ oox/inc/oox/vml/vmldrawing.hxx | 4 + oox/inc/oox/vml/vmlformatting.hxx | 187 ++++++ oox/inc/oox/vml/vmlshape.hxx | 30 +- oox/inc/oox/vml/vmlshapecontainer.hxx | 22 + oox/inc/oox/vml/vmlshapecontext.hxx | 6 +- oox/inc/oox/xls/biffhelper.hxx | 1 + oox/inc/oox/xls/chartsheetfragment.hxx | 4 +- oox/inc/oox/xls/defnamesbuffer.hxx | 38 +- oox/inc/oox/xls/drawingfragment.hxx | 6 + oox/inc/oox/xls/excelfilter.hxx | 30 +- oox/inc/oox/xls/excelhandlers.hxx | 14 +- oox/inc/oox/xls/externallinkbuffer.hxx | 30 +- oox/inc/oox/xls/richstring.hxx | 6 + oox/inc/oox/xls/stylesbuffer.hxx | 66 +- oox/inc/oox/xls/themebuffer.hxx | 2 - oox/inc/oox/xls/viewsettings.hxx | 12 +- oox/inc/oox/xls/workbookfragment.hxx | 2 +- oox/inc/oox/xls/workbookhelper.hxx | 9 +- oox/inc/oox/xls/worksheetbuffer.hxx | 54 +- oox/inc/oox/xls/worksheetfragment.hxx | 4 +- oox/inc/oox/xls/worksheethelper.hxx | 7 +- oox/source/core/fasttokenhandler.cxx | 95 +++ oox/source/core/filterbase.cxx | 14 +- oox/source/core/makefile.mk | 1 + oox/source/core/xmlfilterbase.cxx | 15 +- .../drawingml/chart/objectformatter.cxx | 4 +- oox/source/drawingml/clrschemecontext.cxx | 1 + oox/source/drawingml/color.cxx | 576 ++++++++--------- .../drawingml/customshapeproperties.cxx | 2 +- oox/source/drawingml/fillproperties.cxx | 60 +- oox/source/drawingml/lineproperties.cxx | 153 +++-- .../drawingml/linepropertiescontext.cxx | 6 + oox/source/drawingml/shape.cxx | 6 +- oox/source/drawingml/table/tablecell.cxx | 3 +- .../drawingml/textcharacterproperties.cxx | 1 + .../drawingml/textparagraphproperties.cxx | 1 + oox/source/dump/biffdumper.cxx | 19 +- oox/source/dump/biffdumper.ini | 22 +- oox/source/helper/propertymap.cxx | 24 +- oox/source/ole/axcontrolhelper.cxx | 10 +- oox/source/ppt/animvariantcontext.cxx | 1 + oox/source/ppt/pptimport.cxx | 20 +- oox/source/ppt/slidepersist.cxx | 4 +- oox/source/ppt/timenodelistcontext.cxx | 1 + oox/source/shape/FastTokenHandlerService.hxx | 19 +- oox/source/shape/ShapeFilterBase.cxx | 5 - oox/source/shape/ShapeFilterBase.hxx | 3 - oox/source/token/gentoken.pl | 14 +- oox/source/token/propertylist.cxx | 14 +- oox/source/token/tokenmap.cxx | 96 ++- oox/source/token/tokens.txt | 8 + oox/source/vml/makefile.mk | 1 + oox/source/vml/vmldrawing.cxx | 5 + oox/source/vml/vmldrawingfragment.cxx | 4 +- oox/source/vml/vmlformatting.cxx | 585 ++++++++++++++++++ oox/source/vml/vmlshape.cxx | 173 +++--- oox/source/vml/vmlshapecontext.cxx | 152 +++-- oox/source/xls/chartsheetfragment.cxx | 4 +- oox/source/xls/commentsbuffer.cxx | 39 +- oox/source/xls/defnamesbuffer.cxx | 146 +++-- oox/source/xls/drawingfragment.cxx | 42 ++ oox/source/xls/excelfilter.cxx | 64 +- oox/source/xls/excelhandlers.cxx | 6 +- oox/source/xls/externallinkbuffer.cxx | 168 +++-- oox/source/xls/externallinkfragment.cxx | 6 +- oox/source/xls/pivotcachebuffer.cxx | 4 +- oox/source/xls/richstring.cxx | 12 +- oox/source/xls/stylesbuffer.cxx | 396 ++++++------ oox/source/xls/themebuffer.cxx | 8 - oox/source/xls/viewsettings.cxx | 29 +- oox/source/xls/workbookfragment.cxx | 69 ++- oox/source/xls/workbookhelper.cxx | 33 +- oox/source/xls/worksheetbuffer.cxx | 151 +++-- oox/source/xls/worksheetfragment.cxx | 4 +- oox/source/xls/worksheethelper.cxx | 88 +-- oox/workben/pagesize/excel_pagesize.txt | 66 -- oox/workben/pagesize/parsePageSize.py | 78 --- 92 files changed, 2902 insertions(+), 1480 deletions(-) create mode 100644 oox/inc/oox/token/propertylist.hxx create mode 100644 oox/inc/oox/token/tokenmap.hxx create mode 100644 oox/inc/oox/vml/vmlformatting.hxx create mode 100644 oox/source/core/fasttokenhandler.cxx create mode 100644 oox/source/vml/vmlformatting.cxx delete mode 100644 oox/workben/pagesize/excel_pagesize.txt delete mode 100755 oox/workben/pagesize/parsePageSize.py diff --git a/oox/inc/oox/core/fasttokenhandler.hxx b/oox/inc/oox/core/fasttokenhandler.hxx index 3944011507b2..45709f9da401 100644 --- a/oox/inc/oox/core/fasttokenhandler.hxx +++ b/oox/inc/oox/core/fasttokenhandler.hxx @@ -28,27 +28,41 @@ * ************************************************************************/ -#ifndef OOX_FASTTOKENHANDLER_HXX -#define OOX_FASTTOKENHANDLER_HXX +#ifndef OOX_CORE_FASTTOKENHANDLER_HXX +#define OOX_CORE_FASTTOKENHANDLER_HXX #include #include -namespace oox { +namespace oox { class TokenMap; } +namespace oox { +namespace core { + +// ============================================================================ + +/** Wrapper implementing the com.sun.star.xml.sax.XFastTokenHandler API interface + that provides access to the tokens generated from the internal token name list. + */ class FastTokenHandler : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastTokenHandler > { public: explicit FastTokenHandler(); virtual ~FastTokenHandler(); - virtual ::sal_Int32 SAL_CALL getToken( const ::rtl::OUString& Identifier ) throw (::com::sun::star::uno::RuntimeException); - virtual ::rtl::OUString SAL_CALL getIdentifier( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getUTF8Identifier( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Int32 SAL_CALL getTokenFromUTF8( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& Identifier ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getToken( const ::rtl::OUString& rIdentifier ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getIdentifier( sal_Int32 nToken ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getUTF8Identifier( sal_Int32 nToken ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getTokenFromUTF8( const ::com::sun::star::uno::Sequence< sal_Int8 >& Identifier ) throw (::com::sun::star::uno::RuntimeException); + +private: + const TokenMap& mrTokenMap; /// Reference to global token map singleton. }; -} +// ============================================================================ + +} // namespace core +} // namespace oox #endif diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx index 9115c88be4e7..adfb8d6d0941 100644 --- a/oox/inc/oox/core/filterbase.hxx +++ b/oox/inc/oox/core/filterbase.hxx @@ -198,8 +198,13 @@ public: sal_Int32 convertScreenPixelX( double fPixelX ) const; /** Converts the passed value from vertical screen pixels to 1/100 mm. */ sal_Int32 convertScreenPixelY( double fPixelY ) const; + /** Returns a system color specified by the passed XML token identifier. */ - sal_Int32 getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb = -1 ) const; + sal_Int32 getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb = API_RGB_TRANSPARENT ) const; + /** Derived classes may implement to resolve a scheme color from the passed XML token identifier. */ + virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const; + /** Derived classes may implement to resolve a palette index to an RGB color. */ + virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const; /** Requests a password from the media descriptor or from the user. On success, the password will be inserted into the media descriptor. */ diff --git a/oox/inc/oox/core/xmlfilterbase.hxx b/oox/inc/oox/core/xmlfilterbase.hxx index d1b79dc116d8..510b00ea81fc 100644 --- a/oox/inc/oox/core/xmlfilterbase.hxx +++ b/oox/inc/oox/core/xmlfilterbase.hxx @@ -87,9 +87,6 @@ public: virtual const ::oox::drawingml::Theme* getCurrentTheme() const = 0; - /** Has to be implemented by each filter to resolve scheme colors. */ - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const = 0; - /** Has to be implemented by each filter to return the collection of VML shapes. */ virtual ::oox::vml::Drawing* getVmlDrawing() = 0; diff --git a/oox/inc/oox/drawingml/color.hxx b/oox/inc/oox/drawingml/color.hxx index 91fddf0be69f..b1de124adad5 100644 --- a/oox/inc/oox/drawingml/color.hxx +++ b/oox/inc/oox/drawingml/color.hxx @@ -34,10 +34,11 @@ #include #include #include +#include +#include +#include "oox/helper/helper.hxx" -namespace oox { namespace core { - class XmlFilterBase; -} } +namespace oox { namespace core { class FilterBase; } } namespace oox { namespace drawingml { @@ -50,6 +51,11 @@ public: Color(); ~Color(); + /** Returns the RGB value for the passed DrawingML color token, or nDefaultRgb on error. */ + static sal_Int32 getDmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ); + /** Returns the RGB value for the passed VML color token, or nDefaultRgb on error. */ + static sal_Int32 getVmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ); + /** Sets the color to unused state. */ void setUnused(); /** Sets an RGB value (hexadecimal RRGGBB) from the a:srgbClr element. */ @@ -64,6 +70,8 @@ public: void setSchemeClr( sal_Int32 nToken ); /** Sets a system color from the a:sysClr element. */ void setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb ); + /** Sets a palette color index. */ + void setPaletteClr( sal_Int32 nPaletteIdx ); /** Inserts the passed color transformation. */ void addTransformation( sal_Int32 nElement, sal_Int32 nValue = -1 ); @@ -71,17 +79,21 @@ public: void addChartTintTransformation( double fTint ); /** Inserts Excel specific color tint (-1.0...0.0 = shade, 0.0...1.0 = tint). */ void addExcelTintTransformation( double fTint ); - - /** Overwrites this color with the passed color, if it is used. */ - inline void assignIfUsed( const Color& rColor ) { if( rColor.isUsed() ) *this = rColor; } + /** Removes all color transformations. */ + void clearTransformations(); /** Removes transparence from the color. */ void clearTransparence(); + /** Overwrites this color with the passed color, if it is used. */ + inline void assignIfUsed( const Color& rColor ) { if( rColor.isUsed() ) *this = rColor; } + /** Returns true, if the color is initialized. */ bool isUsed() const { return meMode != COLOR_UNUSED; } + /** Returns true, if the color is a placeholder color in theme style lists. */ + bool isPlaceHolder() const { return meMode == COLOR_PH; } /** Returns the final RGB color value. @param nPhClr Actual color for the phClr placeholder color used in theme style lists. */ - sal_Int32 getColor( const ::oox::core::XmlFilterBase& rFilter, sal_Int32 nPhClr = -1 ) const; + sal_Int32 getColor( const ::oox::core::FilterBase& rFilter, sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Returns true, if the color has a transparence set. */ bool hasTransparence() const; @@ -89,6 +101,9 @@ public: sal_Int16 getTransparence() const; private: + /** Internal helper for getColor(). */ + void setResolvedRgb( sal_Int32 nRgb ) const; + /** Converts the color components to RGB values. */ void toRgb() const; /** Converts the color components to CRGB values (gamma corrected percentage). */ @@ -104,8 +119,9 @@ private: COLOR_CRGB, /// Relative RGB (r/g/b: 0...100000). COLOR_HSL, /// HSL (hue: 0...21600000, sat/lum: 0...100000). COLOR_SCHEME, /// Color from scheme. - COLOR_PH, /// Placeholder color in theme style lists. + COLOR_PALETTE, /// Color from application defined palette. COLOR_SYSTEM, /// Color from system palette. + COLOR_PH, /// Placeholder color in theme style lists. COLOR_FINAL /// Finalized RGB color. }; @@ -120,7 +136,7 @@ private: mutable ColorMode meMode; /// Current color mode. mutable TransformVec maTransforms; /// Color transformations. - mutable sal_Int32 mnC1; /// Red, red%, hue, scheme token, system token, or final RGB. + mutable sal_Int32 mnC1; /// Red, red%, hue, scheme token, palette index, system token, or final RGB. mutable sal_Int32 mnC2; /// Green, green%, saturation, or system default RGB. mutable sal_Int32 mnC3; /// Blue, blue%, or luminance. sal_Int32 mnAlpha; /// Alpha value (color opacity). diff --git a/oox/inc/oox/drawingml/customshapeproperties.hxx b/oox/inc/oox/drawingml/customshapeproperties.hxx index 17a308a6331c..9857a75e4836 100644 --- a/oox/inc/oox/drawingml/customshapeproperties.hxx +++ b/oox/inc/oox/drawingml/customshapeproperties.hxx @@ -72,7 +72,7 @@ public: virtual ~CustomShapeProperties(); void apply( const CustomShapePropertiesPtr& ); - void pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase, + void pushToPropSet( const ::oox::core::FilterBase& rFilterBase, const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > & xPropSet, const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape > & xShape) const; diff --git a/oox/inc/oox/drawingml/drawingmltypes.hxx b/oox/inc/oox/drawingml/drawingmltypes.hxx index fbec84c4b81c..41365f8df086 100644 --- a/oox/inc/oox/drawingml/drawingmltypes.hxx +++ b/oox/inc/oox/drawingml/drawingmltypes.hxx @@ -43,6 +43,14 @@ namespace drawingml { // ============================================================================ +const sal_Int32 PER_PERCENT = 1000; +const sal_Int32 MAX_PERCENT = 100 * PER_PERCENT; + +const sal_Int32 PER_DEGREE = 60000; +const sal_Int32 MAX_DEGREE = 360 * PER_DEGREE; + +// ============================================================================ + struct LineProperties; typedef ::boost::shared_ptr< LineProperties > LinePropertiesPtr; diff --git a/oox/inc/oox/drawingml/fillproperties.hxx b/oox/inc/oox/drawingml/fillproperties.hxx index 9190b87e0e53..9504da617083 100644 --- a/oox/inc/oox/drawingml/fillproperties.hxx +++ b/oox/inc/oox/drawingml/fillproperties.hxx @@ -159,18 +159,20 @@ struct FillProperties /** Writes the properties to the passed property map. */ void pushToPropMap( PropertyMap& rPropMap, - const FillPropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const; + const FillPropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nShapeRotation = 0, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Writes the properties to the passed property set. */ void pushToPropSet( PropertySet& rPropSet, - const FillPropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const; + const FillPropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nShapeRotation = 0, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; }; // ============================================================================ @@ -185,14 +187,14 @@ struct GraphicProperties /** Writes the properties to the passed property map. */ void pushToPropMap( PropertyMap& rPropMap, - const ::oox::core::XmlFilterBase& rFilter, - sal_Int32 nPhClr ) const; + const ::oox::core::FilterBase& rFilter, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Writes the properties to the passed property set. */ void pushToPropSet( PropertySet& rPropSet, - const ::oox::core::XmlFilterBase& rFilter, - sal_Int32 nPhClr ) const; + const ::oox::core::FilterBase& rFilter, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; }; // ============================================================================ diff --git a/oox/inc/oox/drawingml/lineproperties.hxx b/oox/inc/oox/drawingml/lineproperties.hxx index 2aa9ac7fedeb..db337c520092 100644 --- a/oox/inc/oox/drawingml/lineproperties.hxx +++ b/oox/inc/oox/drawingml/lineproperties.hxx @@ -86,11 +86,16 @@ struct LineArrowProperties struct LineProperties { + typedef ::std::pair< sal_Int32, sal_Int32 > DashStop; + typedef ::std::vector< DashStop > DashStopVector; + LineArrowProperties maStartArrow; /// Start line arrow style. LineArrowProperties maEndArrow; /// End line arrow style. FillProperties maLineFill; /// Line fill (solid, gradient, ...). + DashStopVector maCustomDash; /// User-defined line dash style. OptValue< sal_Int32 > moLineWidth; /// Line width (EMUs). OptValue< sal_Int32 > moPresetDash; /// Preset dash (OOXML token). + OptValue< sal_Int32 > moLineCompound; /// Line compound type (OOXML token). OptValue< sal_Int32 > moLineCap; /// Line cap (OOXML token). OptValue< sal_Int32 > moLineJoint; /// Line joint type (OOXML token). @@ -102,18 +107,18 @@ struct LineProperties /** Writes the properties to the passed property map. */ void pushToPropMap( PropertyMap& rPropMap, - const LinePropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nPhClr ) const; + const LinePropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Writes the properties to the passed property map. */ void pushToPropSet( PropertySet& rPropSet, - const LinePropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nPhClr ) const; + const LinePropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; }; // ============================================================================ diff --git a/oox/inc/oox/helper/containerhelper.hxx b/oox/inc/oox/helper/containerhelper.hxx index be3736e92a47..8186d537faee 100644 --- a/oox/inc/oox/helper/containerhelper.hxx +++ b/oox/inc/oox/helper/containerhelper.hxx @@ -91,7 +91,7 @@ public: template< typename FunctorType > inline void forEach( const FunctorType& rFunctor ) const { - ::std::for_each( this->begin(), this->end(), Functor< FunctorType >( rFunctor ) ); + ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) ); } /** Calls the passed member function of ObjType on every contained object. */ @@ -115,13 +115,30 @@ public: forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) ); } + /** Searches for an element by using the passed functor that takes a + constant reference of the object type (const ObjType&). */ + template< typename FunctorType > + inline value_type findIf( const FunctorType& rFunctor ) const + { + typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) ); + return (aIt == this->end()) ? value_type() : *aIt; + } + private: template< typename FunctorType > - struct Functor + struct ForEachFunctor { const FunctorType& mrFunctor; - inline explicit Functor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} - inline void operator()( const value_type& rValue ) const { mrFunctor( *rValue ); } + inline explicit ForEachFunctor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline void operator()( const value_type& rxValue ) const { if( rxValue.get() ) mrFunctor( *rxValue ); } + }; + + template< typename FunctorType > + struct FindFunctor + { + const FunctorType& mrFunctor; + inline explicit FindFunctor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline bool operator()( const value_type& rxValue ) const { return rxValue.get() && mrFunctor( *rxValue ); } }; inline const value_type* getRef( sal_Int32 nIndex ) const @@ -170,7 +187,7 @@ public: template< typename FunctorType > inline void forEach( const FunctorType& rFunctor ) const { - ::std::for_each( this->begin(), this->end(), Functor< FunctorType >( rFunctor ) ); + ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) ); } /** Calls the passed member function of ObjType on every contained object. */ @@ -196,11 +213,11 @@ public: private: template< typename FunctorType > - struct Functor + struct ForEachFunctor { const FunctorType& mrFunctor; - inline explicit Functor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} - inline void operator()( const value_type& rValue ) const { mrFunctor( *rValue.second ); } + inline explicit ForEachFunctor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline void operator()( const value_type& rValue ) const { if( rValue.second.get() ) mrFunctor( *rValue.second ); } }; inline const mapped_type* getRef( key_type nKey ) const diff --git a/oox/inc/oox/helper/helper.hxx b/oox/inc/oox/helper/helper.hxx index d6e2286fd8ac..f08f807da2a2 100644 --- a/oox/inc/oox/helper/helper.hxx +++ b/oox/inc/oox/helper/helper.hxx @@ -104,7 +104,8 @@ inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax ) template< typename ReturnType, typename Type > inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd ) { - BOOST_STATIC_ASSERT( ::std::numeric_limits< Type >::is_integer ); +// this BOOST_STATIC_ASSERT fails with suncc +// BOOST_STATIC_ASSERT( ::std::numeric_limits< Type >::is_integer ); Type nInterval = nEnd - nBegin; Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval); return static_cast< ReturnType >( nValue - nCount * nInterval ); diff --git a/oox/inc/oox/helper/propertymap.hxx b/oox/inc/oox/helper/propertymap.hxx index a3e84c4b73fe..58a769adbb48 100644 --- a/oox/inc/oox/helper/propertymap.hxx +++ b/oox/inc/oox/helper/propertymap.hxx @@ -44,13 +44,7 @@ namespace com { namespace sun { namespace star { namespace beans { namespace oox { -// ============================================================================ - -/** A vector that contains all predefined property names used in the filters. */ -struct PropertyNamesList : public ::std::vector< ::rtl::OUString > -{ - explicit PropertyNamesList(); -}; +struct PropertyList; // ============================================================================ @@ -66,6 +60,9 @@ typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > PropertyMapBase; class PropertyMap : public PropertyMapBase { public: + explicit PropertyMap(); + ~PropertyMap(); + /** Returns the name of the passed property identifier. */ static const ::rtl::OUString& getPropertyName( sal_Int32 nPropId ); @@ -94,6 +91,9 @@ public: /** Creates and fills a new instance supporting the XPropertySet interface. */ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > makePropertySet() const; + +private: + const PropertyList* mpPropNames; }; // ============================================================================ diff --git a/oox/inc/oox/ole/axcontrolhelper.hxx b/oox/inc/oox/ole/axcontrolhelper.hxx index 392a24a2704e..713cbcae362e 100644 --- a/oox/inc/oox/ole/axcontrolhelper.hxx +++ b/oox/inc/oox/ole/axcontrolhelper.hxx @@ -83,8 +83,6 @@ protected: /** Derived classes returns the UNO form of the current context. Called exactly once. */ virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > createControlForm() const = 0; - /** Derived classes may implement to resolve a palette index to an RGB color. */ - virtual sal_Int32 getPaletteColor( sal_uInt16 nPaletteIdx ) const; private: const ::oox::core::FilterBase& mrFilter; diff --git a/oox/inc/oox/ppt/pptimport.hxx b/oox/inc/oox/ppt/pptimport.hxx index d865e48c2569..d6c1d899ac35 100644 --- a/oox/inc/oox/ppt/pptimport.hxx +++ b/oox/inc/oox/ppt/pptimport.hxx @@ -56,10 +56,9 @@ public: virtual bool importDocument() throw(); virtual bool exportDocument() throw(); + virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const; + virtual const ::oox::drawingml::Theme* getCurrentTheme() const; - - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; - virtual ::oox::vml::Drawing* getVmlDrawing(); virtual const oox::drawingml::table::TableStyleListPtr getTableStyles(); virtual ::oox::drawingml::chart::ChartConverter& getChartConverter(); diff --git a/oox/inc/oox/token/propertylist.hxx b/oox/inc/oox/token/propertylist.hxx new file mode 100644 index 000000000000..abc776c348f6 --- /dev/null +++ b/oox/inc/oox/token/propertylist.hxx @@ -0,0 +1,53 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: propertylist.hxx,v $ + * $Revision: 1.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_TOKEN_PROPERTYLIST_HXX +#define OOX_TOKEN_PROPERTYLIST_HXX + +#include +#include + +namespace oox { + +// ============================================================================ + +/** A vector that contains all predefined property names used in the filters. */ +struct PropertyList : public ::std::vector< ::rtl::OUString > +{ + explicit PropertyList(); + ~PropertyList(); +}; + +// ============================================================================ + +} // namespace oox + +#endif + diff --git a/oox/inc/oox/token/tokenmap.hxx b/oox/inc/oox/token/tokenmap.hxx new file mode 100644 index 000000000000..e4dd0be121ce --- /dev/null +++ b/oox/inc/oox/token/tokenmap.hxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: fasttokenhandler.hxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_TOKEN_TOKENMAP_HXX +#define OOX_TOKEN_TOKENMAP_HXX + +#include +#include +#include +#include + +namespace oox { + +// ============================================================================ + +class TokenMap +{ +public: + explicit TokenMap(); + ~TokenMap(); + + /** Returns the Unicode name of the passed token identifier. */ + ::rtl::OUString getUnicodeTokenName( sal_Int32 nToken ) const; + + /** Returns the token identifier for the passed Unicode token name. */ + sal_Int32 getTokenFromUnicode( const ::rtl::OUString& rUnicodeName ) const; + + /** Returns the UTF8 name of the passed token identifier as byte sequence. */ + ::com::sun::star::uno::Sequence< sal_Int8 > + getUtf8TokenName( sal_Int32 nToken ) const; + + /** Returns the token identifier for the passed UTF8 token name. */ + sal_Int32 getTokenFromUtf8( + const ::com::sun::star::uno::Sequence< sal_Int8 >& rUtf8Name ) const; + +private: + struct TokenName + { + ::rtl::OUString maUniName; + ::com::sun::star::uno::Sequence< sal_Int8 > maUtf8Name; + }; + typedef ::std::vector< TokenName > TokenNameVector; + + TokenNameVector maTokenNames; + +}; + +// ============================================================================ + +struct StaticTokenMap : public ::rtl::Static< TokenMap, StaticTokenMap > {}; + +// ============================================================================ + +} // namespace oox + +#endif + diff --git a/oox/inc/oox/vml/vmldrawing.hxx b/oox/inc/oox/vml/vmldrawing.hxx index 4be185bbcd2a..f0bd75046c37 100644 --- a/oox/inc/oox/vml/vmldrawing.hxx +++ b/oox/inc/oox/vml/vmldrawing.hxx @@ -47,6 +47,7 @@ namespace oox { namespace ole { class AxControlHelper; } } namespace oox { namespace vml { +class ShapeBase; class ShapeContainer; struct ShapeClientData; @@ -133,6 +134,9 @@ public: /** Returns the registered info structure for a form control, if extant. */ const ControlInfo* getControlInfo( const ::rtl::OUString& rShapeId ) const; + /** Derived classes may disable conversion of specific shapes. */ + virtual bool isShapeSupported( const ShapeBase& rShape ) const; + /** Derived classes may calculate the shape rectangle from a non-standard anchor information string. */ virtual bool convertShapeClientAnchor( diff --git a/oox/inc/oox/vml/vmlformatting.hxx b/oox/inc/oox/vml/vmlformatting.hxx new file mode 100644 index 000000000000..b37da4daa28c --- /dev/null +++ b/oox/inc/oox/vml/vmlformatting.hxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: vmlformatting.hxx,v $ + * $Revision: 1.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_VML_VMLFORMATTING_HXX +#define OOX_VML_VMLFORMATTING_HXX + +#include "oox/helper/helper.hxx" + +namespace oox { class PropertyMap; } +namespace oox { namespace core { class FilterBase; } } + +namespace oox { +namespace vml { + +// ============================================================================ + +typedef ::std::pair< sal_Int32, sal_Int32 > Int32Pair; +typedef ::std::pair< double, double > DoublePair; + +// ============================================================================ + +class ConversionHelper +{ +public: + /** Returns two values contained in rValue separated by cSep. + */ + static bool separatePair( + ::rtl::OUString& orValue1, ::rtl::OUString& orValue2, + const ::rtl::OUString& rValue, sal_Unicode cSep ); + + /** Returns the boolean value from the passed string of a VML attribute. + Supported values: 'f', 't', 'false', 'true'. False for anything else. + */ + static bool decodeBool( const ::rtl::OUString& rValue ); + + /** Converts the passed VML percentage measure string to a normalized + floating-point value. + + @param rValue The VML percentage value. This is a floating-point value + with optional following '%' sign. If the '%' sign is missing, the + floating point value will be returned unmodified. If the '%' sign + is present, the value will be divided by 100. + */ + static double decodePercent( + const ::rtl::OUString& rValue, + double fDefValue ); + + /** Converts the passed VML measure string to EMU (English Metric Units). + + @param rFilter The core filter object needed to perform pixel + conversion according to the current output device. + + @param rValue The VML measure value. This is a floating-point value + with optional measure string following the value. + + @param nRefValue Reference value needed for percentage measure. + + @param bPixelX Set to true if the value is oriented horizontally (e.g. + X coordinates, widths). Set to false if the value is oriented + vertically (e.g. Y coordinates, heights). This is needed because + output devices may specify different width and height for a pixel. + + @param bDefaultAsPixel Set to true if omitted measure unit means + pixel. Set to false if omitted measure unit means EMU. + */ + static sal_Int32 decodeMeasureToEmu( + const ::oox::core::FilterBase& rFilter, + const ::rtl::OUString& rValue, + sal_Int32 nRefValue, + bool bPixelX, + bool bDefaultAsPixel ); + + /** Converts the passed VML measure string to 1/100 mm. + + @param rFilter See above. + @param rValue See above. + @param nRefValue See above. + @param bPixelX See above. + @param bDefaultAsPixel See above. + */ + static sal_Int32 decodeMeasureToHmm( + const ::oox::core::FilterBase& rFilter, + const ::rtl::OUString& rValue, + sal_Int32 nRefValue, + bool bPixelX, + bool bDefaultAsPixel ); + +private: + ConversionHelper(); + ~ConversionHelper(); +}; + +// ============================================================================ + +/** The stroke arrow model structure contains all properties for an line end arrow. */ +struct StrokeArrowModel +{ + OptValue< sal_Int32 > moArrowType; + OptValue< sal_Int32 > moArrowWidth; + OptValue< sal_Int32 > moArrowLength; + + void assignUsed( const StrokeArrowModel& rSource ); +}; + +// ============================================================================ + +/** The stroke model structure contains all shape border properties. */ +struct StrokeModel +{ + OptValue< bool > moStroked; /// Shape border line on/off. + StrokeArrowModel maStartArrow; /// Start line arrow style. + StrokeArrowModel maEndArrow; /// End line arrow style. + OptValue< ::rtl::OUString > moColor; /// Solid line color. + OptValue< double > moOpacity; /// Solid line color opacity. + OptValue< ::rtl::OUString > moWeight; /// Line width. + OptValue< ::rtl::OUString > moDashStyle; /// Line dash (predefined or manually). + OptValue< sal_Int32 > moLineStyle; /// Line style (single, double, ...). + OptValue< sal_Int32 > moEndCap; /// Type of line end cap. + OptValue< sal_Int32 > moJoinStyle; /// Type of line join. + + void assignUsed( const StrokeModel& rSource ); + + /** Writes the properties to the passed property map. */ + void pushToPropMap( + PropertyMap& rPropMap, + const ::oox::core::FilterBase& rFilter ) const; +}; + +// ============================================================================ + +/** The fill model structure contains all shape fill properties. */ +struct FillModel +{ + OptValue< bool > moFilled; /// Shape fill on/off. + OptValue< ::rtl::OUString > moColor; /// Solid fill color. + OptValue< double > moOpacity; /// Solid fill color opacity. + OptValue< ::rtl::OUString > moColor2; /// End color of gradient. + OptValue< double > moOpacity2; /// End color opycity of gradient. + OptValue< sal_Int32 > moType; /// Fill type. + OptValue< sal_Int32 > moAngle; /// Gradient rotation angle. + OptValue< double > moFocus; /// Linear gradient focus of second color. + OptValue< DoublePair > moFocusPos; /// Rectanguar gradient focus position of second color. + OptValue< DoublePair > moFocusSize; /// Rectanguar gradient focus size of second color. + OptValue< bool > moRotate; /// True = rotate gradient/bitmap with shape. + + void assignUsed( const FillModel& rSource ); + + /** Writes the properties to the passed property map. */ + void pushToPropMap( + PropertyMap& rPropMap, + const ::oox::core::FilterBase& rFilter ) const; +}; + +// ============================================================================ + +} // namespace vml +} // namespace oox + +#endif + diff --git a/oox/inc/oox/vml/vmlshape.hxx b/oox/inc/oox/vml/vmlshape.hxx index f4719f4c1d97..323e643cee50 100644 --- a/oox/inc/oox/vml/vmlshape.hxx +++ b/oox/inc/oox/vml/vmlshape.hxx @@ -34,7 +34,7 @@ #include #include #include -#include "oox/helper/helper.hxx" +#include "oox/vml/vmlformatting.hxx" namespace com { namespace sun { namespace star { namespace awt { struct Rectangle; } @@ -56,12 +56,10 @@ struct ShapeTypeModel { ::rtl::OUString maShapeId; /// Unique identifier of the shape. ::rtl::OUString maName; /// Name of the shape, if present. - OptValue< sal_Int32 > monShapeType; /// Builtin shape type identifier. + OptValue< sal_Int32 > moShapeType; /// Builtin shape type identifier. - OptValue< sal_Int32 > monCoordLeft; /// Left position of coordinate system for children scaling. - OptValue< sal_Int32 > monCoordTop; /// Top position of coordinate system for children scaling. - OptValue< sal_Int32 > monCoordWidth; /// Width of coordinate system for children scaling. - OptValue< sal_Int32 > monCoordHeight; /// Height of coordinate system for children scaling. + OptValue< Int32Pair > moCoordPos; /// Top-left position of coordinate system for children scaling. + OptValue< Int32Pair > moCoordSize; /// Size of coordinate system for children scaling. ::rtl::OUString maPosition; /// Position type of the shape. ::rtl::OUString maLeft; /// X position of the shape bounding box (number with unit). ::rtl::OUString maTop; /// Y position of the shape bounding box (number with unit). @@ -70,11 +68,8 @@ struct ShapeTypeModel ::rtl::OUString maMarginLeft; /// X position of the shape bounding box to shape anchor (number with unit). ::rtl::OUString maMarginTop; /// Y position of the shape bounding box to shape anchor (number with unit). - OptValue< bool > mobStroked; /// True or missing = solid border line. - OptValue< ::rtl::OUString > moStrokeColor; /// Solid border color. - - OptValue< bool > mobFilled; /// True or missing = path is filled. - OptValue< ::rtl::OUString > moFillColor; /// Solid fill color. + StrokeModel maStrokeModel; /// Border line formatting. + FillModel maFillModel; /// Shape fill formatting. OptValue< ::rtl::OUString > moGraphicPath; /// Path to a graphic for this shape. OptValue< ::rtl::OUString > moGraphicTitle; /// Title of the graphic. @@ -131,7 +126,10 @@ struct ShapeClientData ::rtl::OUString maLinkedCell; /// Link to value cell associated to the control. ::rtl::OUString maSourceRange; /// Link to cell range used as data source for the control. sal_Int32 mnObjType; /// Type of the shape. + sal_Int32 mnCol; /// Column index for spreadsheet cell note. + sal_Int32 mnRow; /// Row index for spreadsheet cell note. bool mbPrintObject; /// True = print the object. + bool mbVisible; /// True = cell note is visible. explicit ShapeClientData(); }; @@ -179,6 +177,11 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor = 0 ) const; + /** Converts position and formatting into the passed existing XShape. */ + void convertFormatting( + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, + const ShapeParentAnchor* pParentAnchor = 0 ) const; + protected: explicit ShapeBase( const Drawing& rDrawing ); @@ -188,6 +191,11 @@ protected: const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, const ::com::sun::star::awt::Rectangle& rShapeRect ) const = 0; + /** Calculates the final shape rectangle according to the passed anchor, + if present, otherwise according to the own anchor settings. */ + ::com::sun::star::awt::Rectangle calcShapeRectangle( + const ShapeParentAnchor* pParentAnchor ) const; + /** Converts common shape properties such as formatting attributes. */ void convertShapeProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape ) const; diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx index d8c9b575a6ad..caa8a1a59c6d 100644 --- a/oox/inc/oox/vml/vmlshapecontainer.hxx +++ b/oox/inc/oox/vml/vmlshapecontainer.hxx @@ -73,6 +73,7 @@ public: /** Returns true, if this contaikner does not contain any shapes. */ inline bool empty() const { return maShapes.empty(); } + /** Returns the shape template with the passed identifier. @param bDeep True = searches in all group shapes too. */ const ShapeType* getShapeTypeById( const ::rtl::OUString& rShapeId, bool bDeep ) const; @@ -80,6 +81,15 @@ public: @param bDeep True = searches in all group shapes too. */ const ShapeBase* getShapeById( const ::rtl::OUString& rShapeId, bool bDeep ) const; + /** Searches for a shape type by using the passed functor that takes a + constant reference of a ShapeType object. */ + template< typename Functor > + const ShapeType* findShapeType( const Functor& rFunctor ) const; + /** Searches for a shape by using the passed functor that takes a constant + reference of a ShapeBase object. */ + template< typename Functor > + const ShapeBase* findShape( const Functor& rFunctor ) const; + /** Returns the first shape in the collection (Word only). */ const ShapeBase* getFirstShape() const; @@ -111,6 +121,18 @@ ShapeT& ShapeContainer::createShape() return *xShape; } +template< typename Functor > +const ShapeType* ShapeContainer::findShapeType( const Functor& rFunctor ) const +{ + return maTypes.findIf( rFunctor ).get(); +} + +template< typename Functor > +const ShapeBase* ShapeContainer::findShape( const Functor& rFunctor ) const +{ + return maShapes.findIf( rFunctor ).get(); +} + // ============================================================================ } // namespace vml diff --git a/oox/inc/oox/vml/vmlshapecontext.hxx b/oox/inc/oox/vml/vmlshapecontext.hxx index 0cc0be1f963a..dbc5e1aa611d 100644 --- a/oox/inc/oox/vml/vmlshapecontext.hxx +++ b/oox/inc/oox/vml/vmlshapecontext.hxx @@ -70,7 +70,7 @@ class ShapeContextBase : public ::oox::core::ContextHandler2 { public: static ::oox::core::ContextHandlerRef - createContext( + createShapeContext( ::oox::core::ContextHandler2Helper& rParent, sal_Int32 nElement, const AttributeList& rAttribs, @@ -94,10 +94,6 @@ public: onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); private: - /** Processes the 'coordorigin' attribute. */ - void setCoordOrigin( const ::rtl::OUString& rCoordOrigin ); - /** Processes the 'coordsize' attribute. */ - void setCoordSize( const ::rtl::OUString& rCoordSize ); /** Processes the 'style' attribute. */ void setStyle( const ::rtl::OUString& rStyle ); diff --git a/oox/inc/oox/xls/biffhelper.hxx b/oox/inc/oox/xls/biffhelper.hxx index 1da2c362170f..d5be59019315 100644 --- a/oox/inc/oox/xls/biffhelper.hxx +++ b/oox/inc/oox/xls/biffhelper.hxx @@ -470,6 +470,7 @@ const sal_uInt16 BIFF_ID_STANDARDWIDTH = 0x0099; const sal_uInt16 BIFF2_ID_STRING = 0x0007; const sal_uInt16 BIFF3_ID_STRING = 0x0207; const sal_uInt16 BIFF_ID_STYLE = 0x0293; +const sal_uInt16 BIFF_ID_STYLEEXT = 0x0892; const sal_uInt16 BIFF_ID_SXEXT = 0x00DC; const sal_uInt16 BIFF_ID_TOPMARGIN = 0x0028; const sal_uInt16 BIFF_ID_TXO = 0x01B6; diff --git a/oox/inc/oox/xls/chartsheetfragment.hxx b/oox/inc/oox/xls/chartsheetfragment.hxx index d1effba29166..3e6f5d9d7a6d 100644 --- a/oox/inc/oox/xls/chartsheetfragment.hxx +++ b/oox/inc/oox/xls/chartsheetfragment.hxx @@ -45,7 +45,7 @@ public: const WorkbookHelper& rHelper, const ::rtl::OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, - sal_Int32 nSheet ); + sal_Int16 nSheet ); protected: // oox.core.ContextHandler2Helper interface ------------------------------- @@ -76,7 +76,7 @@ public: explicit BiffChartsheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, - sal_Int32 nSheet ); + sal_Int16 nSheet ); /** Imports the entire sheet fragment, returns true, if EOF record has been reached. */ virtual bool importFragment(); diff --git a/oox/inc/oox/xls/defnamesbuffer.hxx b/oox/inc/oox/xls/defnamesbuffer.hxx index 88e4f7272d8e..88c83c0491b3 100644 --- a/oox/inc/oox/xls/defnamesbuffer.hxx +++ b/oox/inc/oox/xls/defnamesbuffer.hxx @@ -86,17 +86,12 @@ struct DefinedNameModel class DefinedNameBase : public WorkbookHelper { public: - explicit DefinedNameBase( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ); - - /** Returns true, if this defined name is global in the document. */ - inline bool isGlobalName() const { return maModel.mnSheet < 0; } + explicit DefinedNameBase( const WorkbookHelper& rHelper ); /** Returns the original name as imported from or exported to the file. */ inline const ::rtl::OUString& getModelName() const { return maModel.maName; } /** Returns the name as used in the Calc document. */ inline const ::rtl::OUString& getCalcName() const { return maCalcName; } - /** Returns the 0-based sheet index for local names, or -1 for global names. */ - inline sal_Int32 getSheetIndex() const { return maModel.mnSheet; } /** Returns the original name as imported from or exported to the file. */ const ::rtl::OUString& getUpcaseModelName() const; @@ -105,21 +100,19 @@ public: protected: /** Imports the OOX formula string, using the passed formula context. */ - void importOoxFormula( FormulaContext& rContext ); + void importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet ); /** Imports the OOBIN formula, using the passed formula context. */ - void importOobFormula( FormulaContext& rContext, RecordInputStream& rStrm ); + void importOobFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, RecordInputStream& rStrm ); /** Imports the BIFF formula, using the passed formula context. */ - void importBiffFormula( FormulaContext& rContext, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ); + void importBiffFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ); /** Tries to convert the passed token sequence to a SingleReference or ComplexReference. */ - void setReference( const ApiTokenSequence& rTokens ); + void extractReference( const ApiTokenSequence& rTokens ); protected: DefinedNameModel maModel; /// Model data for this defined name. mutable ::rtl::OUString maUpModelName; /// Model name converted to uppercase ASCII. ::rtl::OUString maCalcName; /// Final name used in the Calc document. - -private: ::com::sun::star::uno::Any maRefAny; /// Single cell/range reference. }; @@ -128,7 +121,7 @@ private: class DefinedName : public DefinedNameBase { public: - explicit DefinedName( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ); + explicit DefinedName( const WorkbookHelper& rHelper ); /** Sets the attributes for this defined name from the passed attribute set. */ void importDefinedName( const AttributeList& rAttribs ); @@ -137,7 +130,7 @@ public: /** Imports the defined name from a DEFINEDNAME record in the passed stream. */ void importDefinedName( RecordInputStream& rStrm ); /** Imports the defined name from a DEFINEDNAME record in the passed BIFF stream. */ - void importDefinedName( BiffInputStream& rStrm ); + void importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet ); /** Creates a defined name in the Calc document. */ void createNameObject(); @@ -148,9 +141,13 @@ public: inline bool isBuiltinName() const { return mcBuiltinId != OOX_DEFNAME_UNKNOWN; } /** Returns true, if this defined name is a macro function call. */ inline bool isMacroFunction() const { return maModel.mbMacro && maModel.mbFunction; } + /** Returns true, if this defined name is global in the document. */ + inline bool isGlobalName() const { return mnCalcSheet < 0; } /** Returns the token index used in API token arrays (com.sun.star.sheet.FormulaToken). */ inline sal_Int32 getTokenIndex() const { return mnTokenIndex; } + /** Returns the 0-based sheet index for local names, or -1 for global names. */ + inline sal_Int16 getLocalCalcSheet() const { return mnCalcSheet; } /** Tries to resolve the defined name to an absolute cell range. */ bool getAbsoluteRange( ::com::sun::star::table::CellRangeAddress& orRange ) const; @@ -167,6 +164,7 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange > mxNamedRange; /// XNamedRange interface of the defined name. sal_Int32 mnTokenIndex; /// Name index used in API token array. + sal_Int16 mnCalcSheet; /// Calc sheet index for sheet-local names. sal_Unicode mcBuiltinId; /// Identifier for built-in defined names. StreamDataSeqPtr mxFormula; /// Formula data for OOBIN import. BiffStreamPosPtr mxBiffStrm; /// Cached BIFF stream for formula import. @@ -182,9 +180,9 @@ class DefinedNamesBuffer : public WorkbookHelper public: explicit DefinedNamesBuffer( const WorkbookHelper& rHelper ); - /** Sets the current sheet index for files with local defined names, e.g. - BIFF4 workspaces. All created names initially will contain this index. */ - void setLocalSheetIndex( sal_Int32 nLocalSheet ); + /** Sets the sheet index for local names (BIFF2-BIFF4 only). */ + void setLocalCalcSheet( sal_Int16 nCalcSheet ); + /** Imports a defined name from the passed attribute set. */ DefinedNameRef importDefinedName( const AttributeList& rAttribs ); /** Imports a defined name from a DEFINEDNAME record in the passed stream. */ @@ -203,7 +201,7 @@ public: @param nSheet The sheet index for local names or -1 for global names. If no local name is found, tries to find a matching global name. @return Reference to the defined name or empty reference. */ - DefinedNameRef getByModelName( const ::rtl::OUString& rModelName, sal_Int32 nSheet = -1 ) const; + DefinedNameRef getByModelName( const ::rtl::OUString& rModelName, sal_Int16 nCalcSheet = -1 ) const; private: DefinedNameRef createDefinedName(); @@ -213,8 +211,8 @@ private: typedef RefMap< sal_Int32, DefinedName > DefNameMap; DefNameVector maDefNames; /// List of all defined names in insertion order. - DefNameMap maDefNameMap; /// Maps all defined names by API token index. */ - sal_Int32 mnLocalSheet; /// Current sheet index for import of BIFF sheet-local names. + DefNameMap maDefNameMap; /// Maps all defined names by API token index. + sal_Int16 mnCalcSheet; /// Current sheet index for BIFF2-BIFF4 names (always sheet-local). }; // ============================================================================ diff --git a/oox/inc/oox/xls/drawingfragment.hxx b/oox/inc/oox/xls/drawingfragment.hxx index f1fee71e5c1c..67009f436360 100644 --- a/oox/inc/oox/xls/drawingfragment.hxx +++ b/oox/inc/oox/xls/drawingfragment.hxx @@ -170,6 +170,12 @@ class VmlDrawing : public ::oox::vml::Drawing, public WorksheetHelper public: explicit VmlDrawing( const WorksheetHelper& rHelper ); + /** Returns the drawing shape for a cell note at the specified position. */ + const ::oox::vml::ShapeBase* getNoteShape( const ::com::sun::star::table::CellAddress& rPos ) const; + + /** Filters cell note shapes. */ + virtual bool isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const; + /** Calculates the shape rectangle from a cell anchor string. */ virtual bool convertShapeClientAnchor( ::com::sun::star::awt::Rectangle& orShapeRect, diff --git a/oox/inc/oox/xls/excelfilter.hxx b/oox/inc/oox/xls/excelfilter.hxx index ed6c32cdc463..28059fe30ce7 100644 --- a/oox/inc/oox/xls/excelfilter.hxx +++ b/oox/inc/oox/xls/excelfilter.hxx @@ -41,7 +41,23 @@ namespace xls { class WorkbookHelper; -class ExcelFilter : public ::oox::core::XmlFilterBase +class ExcelFilterBase +{ +protected: + explicit ExcelFilterBase(); + virtual ~ExcelFilterBase(); + + void setWorkbookHelper( WorkbookHelper& rHelper ); + WorkbookHelper& getWorkbookHelper() const; + void clearWorkbookHelper(); + +private: + WorkbookHelper* mpHelper; /// Nonowning pointer to helper base. +}; + +// ============================================================================ + +class ExcelFilter : public ::oox::core::XmlFilterBase, public ExcelFilterBase { public: explicit ExcelFilter( @@ -51,23 +67,21 @@ public: virtual bool importDocument() throw(); virtual bool exportDocument() throw(); - virtual const ::oox::drawingml::Theme* getCurrentTheme() const; - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; + virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const; + virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const; + virtual const ::oox::drawingml::Theme* getCurrentTheme() const; virtual ::oox::vml::Drawing* getVmlDrawing(); virtual const ::oox::drawingml::table::TableStyleListPtr getTableStyles(); virtual ::oox::drawingml::chart::ChartConverter& getChartConverter(); private: virtual ::rtl::OUString implGetImplementationName() const; - -private: - WorkbookHelper* mpHelper; /// Nonowning pointer to helper base. }; // ============================================================================ -class ExcelBiffFilter : public ::oox::core::BinaryFilterBase +class ExcelBiffFilter : public ::oox::core::BinaryFilterBase, public ExcelFilterBase { public: explicit ExcelBiffFilter( @@ -77,6 +91,8 @@ public: virtual bool importDocument() throw(); virtual bool exportDocument() throw(); + virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const; + private: virtual ::rtl::OUString implGetImplementationName() const; }; diff --git a/oox/inc/oox/xls/excelhandlers.hxx b/oox/inc/oox/xls/excelhandlers.hxx index 3b34a14963ec..76d0e599e502 100644 --- a/oox/inc/oox/xls/excelhandlers.hxx +++ b/oox/inc/oox/xls/excelhandlers.hxx @@ -74,7 +74,7 @@ public: ParentType& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); template< typename ParentType > explicit OoxWorksheetContextBase( ParentType& rParent ); @@ -84,7 +84,7 @@ public: template< typename ParentType > OoxWorksheetContextBase::OoxWorksheetContextBase( ParentType& rParent, - ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : ::oox::core::ContextHandler2( rParent ), WorksheetHelperRoot( rParent, xProgressBar, eSheetType, nSheet ) { @@ -125,7 +125,7 @@ public: const ::rtl::OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); explicit OoxWorksheetFragmentBase( const WorksheetHelper& rHelper, @@ -236,7 +236,7 @@ protected: const ParentType& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); template< typename ParentType > explicit BiffWorksheetContextBase( const ParentType& rParent ); @@ -246,7 +246,7 @@ protected: template< typename ParentType > BiffWorksheetContextBase::BiffWorksheetContextBase( const ParentType& rParent, - ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : BiffContextHandler( rParent ), WorksheetHelperRoot( rParent, xProgressBar, eSheetType, nSheet ) { @@ -346,7 +346,7 @@ protected: const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); }; // ============================================================================ @@ -359,7 +359,7 @@ public: explicit BiffSkipWorksheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, - sal_Int32 nSheet ); + sal_Int16 nSheet ); virtual bool importFragment(); }; diff --git a/oox/inc/oox/xls/externallinkbuffer.hxx b/oox/inc/oox/xls/externallinkbuffer.hxx index a50170544813..a4ede4403fe3 100644 --- a/oox/inc/oox/xls/externallinkbuffer.hxx +++ b/oox/inc/oox/xls/externallinkbuffer.hxx @@ -70,9 +70,7 @@ class ExternalLink; class ExternalName : public DefinedNameBase { public: - explicit ExternalName( - const ExternalLink& rParentLink, - sal_Int32 nLocalSheet ); + explicit ExternalName( const ExternalLink& rParentLink ); /** Appends the passed value to the result set. */ template< typename Type > @@ -109,8 +107,10 @@ public: /** Returns true, if the name refers to an OLE object. */ inline bool isOleObject() const { return maExtNameModel.mbOleObj; } +#if 0 /** Returns the sheet cache index if this is a sheet-local external name. */ sal_Int32 getSheetCacheIndex() const; +#endif /** Returns the DDE item info needed by the XML formula parser. */ bool getDdeItemInfo( @@ -123,6 +123,8 @@ public: ::rtl::OUString& orDdeItem ); private: + /** Tries to convert the passed token sequence to an ExternalReference. */ + void extractExternalReference( const ApiTokenSequence& rTokens ); /** Sets the size of the result matrix. */ void setResultSize( sal_Int32 nColumns, sal_Int32 nRows ); @@ -265,14 +267,20 @@ public: /** Returns the type of the external library if this is a library link. */ FunctionLibraryType getFuncLibraryType() const; - /** Returns the internal sheet index or external sheet cache index for the passed sheet. */ - sal_Int32 getSheetIndex( sal_Int32 nTabId = 0 ) const; - /** Returns the internal sheet range or range of external sheet caches for the passed sheet range (BIFF only). */ - void getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const; + /** Returns the internal Calc sheet index or for the passed sheet. */ + sal_Int16 getCalcSheetIndex( sal_Int32 nTabId = 0 ) const; + + /** Returns the token index of the external document. */ + sal_Int32 getDocumentLinkIndex() const; + /** Returns the external sheet cache index or for the passed sheet. */ + sal_Int32 getSheetCacheIndex( sal_Int32 nTabId = 0 ) const; /** Returns the sheet cache of the external sheet with the passed index. */ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache > - getExternalSheetCache( sal_Int32 nTabId ); + getSheetCache( sal_Int32 nTabId ) const; + + /** Returns the internal sheet range or range of external sheet caches for the passed sheet range (BIFF only). */ + void getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const; /** Returns the external name with the passed zero-based index. */ ExternalNameRef getNameByIndex( sal_Int32 nIndex ) const; @@ -289,7 +297,8 @@ private: ExternalNameRef createExternalName(); private: - typedef ::std::vector< sal_Int32 > IndexVector; + typedef ::std::vector< sal_Int16 > Int16Vector; + typedef ::std::vector< sal_Int32 > Int32Vector; typedef RefVector< ExternalName > ExternalNameVector; ExternalLinkType meLinkType; /// Type of this link object. @@ -299,7 +308,8 @@ private: ::rtl::OUString maTargetUrl; /// Target link, DDE topic, OLE target. ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalDocLink > mxDocLink; /// Interface for an external document. - IndexVector maIndexes; /// Internal sheet indexes or external sheet cache indexes. + Int16Vector maCalcSheets; /// Internal sheet indexes. + Int32Vector maSheetCaches; /// External sheet cache indexes. ExternalNameVector maExtNames; /// Defined names in external document. }; diff --git a/oox/inc/oox/xls/richstring.hxx b/oox/inc/oox/xls/richstring.hxx index 23a0801531ae..47a55e92c350 100644 --- a/oox/inc/oox/xls/richstring.hxx +++ b/oox/inc/oox/xls/richstring.hxx @@ -71,6 +71,9 @@ public: /** Final processing after import of all strings. */ void finalizeImport(); + /** Returns the text data of this portion. */ + inline const ::rtl::OUString& getText() const { return maText; } + /** Converts the portion and appends it to the passed XText. */ void convert( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >& rxText, @@ -254,6 +257,9 @@ public: /** Final processing after import of all strings. */ void finalizeImport(); + /** Returns the plain text concatenated from all string portions. */ + ::rtl::OUString getPlainText() const; + /** Converts the string and writes it into the passed XText. */ void convert( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >& rxText, diff --git a/oox/inc/oox/xls/stylesbuffer.hxx b/oox/inc/oox/xls/stylesbuffer.hxx index 13890aec7223..2b5b5bf3e7f7 100644 --- a/oox/inc/oox/xls/stylesbuffer.hxx +++ b/oox/inc/oox/xls/stylesbuffer.hxx @@ -38,6 +38,7 @@ #include #include #include "oox/helper/containerhelper.hxx" +#include "oox/drawingml/color.hxx" #include "oox/xls/numberformatsbuffer.hxx" namespace com { namespace sun { namespace star { @@ -46,8 +47,6 @@ namespace com { namespace sun { namespace star { namespace oox { class PropertySet; } -#define OOX_XLS_USE_DEFAULT_STYLE 0 - namespace oox { namespace xls { @@ -67,9 +66,6 @@ const sal_Int32 OOX_COLOR_FONTAUTO = 0x7FFF; /// Font auto color (sys // ---------------------------------------------------------------------------- -const sal_Int32 API_RGB_TRANSPARENT = -1; /// Transparent color for API calls. -const sal_Int32 API_RGB_BLACK = 0; /// Black color for API calls. - const sal_Int16 API_LINE_NONE = 0; const sal_Int16 API_LINE_HAIR = 2; const sal_Int16 API_LINE_THIN = 35; @@ -85,11 +81,9 @@ const sal_Int8 API_ESCAPEHEIGHT_DEFAULT = 58; /// Relative character h // ============================================================================ -class Color +class Color : public ::oox::drawingml::Color { public: - explicit Color(); - /** Sets the color to automatic. */ void setAuto(); /** Sets the color to the passed RGB value. */ @@ -115,23 +109,7 @@ public: void importColorRgb( BiffInputStream& rStrm ); /** Returns true, if the color is set to automatic. */ - bool isAuto() const; - /** Returns the RGB value of the color, or nAuto for automatic colors. */ - sal_Int32 getColor( const WorkbookHelper& rHelper, sal_Int32 nAuto = API_RGB_TRANSPARENT ) const; - -private: - enum ColorMode - { - COLOR_AUTO, /// Automatic color (dependent on context). - COLOR_RGB, /// Hexadecimal RGB color. - COLOR_THEME, /// Indexed theme color. - COLOR_INDEXED, /// Indexed palette color. - COLOR_FINAL /// Finalized RGB color (resolved theme, applied tint). - }; - - mutable ColorMode meMode; /// Current color mode. - mutable sal_Int32 mnValue; /// RGB value, palette index, scheme index. - double mfTint; /// Color tint (darken/lighten). + inline bool isAuto() const { return isPlaceHolder(); } }; // ---------------------------------------------------------------------------- @@ -851,8 +829,6 @@ struct CellStyleModel inline bool isBuiltin() const { return mbBuiltin && (mnBuiltinId >= 0); } /** Returns true, if this style represents the default document cell style. */ bool isDefaultStyle() const; - /** Returns the style name used in the UI. */ - ::rtl::OUString createStyleName() const; }; // ============================================================================ @@ -868,18 +844,29 @@ public: void importCellStyle( RecordInputStream& rStrm ); /** Imports style settings from a STYLE record. */ void importStyle( BiffInputStream& rStrm ); + /** Sets the final style name to be used in the document. */ + inline void setFinalStyleName( const ::rtl::OUString& rStyleName ) { maFinalName = rStyleName; } + /** Returns true, if this style is a builtin style. */ + inline bool isBuiltin() const { return maModel.isBuiltin(); } /** Returns true, if this style represents the default document cell style. */ inline bool isDefaultStyle() const { return maModel.isDefaultStyle(); } /** Returns the XF identifier for this cell style. */ inline sal_Int32 getXfId() const { return maModel.mnXfId; } + /** Calculates a readable style name according to the settings. */ + ::rtl::OUString calcInitialStyleName() const; + /** Returns the final style name used in the document. */ + inline const ::rtl::OUString& getFinalStyleName() const { return maFinalName; } - /** Creates the style sheet described by the style XF with the passed identifier. */ - const ::rtl::OUString& createCellStyle( sal_Int32 nXfId, bool bSkipDefaultBuiltin = false ); + /** Creates the style sheet in the document described by this cell style object. */ + void createCellStyle(); + /** Creates the cell style, if it is user-defined or modified built-in. */ + void finalizeImport(); private: CellStyleModel maModel; - ::rtl::OUString maCalcName; /// Final style name used in API. + ::rtl::OUString maFinalName; /// Final style name used in API. + bool mbCreated; /// True = style sheet created. }; typedef ::boost::shared_ptr< CellStyle > CellStyleRef; @@ -964,11 +951,8 @@ public: const ::rtl::OUString& createCellStyle( sal_Int32 nXfId ) const; /** Creates the style sheet described by the DXF with the passed identifier. */ const ::rtl::OUString& createDxfStyle( sal_Int32 nDxfId ) const; -#if OOX_XLS_USE_DEFAULT_STYLE -#else /** Returns the default style sheet for unused cells. */ const ::rtl::OUString& getDefaultStyleName() const; -#endif /** Writes the font attributes of the specified font data to the passed property map. */ void writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const; @@ -992,12 +976,13 @@ private: void insertCellStyle( CellStyleRef xCellStyle ); private: - typedef RefVector< Font > FontVec; - typedef RefVector< Border > BorderVec; - typedef RefVector< Fill > FillVec; - typedef RefVector< Xf > XfVec; - typedef RefVector< Dxf > DxfVec; - typedef RefMap< sal_Int32, CellStyle > CellStyleMap; + typedef RefVector< Font > FontVec; + typedef RefVector< Border > BorderVec; + typedef RefVector< Fill > FillVec; + typedef RefVector< Xf > XfVec; + typedef RefVector< Dxf > DxfVec; + typedef RefMap< sal_Int32, CellStyle > CellStyleIdMap; + typedef RefMap< ::rtl::OUString, CellStyle > CellStyleNameMap; ColorPalette maPalette; /// Color palette. FontVec maFonts; /// List of font objects. @@ -1007,7 +992,8 @@ private: XfVec maCellXfs; /// List of cell formats. XfVec maStyleXfs; /// List of cell styles. DxfVec maDxfs; /// List of differential cell styles. - CellStyleMap maCellStyles; /// List of named cell styles. + CellStyleIdMap maCellStylesById; /// List of named cell styles, mapped by XF identifier. + CellStyleNameMap maCellStylesByName; /// List of named cell styles, mapped by name. ::rtl::OUString maDefStyleName; /// API name of default cell style. sal_Int32 mnDefStyleXf; /// Style XF index of default cell style. }; diff --git a/oox/inc/oox/xls/themebuffer.hxx b/oox/inc/oox/xls/themebuffer.hxx index ca0a80d983fe..b1ee4b4ebc66 100644 --- a/oox/inc/oox/xls/themebuffer.hxx +++ b/oox/inc/oox/xls/themebuffer.hxx @@ -49,8 +49,6 @@ public: /** Returns the theme color with the specified token identifier. */ sal_Int32 getColorByToken( sal_Int32 nToken ) const; - /** Returns the theme color with the specified index. */ - sal_Int32 getColorByIndex( sal_Int32 nIndex ) const; /** Returns the default font data for the current file type. */ inline const FontModel& getDefaultFontModel() const { return *mxDefFontModel; } diff --git a/oox/inc/oox/xls/viewsettings.hxx b/oox/inc/oox/xls/viewsettings.hxx index fceb1bc1a63c..f18d0371c6c2 100644 --- a/oox/inc/oox/xls/viewsettings.hxx +++ b/oox/inc/oox/xls/viewsettings.hxx @@ -92,6 +92,8 @@ struct SheetViewModel sal_Int32 getNormalZoom() const; /** Returns the zoom in pagebreak preview (returns default, if current value is 0). */ sal_Int32 getPageBreakZoom() const; + /** Returns the grid color as RGB value. */ + sal_Int32 getGridColor( const ::oox::core::FilterBase& rFilter ) const; /** Returns the selection data, if available, otherwise 0. */ const PaneSelectionModel* getPaneSelection( sal_Int32 nPaneId ) const; @@ -186,23 +188,23 @@ public: void importWindow1( BiffInputStream& rStrm ); /** Stores converted view settings for a specific worksheet. */ - void setSheetViewSettings( sal_Int32 nSheet, + void setSheetViewSettings( sal_Int16 nSheet, const SheetViewModelRef& rxSheetView, const ::com::sun::star::uno::Any& rProperties ); /** Converts all imported document view settings. */ void finalizeImport(); - /** Returns the index of the active sheet. */ - sal_Int32 getActiveSheetIndex() const; + /** Returns the Calc index of the active sheet. */ + sal_Int16 getActiveCalcSheet() const; private: WorkbookViewModel& createWorkbookView(); private: typedef RefVector< WorkbookViewModel > WorkbookViewModelVec; - typedef RefMap< sal_Int32, SheetViewModel > SheetViewModelMap; - typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > SheetPropertiesMap; + typedef RefMap< sal_Int16, SheetViewModel > SheetViewModelMap; + typedef ::std::map< sal_Int16, ::com::sun::star::uno::Any > SheetPropertiesMap; WorkbookViewModelVec maBookViews; /// Workbook view models. SheetViewModelMap maSheetViews; /// Active view model for each sheet. diff --git a/oox/inc/oox/xls/workbookfragment.hxx b/oox/inc/oox/xls/workbookfragment.hxx index a691fcf5cf57..d3925f9113d8 100644 --- a/oox/inc/oox/xls/workbookfragment.hxx +++ b/oox/inc/oox/xls/workbookfragment.hxx @@ -94,7 +94,7 @@ private: /** Imports a sheet fragment with passed type from current stream position. */ bool importSheetFragment( ISegmentProgressBar& rProgressBar, - BiffFragmentType eFragment, sal_Int32 nSheet ); + BiffFragmentType eFragment, sal_Int16 nCalcSheet ); }; // ============================================================================ diff --git a/oox/inc/oox/xls/workbookhelper.hxx b/oox/inc/oox/xls/workbookhelper.hxx index 207b69184c1d..1c4210deabf6 100644 --- a/oox/inc/oox/xls/workbookhelper.hxx +++ b/oox/inc/oox/xls/workbookhelper.hxx @@ -253,7 +253,7 @@ public: /** Returns a reference to the specified spreadsheet in the document model. */ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > - getSheetFromDoc( sal_Int32 nSheet ) const; + getSheetFromDoc( sal_Int16 nSheet ) const; /** Returns a reference to the specified spreadsheet in the document model. */ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > getSheetFromDoc( const ::rtl::OUString& rSheet ) const; @@ -281,12 +281,11 @@ public: createNamedRangeObject( ::rtl::OUString& orName, sal_Int32 nNameFlags = 0 ) const; - /** Creates a com.sun.star.style.Style object and returns its final name. */ + /** Creates and returns a com.sun.star.style.Style object for cells or pages. */ ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > createStyleObject( ::rtl::OUString& orStyleName, - bool bPageStyle, - bool bRenameOldExisting = false ) const; + bool bPageStyle ) const; // buffers ---------------------------------------------------------------- @@ -361,7 +360,7 @@ public: /** Enables workbook file mode, used for BIFF4 workspace files. */ void setIsWorkbookFile(); /** Recreates global buffers that are used per sheet in specific BIFF versions. */ - void createBuffersPerSheet(); + void createBuffersPerSheet( sal_Int16 nSheet ); /** Returns the codec helper that stores the encoder/decoder object. */ BiffCodecHelper& getCodecHelper() const; diff --git a/oox/inc/oox/xls/worksheetbuffer.hxx b/oox/inc/oox/xls/worksheetbuffer.hxx index a4ebdedef7e2..327ff5c5638d 100644 --- a/oox/inc/oox/xls/worksheetbuffer.hxx +++ b/oox/inc/oox/xls/worksheetbuffer.hxx @@ -31,9 +31,8 @@ #ifndef OOX_XLS_WORKSHEETBUFFER_HXX #define OOX_XLS_WORKSHEETBUFFER_HXX -#include -#include #include +#include "oox/helper/containerhelper.hxx" #include "oox/xls/workbookhelper.hxx" namespace com { namespace sun { namespace star { @@ -50,7 +49,6 @@ struct SheetInfoModel { ::rtl::OUString maRelId; /// Relation identifier for the sheet substream. ::rtl::OUString maName; /// Original name of the sheet. - ::rtl::OUString maFinalName; /// Final (converted) name of the sheet. sal_Int32 mnSheetId; /// Sheet identifier. sal_Int32 mnState; /// Visibility state. @@ -70,6 +68,9 @@ class WorksheetBuffer : public WorkbookHelper public: explicit WorksheetBuffer( const WorkbookHelper& rHelper ); + /** Returns the base file name without path and file extension. */ + static ::rtl::OUString getBaseFileName( const ::rtl::OUString& rUrl ); + /** Initializes the buffer for single sheet files (BIFF2-BIFF4). */ void initializeSingleSheet(); @@ -79,34 +80,49 @@ public: void importSheet( RecordInputStream& rStrm ); /** Imports the SHEET record from the passed BIFF stream. */ void importSheet( BiffInputStream& rStrm ); - /** Inserts a new empty sheet into the document. Looks for an unused name. - @return Internal index of the new sheet. */ + @return Index of the new sheet in the Calc document. */ sal_Int16 insertEmptySheet( const ::rtl::OUString& rPreferredName, bool bVisible ); /** Returns the number of original sheets contained in the workbook. */ - sal_Int32 getSheetCount() const; - /** Returns the OOX relation identifier of the specified sheet. */ - ::rtl::OUString getSheetRelId( sal_Int32 nSheet ) const; - /** Returns the finalized name of the specified sheet. */ - ::rtl::OUString getCalcSheetName( sal_Int32 nSheet ) const; - /** Returns the finalized name of the sheet with the passed original name. */ - ::rtl::OUString getCalcSheetName( const ::rtl::OUString& rModelName ) const; - /** Returns the index of the sheet with the passed original name. */ - sal_Int32 getCalcSheetIndex( const ::rtl::OUString& rModelName ) const; + sal_Int32 getWorksheetCount() const; + /** Returns the OOX relation identifier of the specified worksheet. */ + ::rtl::OUString getWorksheetRelId( sal_Int32 nWorksheet ) const; + + /** Returns the Calc index of the specified worksheet. */ + sal_Int16 getCalcSheetIndex( sal_Int32 nWorksheet ) const; + /** Returns the finalized name of the specified worksheet. */ + ::rtl::OUString getCalcSheetName( sal_Int32 nWorksheet ) const; + + /** Returns the Calc index of the sheet with the passed original worksheet name. */ + sal_Int16 getCalcSheetIndex( const ::rtl::OUString& rWorksheetName ) const; + /** Returns the finalized name of the sheet with the passed worksheet name. */ + ::rtl::OUString getCalcSheetName( const ::rtl::OUString& rWorksheetName ) const; private: + struct SheetInfo : public SheetInfoModel + { + ::rtl::OUString maCalcName; + ::rtl::OUString maCalcQuotedName; + sal_Int16 mnCalcSheet; + + explicit SheetInfo( const SheetInfoModel& rModel, sal_Int16 nCalcSheet, const ::rtl::OUString& rCalcName ); + }; + typedef ::std::pair< sal_Int16, ::rtl::OUString > IndexNamePair; - const SheetInfoModel* getSheetInfo( sal_Int32 nSheet ) const; - - IndexNamePair insertSheet( const ::rtl::OUString& rPreferredName, sal_Int16 nSheet, bool bVisible ); + /** Creates a new sheet in the Calc document. Does not insert anything in the own lists. */ + IndexNamePair createSheet( const ::rtl::OUString& rPreferredName, sal_Int32 nSheetPos, bool bVisible ); + /** Creates a new sheet in the Calc document and inserts the related SheetInfo. */ void insertSheet( const SheetInfoModel& rModel ); private: - typedef ::std::vector< SheetInfoModel > SheetInfoModelVec; + typedef RefVector< SheetInfo > SheetInfoVector; + SheetInfoVector maSheetInfos; - SheetInfoModelVec maSheetInfos; + struct SheetNameCompare { bool operator()( const ::rtl::OUString& rName1, const ::rtl::OUString& rName2 ) const; }; + typedef RefMap< ::rtl::OUString, SheetInfo, SheetNameCompare > SheetInfoMap; + SheetInfoMap maSheetInfosByName; }; // ============================================================================ diff --git a/oox/inc/oox/xls/worksheetfragment.hxx b/oox/inc/oox/xls/worksheetfragment.hxx index e5721265937f..110851ea9521 100644 --- a/oox/inc/oox/xls/worksheetfragment.hxx +++ b/oox/inc/oox/xls/worksheetfragment.hxx @@ -71,7 +71,7 @@ public: const ::rtl::OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); protected: // oox.core.ContextHandler2Helper interface ------------------------------- @@ -147,7 +147,7 @@ public: const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); virtual ~BiffWorksheetFragment(); /** Imports the entire worksheet fragment, returns true, if EOF record has been reached. */ diff --git a/oox/inc/oox/xls/worksheethelper.hxx b/oox/inc/oox/xls/worksheethelper.hxx index fc097783510b..7bb9b52ff117 100644 --- a/oox/inc/oox/xls/worksheethelper.hxx +++ b/oox/inc/oox/xls/worksheethelper.hxx @@ -175,8 +175,9 @@ struct PageBreakModel /** Stores data about a hyperlink range. */ struct HyperlinkModel : public ::oox::ole::StdHlinkInfo { - ::com::sun::star::table::CellRangeAddress maRange; - ::rtl::OUString maTooltip; + ::com::sun::star::table::CellRangeAddress + maRange; /// The cell area containing the hyperlink. + ::rtl::OUString maTooltip; /// Additional tooltip text. explicit HyperlinkModel(); }; @@ -442,7 +443,7 @@ protected: const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); /** Constructs from another sheet helper, does not create a data object. */ explicit WorksheetHelperRoot( diff --git a/oox/source/core/fasttokenhandler.cxx b/oox/source/core/fasttokenhandler.cxx new file mode 100644 index 000000000000..cb8841b7dc9f --- /dev/null +++ b/oox/source/core/fasttokenhandler.cxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tokenmap.cxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/core/fasttokenhandler.hxx" +#include +#include "oox/token/tokenmap.hxx" + +using ::rtl::OUString; +using ::osl::Mutex; +using ::osl::MutexGuard; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::RuntimeException; + +namespace oox { +namespace core { + +// ============================================================================ + +namespace { + +Mutex& lclGetTokenMutex() +{ + static Mutex aMutex; + return aMutex; +} + +} // namespace + +// ============================================================================ + +FastTokenHandler::FastTokenHandler() : + mrTokenMap( StaticTokenMap::get() ) +{ +} + +FastTokenHandler::~FastTokenHandler() +{ +} + +sal_Int32 FastTokenHandler::getToken( const OUString& rIdentifier ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getTokenFromUnicode( rIdentifier ); +} + +OUString FastTokenHandler::getIdentifier( sal_Int32 nToken ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getUnicodeTokenName( nToken ); +} + +Sequence< sal_Int8 > FastTokenHandler::getUTF8Identifier( sal_Int32 nToken ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getUtf8TokenName( nToken ); +} + +sal_Int32 FastTokenHandler::getTokenFromUTF8( const Sequence< sal_Int8 >& rIdentifier ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getTokenFromUtf8( rIdentifier ); +} + +// ============================================================================ + +} // namespace core +} // namespace oox + diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index 55793859fe2e..d289255bac98 100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -471,7 +471,19 @@ sal_Int32 FilterBase::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) { FilterBaseImpl::SystemPalette::const_iterator aIt = mxImpl->maSystemPalette.find( nToken ); OSL_ENSURE( aIt != mxImpl->maSystemPalette.end(), "FilterBase::getSystemColor - invalid token identifier" ); - return (aIt == mxImpl->maSystemPalette.end()) ? ((nDefaultRgb < 0) ? API_RGB_WHITE : nDefaultRgb) : aIt->second; + return (aIt == mxImpl->maSystemPalette.end()) ? nDefaultRgb : aIt->second; +} + +sal_Int32 FilterBase::getSchemeColor( sal_Int32 /*nToken*/ ) const +{ + OSL_ENSURE( false, "FilterBase::getSchemeColor - scheme colors not implemented" ); + return API_RGB_TRANSPARENT; +} + +sal_Int32 FilterBase::getPaletteColor( sal_Int32 /*nPaletteIdx*/ ) const +{ + OSL_ENSURE( false, "FilterBase::getPaletteColor - palette colors not implemented" ); + return API_RGB_TRANSPARENT; } OUString FilterBase::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk index 51804e1d04c8..84d12776eadd 100644 --- a/oox/source/core/makefile.mk +++ b/oox/source/core/makefile.mk @@ -54,6 +54,7 @@ SLOFILES = \ $(SLO)$/contexthandler.obj \ $(SLO)$/contexthandler2.obj \ $(SLO)$/facreg.obj \ + $(SLO)$/fasttokenhandler.obj \ $(SLO)$/filterbase.obj \ $(SLO)$/filterdetect.obj \ $(SLO)$/fragmenthandler.obj \ diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index 27b3eef0ce60..07652c5c447b 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -32,6 +32,7 @@ #include +#include #include #include #include @@ -52,6 +53,7 @@ #include "oox/core/recordparser.hxx" #include "oox/core/relationshandler.hxx" +using ::rtl::OStringBuffer; using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::com::sun::star::beans::StringPair; @@ -209,8 +211,17 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r InputSource aSource; aSource.aInputStream = xInStrm; aSource.sSystemId = aFragmentPath; - xParser->parseStream( aSource ); - return true; + // own try/catch block for showing parser failure assertion with fragment path + try + { + xParser->parseStream( aSource ); + return true; + } + catch( Exception& ) + { + OSL_ENSURE( false, OStringBuffer( "XmlFilterBase::importFragment - XML parser failed in fragment '" ). + append( OUStringToOString( aFragmentPath, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); + } } catch( Exception& ) { diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx index 6ddb72bd3040..46253e92dd68 100644 --- a/oox/source/drawingml/chart/objectformatter.cxx +++ b/oox/source/drawingml/chart/objectformatter.cxx @@ -892,7 +892,7 @@ void LineFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Sh aLineProps.assignUsed( *mxAutoLine ); if( rxShapeProp.is() ) aLineProps.assignUsed( rxShapeProp->getLineProperties() ); - aLineProps.pushToPropSet( rPropSet, mrLinePropIds, mrData.mrFilter, mrData.maModelObjHelper, getPhColor( nSeriesIdx ) ); + aLineProps.pushToPropSet( rPropSet, mrData.mrFilter, mrData.maModelObjHelper, mrLinePropIds, getPhColor( nSeriesIdx ) ); } // ============================================================================ @@ -920,7 +920,7 @@ void FillFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Sh aFillProps.assignUsed( rxShapeProp->getFillProperties() ); if( pPicOptions ) lclConvertPictureOptions( aFillProps, *pPicOptions ); - aFillProps.pushToPropSet( rPropSet, mrFillPropIds, mrData.mrFilter, mrData.maModelObjHelper, 0, getPhColor( nSeriesIdx ) ); + aFillProps.pushToPropSet( rPropSet, mrData.mrFilter, mrData.maModelObjHelper, mrFillPropIds, 0, getPhColor( nSeriesIdx ) ); } // ============================================================================ diff --git a/oox/source/drawingml/clrschemecontext.cxx b/oox/source/drawingml/clrschemecontext.cxx index 6eedb908c00e..a8fa5d737c63 100644 --- a/oox/source/drawingml/clrschemecontext.cxx +++ b/oox/source/drawingml/clrschemecontext.cxx @@ -30,6 +30,7 @@ #include "oox/drawingml/clrschemecontext.hxx" #include "oox/core/namespaces.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "tokens.hxx" using namespace ::oox::core; diff --git a/oox/source/drawingml/color.cxx b/oox/source/drawingml/color.cxx index c269379b5adc..009be55424f3 100644 --- a/oox/source/drawingml/color.cxx +++ b/oox/source/drawingml/color.cxx @@ -29,11 +29,15 @@ ************************************************************************/ #include "oox/drawingml/color.hxx" -#include "oox/core/namespaces.hxx" -#include "oox/core/xmlfilterbase.hxx" -#include "tokens.hxx" #include #include +#include "tokens.hxx" +#include "oox/helper/containerhelper.hxx" +#include "oox/core/namespaces.hxx" +#include "oox/core/filterbase.hxx" +#include "oox/drawingml/drawingmltypes.hxx" + +using ::rtl::OUString; namespace oox { namespace drawingml { @@ -42,163 +46,126 @@ namespace drawingml { namespace { -const sal_Int32 PER_PERCENT = 1000; -const sal_Int32 MAX_PERCENT = 100 * PER_PERCENT; +/** Global storage for predefined color values used in OOXML file formats. */ +struct PresetColorsPool +{ + typedef ::std::vector< sal_Int32 > ColorVector; -const sal_Int32 PER_DEGREE = 60000; -const sal_Int32 MAX_DEGREE = 360 * PER_DEGREE; + ColorVector maDmlColors; /// Predefined colors in DrawingML, indexed by XML token. + ColorVector maVmlColors; /// Predefined colors in VML, indexed by XML token. + + explicit PresetColorsPool(); +}; + +// ---------------------------------------------------------------------------- + +PresetColorsPool::PresetColorsPool() : + maDmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ), + maVmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ) +{ + // predefined colors in DrawingML (map XML token identifiers to RGB values) + static const sal_Int32 spnDmlColors[] = + { + XML_aliceBlue, 0xF0F8FF, XML_antiqueWhite, 0xFAEBD7, + XML_aqua, 0x00FFFF, XML_aquamarine, 0x7FFFD4, + XML_azure, 0xF0FFFF, XML_beige, 0xF5F5DC, + XML_bisque, 0xFFE4C4, XML_black, 0x000000, + XML_blanchedAlmond, 0xFFEBCD, XML_blue, 0x0000FF, + XML_blueViolet, 0x8A2BE2, XML_brown, 0xA52A2A, + XML_burlyWood, 0xDEB887, XML_cadetBlue, 0x5F9EA0, + XML_chartreuse, 0x7FFF00, XML_chocolate, 0xD2691E, + XML_coral, 0xFF7F50, XML_cornflowerBlue, 0x6495ED, + XML_cornsilk, 0xFFF8DC, XML_crimson, 0xDC143C, + XML_cyan, 0x00FFFF, XML_deepPink, 0xFF1493, + XML_deepSkyBlue, 0x00BFFF, XML_dimGray, 0x696969, + XML_dkBlue, 0x00008B, XML_dkCyan, 0x008B8B, + XML_dkGoldenrod, 0xB8860B, XML_dkGray, 0xA9A9A9, + XML_dkGreen, 0x006400, XML_dkKhaki, 0xBDB76B, + XML_dkMagenta, 0x8B008B, XML_dkOliveGreen, 0x556B2F, + XML_dkOrange, 0xFF8C00, XML_dkOrchid, 0x9932CC, + XML_dkRed, 0x8B0000, XML_dkSalmon, 0xE9967A, + XML_dkSeaGreen, 0x8FBC8B, XML_dkSlateBlue, 0x483D8B, + XML_dkSlateGray, 0x2F4F4F, XML_dkTurquoise, 0x00CED1, + XML_dkViolet, 0x9400D3, XML_dodgerBlue, 0x1E90FF, + XML_firebrick, 0xB22222, XML_floralWhite, 0xFFFAF0, + XML_forestGreen, 0x228B22, XML_fuchsia, 0xFF00FF, + XML_gainsboro, 0xDCDCDC, XML_ghostWhite, 0xF8F8FF, + XML_gold, 0xFFD700, XML_goldenrod, 0xDAA520, + XML_gray, 0x808080, XML_green, 0x008000, + XML_greenYellow, 0xADFF2F, XML_honeydew, 0xF0FFF0, + XML_hotPink, 0xFF69B4, XML_indianRed, 0xCD5C5C, + XML_indigo, 0x4B0082, XML_ivory, 0xFFFFF0, + XML_khaki, 0xF0E68C, XML_lavender, 0xE6E6FA, + XML_lavenderBlush, 0xFFF0F5, XML_lawnGreen, 0x7CFC00, + XML_lemonChiffon, 0xFFFACD, XML_lime, 0x00FF00, + XML_limeGreen, 0x32CD32, XML_linen, 0xFAF0E6, + XML_ltBlue, 0xADD8E6, XML_ltCoral, 0xF08080, + XML_ltCyan, 0xE0FFFF, XML_ltGoldenrodYellow, 0xFAFA78, + XML_ltGray, 0xD3D3D3, XML_ltGreen, 0x90EE90, + XML_ltPink, 0xFFB6C1, XML_ltSalmon, 0xFFA07A, + XML_ltSeaGreen, 0x20B2AA, XML_ltSkyBlue, 0x87CEFA, + XML_ltSlateGray, 0x778899, XML_ltSteelBlue, 0xB0C4DE, + XML_ltYellow, 0xFFFFE0, XML_magenta, 0xFF00FF, + XML_maroon, 0x800000, XML_medAquamarine, 0x66CDAA, + XML_medBlue, 0x0000CD, XML_medOrchid, 0xBA55D3, + XML_medPurple, 0x9370DB, XML_medSeaGreen, 0x3CB371, + XML_medSlateBlue, 0x7B68EE, XML_medSpringGreen, 0x00FA9A, + XML_medTurquoise, 0x48D1CC, XML_medVioletRed, 0xC71585, + XML_midnightBlue, 0x191970, XML_mintCream, 0xF5FFFA, + XML_mistyRose, 0xFFE4E1, XML_moccasin, 0xFFE4B5, + XML_navajoWhite, 0xFFDEAD, XML_navy, 0x000080, + XML_oldLace, 0xFDF5E6, XML_olive, 0x808000, + XML_oliveDrab, 0x6B8E23, XML_orange, 0xFFA500, + XML_orangeRed, 0xFF4500, XML_orchid, 0xDA70D6, + XML_paleGoldenrod, 0xEEE8AA, XML_paleGreen, 0x98FB98, + XML_paleTurquoise, 0xAFEEEE, XML_paleVioletRed, 0xDB7093, + XML_papayaWhip, 0xFFEFD5, XML_peachPuff, 0xFFDAB9, + XML_peru, 0xCD853F, XML_pink, 0xFFC0CB, + XML_plum, 0xDDA0DD, XML_powderBlue, 0xB0E0E6, + XML_purple, 0x800080, XML_red, 0xFF0000, + XML_rosyBrown, 0xBC8F8F, XML_royalBlue, 0x4169E1, + XML_saddleBrown, 0x8B4513, XML_salmon, 0xFA8072, + XML_sandyBrown, 0xF4A460, XML_seaGreen, 0x2E8B57, + XML_seaShell, 0xFFF5EE, XML_sienna, 0xA0522D, + XML_silver, 0xC0C0C0, XML_skyBlue, 0x87CEEB, + XML_slateBlue, 0x6A5ACD, XML_slateGray, 0x708090, + XML_snow, 0xFFFAFA, XML_springGreen, 0x00FF7F, + XML_steelBlue, 0x4682B4, XML_tan, 0xD2B48C, + XML_teal, 0x008080, XML_thistle, 0xD8BFD8, + XML_tomato, 0xFF6347, XML_turquoise, 0x40E0D0, + XML_violet, 0xEE82EE, XML_wheat, 0xF5DEB3, + XML_white, 0xFFFFFF, XML_whiteSmoke, 0xF5F5F5, + XML_yellow, 0xFFFF00, XML_yellowGreen, 0x9ACD32 + }; + for( const sal_Int32* pnEntry = spnDmlColors; pnEntry < STATIC_ARRAY_END( spnDmlColors ); pnEntry += 2 ) + maDmlColors[ static_cast< size_t >( pnEntry[ 0 ] ) ] = pnEntry[ 1 ]; + + // predefined colors in VML (map XML token identifiers to RGB values) + static const sal_Int32 spnVmlColors[] = + { + XML_aqua, 0x00FFFF, XML_black, 0x000000, + XML_blue, 0x0000FF, XML_fuchsia, 0xFF00FF, + XML_gray, 0x808080, XML_green, 0x008000, + XML_lime, 0x00FF00, XML_maroon, 0x800000, + XML_navy, 0x000080, XML_olive, 0x808000, + XML_purple, 0x800080, XML_red, 0xFF0000, + XML_silver, 0xC0C0C0, XML_teal, 0x008080, + XML_white, 0xFFFFFF, XML_yellow, 0xFFFF00 + }; + for( const sal_Int32* pnEntry = spnVmlColors; pnEntry < STATIC_ARRAY_END( spnVmlColors ); pnEntry += 2 ) + maVmlColors[ static_cast< size_t >( pnEntry[ 0 ] ) ] = pnEntry[ 1 ]; +} + +// ---------------------------------------------------------------------------- + +struct StaticPresetColorsPool : public ::rtl::Static< PresetColorsPool, StaticPresetColorsPool > {}; + +// ---------------------------------------------------------------------------- const double DEC_GAMMA = 2.3; const double INC_GAMMA = 1.0 / DEC_GAMMA; -sal_Int32 lclGetPresetColor( sal_Int32 nToken ) -{ - switch( nToken ) - { - case XML_aliceBlue: return 0xF0F8FF; - case XML_antiqueWhite: return 0xFAEBD7; - case XML_aqua: return 0x00FFFF; - case XML_aquamarine: return 0x7FFFD4; - case XML_azure: return 0xF0FFFF; - case XML_beige: return 0xF5F5DC; - case XML_bisque: return 0xFFE4C4; - case XML_black: return 0x000000; - case XML_blanchedAlmond: return 0xFFEBCD; - case XML_blue: return 0x0000FF; - case XML_blueViolet: return 0x8A2BE2; - case XML_brown: return 0xA52A2A; - case XML_burlyWood: return 0xDEB887; - case XML_cadetBlue: return 0x5F9EA0; - case XML_chartreuse: return 0x7FFF00; - case XML_chocolate: return 0xD2691E; - case XML_coral: return 0xFF7F50; - case XML_cornflowerBlue: return 0x6495ED; - case XML_cornsilk: return 0xFFF8DC; - case XML_crimson: return 0xDC143C; - case XML_cyan: return 0x00FFFF; - case XML_deepPink: return 0xFF1493; - case XML_deepSkyBlue: return 0x00BFFF; - case XML_dimGray: return 0x696969; - case XML_dkBlue: return 0x00008B; - case XML_dkCyan: return 0x008B8B; - case XML_dkGoldenrod: return 0xB8860B; - case XML_dkGray: return 0xA9A9A9; - case XML_dkGreen: return 0x006400; - case XML_dkKhaki: return 0xBDB76B; - case XML_dkMagenta: return 0x8B008B; - case XML_dkOliveGreen: return 0x556B2F; - case XML_dkOrange: return 0xFF8C00; - case XML_dkOrchid: return 0x9932CC; - case XML_dkRed: return 0x8B0000; - case XML_dkSalmon: return 0xE9967A; - case XML_dkSeaGreen: return 0x8FBC8B; - case XML_dkSlateBlue: return 0x483D8B; - case XML_dkSlateGray: return 0x2F4F4F; - case XML_dkTurquoise: return 0x00CED1; - case XML_dkViolet: return 0x9400D3; - case XML_dodgerBlue: return 0x1E90FF; - case XML_firebrick: return 0xB22222; - case XML_floralWhite: return 0xFFFAF0; - case XML_forestGreen: return 0x228B22; - case XML_fuchsia: return 0xFF00FF; - case XML_gainsboro: return 0xDCDCDC; - case XML_ghostWhite: return 0xF8F8FF; - case XML_gold: return 0xFFD700; - case XML_goldenrod: return 0xDAA520; - case XML_gray: return 0x808080; - case XML_green: return 0x008000; - case XML_greenYellow: return 0xADFF2F; - case XML_honeydew: return 0xF0FFF0; - case XML_hotPink: return 0xFF69B4; - case XML_indianRed: return 0xCD5C5C; - case XML_indigo: return 0x4B0082; - case XML_ivory: return 0xFFFFF0; - case XML_khaki: return 0xF0E68C; - case XML_lavender: return 0xE6E6FA; - case XML_lavenderBlush: return 0xFFF0F5; - case XML_lawnGreen: return 0x7CFC00; - case XML_lemonChiffon: return 0xFFFACD; - case XML_lime: return 0x00FF00; - case XML_limeGreen: return 0x32CD32; - case XML_linen: return 0xFAF0E6; - case XML_ltBlue: return 0xADD8E6; - case XML_ltCoral: return 0xF08080; - case XML_ltCyan: return 0xE0FFFF; - case XML_ltGoldenrodYellow: return 0xFAFA78; - case XML_ltGray: return 0xD3D3D3; - case XML_ltGreen: return 0x90EE90; - case XML_ltPink: return 0xFFB6C1; - case XML_ltSalmon: return 0xFFA07A; - case XML_ltSeaGreen: return 0x20B2AA; - case XML_ltSkyBlue: return 0x87CEFA; - case XML_ltSlateGray: return 0x778899; - case XML_ltSteelBlue: return 0xB0C4DE; - case XML_ltYellow: return 0xFFFFE0; - case XML_magenta: return 0xFF00FF; - case XML_maroon: return 0x800000; - case XML_medAquamarine: return 0x66CDAA; - case XML_medBlue: return 0x0000CD; - case XML_medOrchid: return 0xBA55D3; - case XML_medPurple: return 0x9370DB; - case XML_medSeaGreen: return 0x3CB371; - case XML_medSlateBlue: return 0x7B68EE; - case XML_medSpringGreen: return 0x00FA9A; - case XML_medTurquoise: return 0x48D1CC; - case XML_medVioletRed: return 0xC71585; - case XML_midnightBlue: return 0x191970; - case XML_mintCream: return 0xF5FFFA; - case XML_mistyRose: return 0xFFE4E1; - case XML_moccasin: return 0xFFE4B5; - case XML_navajoWhite: return 0xFFDEAD; - case XML_navy: return 0x000080; - case XML_oldLace: return 0xFDF5E6; - case XML_olive: return 0x808000; - case XML_oliveDrab: return 0x6B8E23; - case XML_orange: return 0xFFA500; - case XML_orangeRed: return 0xFF4500; - case XML_orchid: return 0xDA70D6; - case XML_paleGoldenrod: return 0xEEE8AA; - case XML_paleGreen: return 0x98FB98; - case XML_paleTurquoise: return 0xAFEEEE; - case XML_paleVioletRed: return 0xDB7093; - case XML_papayaWhip: return 0xFFEFD5; - case XML_peachPuff: return 0xFFDAB9; - case XML_peru: return 0xCD853F; - case XML_pink: return 0xFFC0CB; - case XML_plum: return 0xDDA0DD; - case XML_powderBlue: return 0xB0E0E6; - case XML_purple: return 0x800080; - case XML_red: return 0xFF0000; - case XML_rosyBrown: return 0xBC8F8F; - case XML_royalBlue: return 0x4169E1; - case XML_saddleBrown: return 0x8B4513; - case XML_salmon: return 0xFA8072; - case XML_sandyBrown: return 0xF4A460; - case XML_seaGreen: return 0x2E8B57; - case XML_seaShell: return 0xFFF5EE; - case XML_sienna: return 0xA0522D; - case XML_silver: return 0xC0C0C0; - case XML_skyBlue: return 0x87CEEB; - case XML_slateBlue: return 0x6A5ACD; - case XML_slateGray: return 0x708090; - case XML_snow: return 0xFFFAFA; - case XML_springGreen: return 0x00FF7F; - case XML_steelBlue: return 0x4682B4; - case XML_tan: return 0xD2B48C; - case XML_teal: return 0x008080; - case XML_thistle: return 0xD8BFD8; - case XML_tomato: return 0xFF6347; - case XML_turquoise: return 0x40E0D0; - case XML_violet: return 0xEE82EE; - case XML_wheat: return 0xF5DEB3; - case XML_white: return 0xFFFFFF; - case XML_whiteSmoke: return 0xF5F5F5; - case XML_yellow: return 0xFFFF00; - case XML_yellowGreen: return 0x9ACD32; - } - OSL_ENSURE( false, "lclGetPresetColor - invalid preset color token" ); - return API_RGB_BLACK; -} +// ---------------------------------------------------------------------------- inline void lclRgbToRgbComponents( sal_Int32& ornR, sal_Int32& ornG, sal_Int32& ornB, sal_Int32 nRgb ) { @@ -248,7 +215,7 @@ void lclOffValue( sal_Int32& ornValue, sal_Int32 nOff, sal_Int32 nMax = MAX_PERC } // namespace -// ---------------------------------------------------------------------------- +// ============================================================================ Color::Color() : meMode( COLOR_UNUSED ), @@ -263,6 +230,24 @@ Color::~Color() { } +/*static*/ sal_Int32 Color::getDmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) +{ + /* Do not pass nDefaultRgb to ContainerHelper::getVectorElement(), to be + able to catch the existing vector entries without corresponding XML + token identifier. */ + sal_Int32 nRgbValue = ContainerHelper::getVectorElement( StaticPresetColorsPool::get().maDmlColors, nToken, API_RGB_TRANSPARENT ); + return (nRgbValue >= 0) ? nRgbValue : nDefaultRgb; +} + +/*static*/ sal_Int32 Color::getVmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) +{ + /* Do not pass nDefaultRgb to ContainerHelper::getVectorElement(), to be + able to catch the existing vector entries without corresponding XML + token identifier. */ + sal_Int32 nRgbValue = ContainerHelper::getVectorElement( StaticPresetColorsPool::get().maVmlColors, nToken, API_RGB_TRANSPARENT ); + return (nRgbValue >= 0) ? nRgbValue : nDefaultRgb; +} + void Color::setUnused() { meMode = COLOR_UNUSED; @@ -299,7 +284,10 @@ void Color::setHslClr( sal_Int32 nHue, sal_Int32 nSat, sal_Int32 nLum ) void Color::setPrstClr( sal_Int32 nToken ) { - setSrgbClr( lclGetPresetColor( nToken ) ); + sal_Int32 nRgbValue = getDmlPresetColor( nToken, API_RGB_TRANSPARENT ); + OSL_ENSURE( nRgbValue >= 0, "Color::setPrstClr - invalid preset color token" ); + if( nRgbValue >= 0 ) + setSrgbClr( nRgbValue ); } void Color::setSchemeClr( sal_Int32 nToken ) @@ -309,6 +297,13 @@ void Color::setSchemeClr( sal_Int32 nToken ) mnC1 = nToken; } +void Color::setPaletteClr( sal_Int32 nPaletteIdx ) +{ + OSL_ENSURE( nPaletteIdx >= 0, "Color::setPaletteClr - invalid palette index" ); + meMode = COLOR_PALETTE; + mnC1 = nPaletteIdx; +} + void Color::setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb ) { OSL_ENSURE( (-1 <= nLastRgb) && (nLastRgb <= 0xFFFFFF), "Color::setSysClr - invalid RGB value" ); @@ -347,12 +342,18 @@ void Color::addExcelTintTransformation( double fTint ) maTransforms.push_back( Transformation( NMSP_XLS | XML_tint, nValue ) ); } +void Color::clearTransformations() +{ + maTransforms.clear(); + clearTransparence(); +} + void Color::clearTransparence() { mnAlpha = MAX_PERCENT; } -sal_Int32 Color::getColor( const ::oox::core::XmlFilterBase& rFilter, sal_Int32 nPhClr ) const +sal_Int32 Color::getColor( const ::oox::core::FilterBase& rFilter, sal_Int32 nPhClr ) const { /* Special handling for theme style list placeholder colors (state COLOR_PH), Color::getColor() may be called with different placeholder @@ -364,151 +365,154 @@ sal_Int32 Color::getColor( const ::oox::core::XmlFilterBase& rFilter, sal_Int32 switch( meMode ) { - case COLOR_UNUSED: return -1; - case COLOR_FINAL: return mnC1; + case COLOR_UNUSED: mnC1 = API_RGB_TRANSPARENT; break; case COLOR_RGB: break; // nothing to do case COLOR_CRGB: break; // nothing to do case COLOR_HSL: break; // nothing to do - case COLOR_SCHEME: - meMode = COLOR_RGB; - lclRgbToRgbComponents( mnC1, mnC2, mnC3, rFilter.getSchemeClr( mnC1 ) ); - break; - case COLOR_PH: - meMode = COLOR_RGB; - lclRgbToRgbComponents( mnC1, mnC2, mnC3, nPhClr ); - bIsPh = true; - break; - case COLOR_SYSTEM: - meMode = COLOR_RGB; - lclRgbToRgbComponents( mnC1, mnC2, mnC3, rFilter.getSystemColor( mnC1, mnC2 ) ); - break; + case COLOR_SCHEME: setResolvedRgb( rFilter.getSchemeColor( mnC1 ) ); break; + case COLOR_PALETTE: setResolvedRgb( rFilter.getPaletteColor( mnC1 ) ); break; + case COLOR_SYSTEM: setResolvedRgb( rFilter.getSystemColor( mnC1, mnC2 ) ); break; + case COLOR_PH: setResolvedRgb( nPhClr ); bIsPh = true; break; + + case COLOR_FINAL: return mnC1; } - for( TransformVec::const_iterator aIt = maTransforms.begin(), aEnd = maTransforms.end(); aIt != aEnd; ++aIt ) + // if color is UNUSED or turns to UNUSED in setResolvedRgb, do not perform transformations + if( meMode != COLOR_UNUSED ) { - switch( aIt->mnToken ) + for( TransformVec::const_iterator aIt = maTransforms.begin(), aEnd = maTransforms.end(); aIt != aEnd; ++aIt ) { - case XML_red: toCrgb(); lclSetValue( mnC1, aIt->mnValue ); break; - case XML_redMod: toCrgb(); lclModValue( mnC1, aIt->mnValue ); break; - case XML_redOff: toCrgb(); lclOffValue( mnC1, aIt->mnValue ); break; - case XML_green: toCrgb(); lclSetValue( mnC2, aIt->mnValue ); break; - case XML_greenMod: toCrgb(); lclModValue( mnC2, aIt->mnValue ); break; - case XML_greenOff: toCrgb(); lclOffValue( mnC2, aIt->mnValue ); break; - case XML_blue: toCrgb(); lclSetValue( mnC3, aIt->mnValue ); break; - case XML_blueMod: toCrgb(); lclModValue( mnC3, aIt->mnValue ); break; - case XML_blueOff: toCrgb(); lclOffValue( mnC3, aIt->mnValue ); break; + switch( aIt->mnToken ) + { + case XML_red: toCrgb(); lclSetValue( mnC1, aIt->mnValue ); break; + case XML_redMod: toCrgb(); lclModValue( mnC1, aIt->mnValue ); break; + case XML_redOff: toCrgb(); lclOffValue( mnC1, aIt->mnValue ); break; + case XML_green: toCrgb(); lclSetValue( mnC2, aIt->mnValue ); break; + case XML_greenMod: toCrgb(); lclModValue( mnC2, aIt->mnValue ); break; + case XML_greenOff: toCrgb(); lclOffValue( mnC2, aIt->mnValue ); break; + case XML_blue: toCrgb(); lclSetValue( mnC3, aIt->mnValue ); break; + case XML_blueMod: toCrgb(); lclModValue( mnC3, aIt->mnValue ); break; + case XML_blueOff: toCrgb(); lclOffValue( mnC3, aIt->mnValue ); break; - case XML_hue: toHsl(); lclSetValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; - case XML_hueMod: toHsl(); lclModValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; - case XML_hueOff: toHsl(); lclOffValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; - case XML_sat: toHsl(); lclSetValue( mnC2, aIt->mnValue ); break; - case XML_satMod: toHsl(); lclModValue( mnC2, aIt->mnValue ); break; - case XML_satOff: toHsl(); lclOffValue( mnC2, aIt->mnValue ); break; + case XML_hue: toHsl(); lclSetValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; + case XML_hueMod: toHsl(); lclModValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; + case XML_hueOff: toHsl(); lclOffValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; + case XML_sat: toHsl(); lclSetValue( mnC2, aIt->mnValue ); break; + case XML_satMod: toHsl(); lclModValue( mnC2, aIt->mnValue ); break; + case XML_satOff: toHsl(); lclOffValue( mnC2, aIt->mnValue ); break; - case XML_lum: - toHsl(); - lclSetValue( mnC3, aIt->mnValue ); - // if color changes to black or white, it will stay gray if luminance changes again - if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; - break; - case XML_lumMod: - toHsl(); - lclModValue( mnC3, aIt->mnValue ); - // if color changes to black or white, it will stay gray if luminance changes again - if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; - break; - case XML_lumOff: - toHsl(); - lclOffValue( mnC3, aIt->mnValue ); - // if color changes to black or white, it will stay gray if luminance changes again - if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; - break; + case XML_lum: + toHsl(); + lclSetValue( mnC3, aIt->mnValue ); + // if color changes to black or white, it will stay gray if luminance changes again + if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; + break; + case XML_lumMod: + toHsl(); + lclModValue( mnC3, aIt->mnValue ); + // if color changes to black or white, it will stay gray if luminance changes again + if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; + break; + case XML_lumOff: + toHsl(); + lclOffValue( mnC3, aIt->mnValue ); + // if color changes to black or white, it will stay gray if luminance changes again + if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; + break; - case XML_shade: - // shade: 0% = black, 100% = original color - toCrgb(); - OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid shade value" ); - if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) - { - double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; - mnC1 = static_cast< sal_Int32 >( mnC1 * fFactor ); - mnC2 = static_cast< sal_Int32 >( mnC2 * fFactor ); - mnC3 = static_cast< sal_Int32 >( mnC3 * fFactor ); - } - break; - case XML_tint: - // tint: 0% = white, 100% = original color - toCrgb(); - OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); - if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) - { - double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; - mnC1 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC1) * fFactor ); - mnC2 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC2) * fFactor ); - mnC3 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC3) * fFactor ); - } - break; - case XLS_TOKEN( tint ): - // Excel tint: move luminance relative to current value - toHsl(); - OSL_ENSURE( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); - if( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue < 0) ) - { - // negative: luminance towards 0% (black) - lclModValue( mnC3, aIt->mnValue + MAX_PERCENT ); - } - else if( (0 < aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) - { - // positive: luminance towards 100% (white) + case XML_shade: + // shade: 0% = black, 100% = original color + toCrgb(); + OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid shade value" ); + if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) + { + double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; + mnC1 = static_cast< sal_Int32 >( mnC1 * fFactor ); + mnC2 = static_cast< sal_Int32 >( mnC2 * fFactor ); + mnC3 = static_cast< sal_Int32 >( mnC3 * fFactor ); + } + break; + case XML_tint: + // tint: 0% = white, 100% = original color + toCrgb(); + OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); + if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) + { + double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; + mnC1 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC1) * fFactor ); + mnC2 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC2) * fFactor ); + mnC3 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC3) * fFactor ); + } + break; + case XLS_TOKEN( tint ): + // Excel tint: move luminance relative to current value + toHsl(); + OSL_ENSURE( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); + if( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue < 0) ) + { + // negative: luminance towards 0% (black) + lclModValue( mnC3, aIt->mnValue + MAX_PERCENT ); + } + else if( (0 < aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) + { + // positive: luminance towards 100% (white) + mnC3 = MAX_PERCENT - mnC3; + lclModValue( mnC3, MAX_PERCENT - aIt->mnValue ); + mnC3 = MAX_PERCENT - mnC3; + } + break; + + case XML_gray: + // change color to gray, weighted RGB: 22% red, 72% green, 6% blue + toRgb(); + mnC1 = mnC2 = mnC3 = (mnC1 * 22 + mnC2 * 72 + mnC3 * 6) / 100; + break; + + case XML_comp: + // comp: rotate hue by 180 degrees, do not change lum/sat + toHsl(); + (mnC1 += 180 * PER_DEGREE) %= MAX_DEGREE; + break; + case XML_inv: + // invert percentual RGB values + toCrgb(); + mnC1 = MAX_PERCENT - mnC1; + mnC2 = MAX_PERCENT - mnC2; mnC3 = MAX_PERCENT - mnC3; - lclModValue( mnC3, MAX_PERCENT - aIt->mnValue ); - mnC3 = MAX_PERCENT - mnC3; - } - break; + break; - case XML_gray: - // change color to gray, weighted RGB: 22% red, 72% green, 6% blue - toRgb(); - mnC1 = mnC2 = mnC3 = (mnC1 * 22 + mnC2 * 72 + mnC3 * 6) / 100; - break; - - case XML_comp: - // comp: rotate hue by 180 degrees, do not change lum/sat - toHsl(); - (mnC1 += 180 * PER_DEGREE) %= MAX_DEGREE; - break; - case XML_inv: - // invert percentual RGB values - toCrgb(); - mnC1 = MAX_PERCENT - mnC1; - mnC2 = MAX_PERCENT - mnC2; - mnC3 = MAX_PERCENT - mnC3; - break; - - case XML_gamma: - // increase gamma of color - toCrgb(); - mnC1 = lclGamma( mnC1, INC_GAMMA ); - mnC2 = lclGamma( mnC2, INC_GAMMA ); - mnC3 = lclGamma( mnC3, INC_GAMMA ); - break; - case XML_invGamma: - // decrease gamma of color - toCrgb(); - mnC1 = lclGamma( mnC1, DEC_GAMMA ); - mnC2 = lclGamma( mnC2, DEC_GAMMA ); - mnC3 = lclGamma( mnC3, DEC_GAMMA ); - break; + case XML_gamma: + // increase gamma of color + toCrgb(); + mnC1 = lclGamma( mnC1, INC_GAMMA ); + mnC2 = lclGamma( mnC2, INC_GAMMA ); + mnC3 = lclGamma( mnC3, INC_GAMMA ); + break; + case XML_invGamma: + // decrease gamma of color + toCrgb(); + mnC1 = lclGamma( mnC1, DEC_GAMMA ); + mnC2 = lclGamma( mnC2, DEC_GAMMA ); + mnC3 = lclGamma( mnC3, DEC_GAMMA ); + break; + } } + + // store resulting RGB value in mnC1 + toRgb(); + mnC1 = lclRgbComponentsToRgb( mnC1, mnC2, mnC3 ); + } + else // if( meMode != COLOR_UNUSED ) + { + mnC1 = API_RGB_TRANSPARENT; } - toRgb(); meMode = bIsPh ? COLOR_PH : COLOR_FINAL; if( meMode == COLOR_FINAL ) maTransforms.clear(); - return mnC1 = lclRgbComponentsToRgb( mnC1, mnC2, mnC3 ); + return mnC1; } bool Color::hasTransparence() const @@ -523,6 +527,12 @@ sal_Int16 Color::getTransparence() const // private -------------------------------------------------------------------- +void Color::setResolvedRgb( sal_Int32 nRgb ) const +{ + meMode = (nRgb < 0) ? COLOR_UNUSED : COLOR_RGB; + lclRgbToRgbComponents( mnC1, mnC2, mnC3, nRgb ); +} + void Color::toRgb() const { switch( meMode ) diff --git a/oox/source/drawingml/customshapeproperties.cxx b/oox/source/drawingml/customshapeproperties.cxx index 5a1756e6d110..fdede72a7e8e 100644 --- a/oox/source/drawingml/customshapeproperties.cxx +++ b/oox/source/drawingml/customshapeproperties.cxx @@ -63,7 +63,7 @@ void CustomShapeProperties::apply( const CustomShapePropertiesPtr& /* rSourceCus // not sure if this needs to be implemented } -void CustomShapeProperties::pushToPropSet( const ::oox::core::XmlFilterBase& /* rFilterBase */, +void CustomShapeProperties::pushToPropSet( const ::oox::core::FilterBase& /* rFilterBase */, const Reference < XPropertySet >& xPropSet, const Reference < XShape > & xShape ) const { if ( maShapePresetType.getLength() ) diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index 46fe6ae5292c..f6a72c3aafce 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -44,7 +44,8 @@ #include "oox/helper/modelobjecthelper.hxx" #include "oox/helper/propertymap.hxx" #include "oox/helper/propertyset.hxx" -#include "oox/core/xmlfilterbase.hxx" +#include "oox/core/filterbase.hxx" +#include "oox/drawingml/drawingmltypes.hxx" using namespace ::com::sun::star; using namespace ::com::sun::star::drawing; @@ -55,7 +56,8 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; -using ::oox::core::XmlFilterBase; +using ::com::sun::star::geometry::IntegerRectangle2D; +using ::oox::core::FilterBase; namespace oox { namespace drawingml { @@ -106,7 +108,7 @@ RectanglePoint lclGetRectanglePoint( sal_Int32 nToken ) return RectanglePoint_LEFT_TOP; } -const awt::Size lclGetOriginalSize( const XmlFilterBase& rFilter, const Reference< XGraphic >& rxGraphic ) +const awt::Size lclGetOriginalSize( const FilterBase& rFilter, const Reference< XGraphic >& rxGraphic ) { awt::Size aSize100thMM( 0, 0 ); try @@ -222,8 +224,8 @@ Color FillProperties::getBestSolidColor() const return aSolidColor; } -void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, +void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const FillPropertyIds& rPropIds, sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const { if( moFillType.has() ) @@ -254,7 +256,8 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds aGradient.StartIntensity = 100; aGradient.EndIntensity = 100; - if( maGradientProps.maGradientStops.size() > 1 ) + size_t nColorCount = maGradientProps.maGradientStops.size(); + if( nColorCount > 1 ) { aGradient.StartColor = maGradientProps.maGradientStops.begin()->second.getColor( rFilter, nPhClr ); aGradient.EndColor = maGradientProps.maGradientStops.rbegin()->second.getColor( rFilter, nPhClr ); @@ -264,19 +267,36 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds if ( !maGradientProps.moRotateWithShape.get( false ) ) nShapeRotation = 0; + sal_Int32 nDmlAngle = 0; if( maGradientProps.moGradientPath.has() ) { aGradient.Style = (maGradientProps.moGradientPath.get() == XML_circle) ? awt::GradientStyle_ELLIPTICAL : awt::GradientStyle_RECT; - aGradient.Angle = static_cast< sal_Int16 >( (900 - (nShapeRotation / 6000)) % 3600 ); - aGradient.XOffset = maGradientProps.moFillToRect.has() ? getLimitedValue< sal_Int16, sal_Int32 >( maGradientProps.moFillToRect.get().X1 / 1000, 30, 70 ) : 50; - aGradient.YOffset = maGradientProps.moFillToRect.has() ? getLimitedValue< sal_Int16, sal_Int32 >( maGradientProps.moFillToRect.get().Y1 / 1000, 30, 70 ) : 50; + // position of gradient center (limited to [30%;70%], otherwise gradient is too hidden) + IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.get( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) ); + sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2; + aGradient.XOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterX / PER_PERCENT, 30, 70 ); + sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2; + aGradient.YOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterY / PER_PERCENT, 30, 70 ); ::std::swap( aGradient.StartColor, aGradient.EndColor ); + nDmlAngle = nShapeRotation; } else { - aGradient.Style = awt::GradientStyle_LINEAR; - aGradient.Angle = static_cast< sal_Int16 >( (4500 - ((maGradientProps.moShadeAngle.get( 0 ) - nShapeRotation) / 6000)) % 3600 ); + /* Try to detect a VML axial gradient. This type of + gradient is simulated by a 3-point linear gradient + with equal start and end color. */ + bool bAxial = (nColorCount == 3) && (aGradient.StartColor == aGradient.EndColor); + aGradient.Style = bAxial ? awt::GradientStyle_AXIAL : awt::GradientStyle_LINEAR; + if( bAxial ) + { + GradientFillProperties::GradientStopMap::const_iterator aIt = maGradientProps.maGradientStops.begin(); + // API StartColor is inner color in axial gradient + aGradient.StartColor = (++aIt)->second.getColor( rFilter, nPhClr ); + } + nDmlAngle = maGradientProps.moShadeAngle.get( 0 ) - nShapeRotation; } + // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees) + aGradient.Angle = static_cast< sal_Int16 >( (4500 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 ); // push gradient or named gradient to property map if( rPropIds.mbNamedFillGradient ) @@ -340,10 +360,10 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) ) { // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm - double fScaleX = maBlipProps.moTileScaleX.get( 100000 ) / 100000.0; + double fScaleX = maBlipProps.moTileScaleX.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT ); sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 ); rPropMap.setProperty( rPropIds[ FillBitmapSizeXId ], nFillBmpSizeX ); - double fScaleY = maBlipProps.moTileScaleY.get( 100000 ) / 100000.0; + double fScaleY = maBlipProps.moTileScaleY.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT ); sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 ); rPropMap.setProperty( rPropIds[ FillBitmapSizeYId ], nFillBmpSizeY ); @@ -383,12 +403,12 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds } } -void FillProperties::pushToPropSet( PropertySet& rPropSet, const FillPropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, +void FillProperties::pushToPropSet( PropertySet& rPropSet, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const FillPropertyIds& rPropIds, sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const { PropertyMap aPropMap; - pushToPropMap( aPropMap, rPropIds, rFilter, rModelObjHelper, nShapeRotation, nPhClr ); + pushToPropMap( aPropMap, rFilter, rModelObjHelper, rPropIds, nShapeRotation, nPhClr ); rPropSet.setProperties( aPropMap ); } @@ -399,7 +419,7 @@ void GraphicProperties::assignUsed( const GraphicProperties& rSourceProps ) maBlipProps.assignUsed( rSourceProps.maBlipProps ); } -void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFilterBase& rFilter, sal_Int32 nPhClr ) const +void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter, sal_Int32 nPhClr ) const { if( maBlipProps.mxGraphic.is() ) { @@ -436,15 +456,15 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFilterBas rPropMap[ PROP_GraphicColorMode ] <<= eColorMode; // brightness and contrast - sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.get( 0 ) / 1000, -100, 100 ); + sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.get( 0 ) / PER_PERCENT, -100, 100 ); if( nBrightness != 0 ) rPropMap[ PROP_AdjustLuminance ] <<= nBrightness; - sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.get( 0 ) / 1000, -100, 100 ); + sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.get( 0 ) / PER_PERCENT, -100, 100 ); if( nContrast != 0 ) rPropMap[ PROP_AdjustContrast ] <<= nContrast; } -void GraphicProperties::pushToPropSet( PropertySet& rPropSet, const XmlFilterBase& rFilter, sal_Int32 nPhClr ) const +void GraphicProperties::pushToPropSet( PropertySet& rPropSet, const FilterBase& rFilter, sal_Int32 nPhClr ) const { PropertyMap aPropMap; pushToPropMap( aPropMap, rFilter, nPhClr ); diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx index 7f31bc05cb7e..6cee420c167d 100644 --- a/oox/source/drawingml/lineproperties.cxx +++ b/oox/source/drawingml/lineproperties.cxx @@ -43,8 +43,8 @@ #include "oox/helper/modelobjecthelper.hxx" #include "oox/helper/propertymap.hxx" #include "oox/helper/propertyset.hxx" +#include "oox/core/filterbase.hxx" #include "oox/core/namespaces.hxx" -#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" using namespace ::com::sun::star::drawing; @@ -55,7 +55,7 @@ using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; using ::com::sun::star::awt::Point; using ::com::sun::star::container::XNameContainer; -using ::oox::core::XmlFilterBase; +using ::oox::core::FilterBase; namespace oox { namespace drawingml { @@ -82,6 +82,85 @@ static const sal_Int32 spnDefaultLineIds[ LineId_END ] = // ---------------------------------------------------------------------------- +void lclSetDashData( LineDash& orLineDash, sal_Int16 nDots, sal_Int32 nDotLen, + sal_Int16 nDashes, sal_Int32 nDashLen, sal_Int32 nDistance ) +{ + orLineDash.Dots = nDots; + orLineDash.DotLen = nDotLen; + orLineDash.Dashes = nDashes; + orLineDash.DashLen = nDashLen; + orLineDash.Distance = nDistance; +} + +/** Converts the specified preset dash to API dash. + + Line length and dot length are set relative to line width and have to be + multiplied by the actual line width after this function. + */ +void lclConvertPresetDash( LineDash& orLineDash, sal_Int32 nPresetDash ) +{ + switch( nPresetDash ) + { + case XML_dot: lclSetDashData( orLineDash, 1, 1, 0, 0, 3 ); break; + case XML_dash: lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); break; + case XML_dashDot: lclSetDashData( orLineDash, 1, 1, 1, 4, 3 ); break; + + case XML_lgDash: lclSetDashData( orLineDash, 0, 0, 1, 8, 3 ); break; + case XML_lgDashDot: lclSetDashData( orLineDash, 1, 1, 1, 8, 3 ); break; + case XML_lgDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 8, 3 ); break; + + case XML_sysDot: lclSetDashData( orLineDash, 1, 1, 0, 0, 1 ); break; + case XML_sysDash: lclSetDashData( orLineDash, 0, 0, 1, 3, 1 ); break; + case XML_sysDashDot: lclSetDashData( orLineDash, 1, 1, 1, 3, 1 ); break; + case XML_sysDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 3, 1 ); break; + + default: + OSL_ENSURE( false, "lclConvertPresetDash - unsupported preset dash" ); + lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); + } +} + +/** Converts the passed custom dash to API dash. + + Line length and dot length are set relative to line width and have to be + multiplied by the actual line width after this function. + */ +void lclConvertCustomDash( LineDash& orLineDash, const LineProperties::DashStopVector& rCustomDash ) +{ + if( rCustomDash.empty() ) + { + OSL_ENSURE( false, "lclConvertCustomDash - unexpected empty custom dash" ); + lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); + return; + } + + // count dashes and dots (stops equal or less than 2 are assumed to be dots) + sal_Int16 nDots = 0; + sal_Int32 nDotLen = 0; + sal_Int16 nDashes = 0; + sal_Int32 nDashLen = 0; + sal_Int32 nDistance = 0; + for( LineProperties::DashStopVector::const_iterator aIt = rCustomDash.begin(), aEnd = rCustomDash.end(); aIt != aEnd; ++aIt ) + { + if( aIt->first <= 2 ) + { + ++nDots; + nDotLen += aIt->first; + } + else + { + ++nDashes; + nDashLen += aIt->first; + } + nDistance += aIt->second; + } + orLineDash.DotLen = (nDots > 0) ? ::std::max< sal_Int32 >( nDotLen / nDots, 1 ) : 0; + orLineDash.Dots = nDots; + orLineDash.DashLen = (nDashes > 0) ? ::std::max< sal_Int32 >( nDashLen / nDashes, 1 ) : 0; + orLineDash.Dashes = nDashes; + orLineDash.Distance = ::std::max< sal_Int32 >( nDistance / rCustomDash.size(), 1 ); +} + DashStyle lclGetDashStyle( sal_Int32 nToken ) { switch( nToken ) @@ -122,7 +201,7 @@ sal_Int32 lclGetArrowSize( sal_Int32 nToken ) // ---------------------------------------------------------------------------- void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& rArrowProps, - const LinePropertyIds& rPropIds, ModelObjectHelper& rModelObjHelper, sal_Int32 nLineWidth, bool bLineEnd ) + ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nLineWidth, bool bLineEnd ) { PolyPolygonBezierCoords aMarker; OUString aMarkerName; @@ -310,14 +389,17 @@ void LineProperties::assignUsed( const LineProperties& rSourceProps ) maStartArrow.assignUsed( rSourceProps.maStartArrow ); maEndArrow.assignUsed( rSourceProps.maEndArrow ); maLineFill.assignUsed( rSourceProps.maLineFill ); + if( !rSourceProps.maCustomDash.empty() ) + maCustomDash = rSourceProps.maCustomDash; moLineWidth.assignIfUsed( rSourceProps.moLineWidth ); moPresetDash.assignIfUsed( rSourceProps.moPresetDash ); + moLineCompound.assignIfUsed( rSourceProps.moLineCompound ); moLineCap.assignIfUsed( rSourceProps.moLineCap ); moLineJoint.assignIfUsed( rSourceProps.moLineJoint ); } -void LineProperties::pushToPropMap( PropertyMap& rPropMap, const LinePropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, sal_Int32 nPhClr ) const +void LineProperties::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const { // line fill type must exist, otherwise ignore other properties if( maLineFill.moFillType.has() ) @@ -326,51 +408,22 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, const LinePropertyIds LineStyle eLineStyle = (maLineFill.moFillType.get() == XML_noFill) ? LineStyle_NONE : LineStyle_SOLID; // create line dash from preset dash token (not for invisible line) - if( (eLineStyle != LineStyle_NONE) && moPresetDash.differsFrom( XML_solid ) ) + if( (eLineStyle != LineStyle_NONE) && (moPresetDash.differsFrom( XML_solid ) || (!moPresetDash && !maCustomDash.empty())) ) { LineDash aLineDash; - - sal_Int32 nLineWidth = GetCoordinate( moLineWidth.get( 103500 ) ); aLineDash.Style = lclGetDashStyle( moLineCap.get( XML_rnd ) ); - aLineDash.Dots = 1; - aLineDash.DotLen = nLineWidth; - aLineDash.Dashes = 0; - aLineDash.DashLen = 8 * nLineWidth; - aLineDash.Distance = 3 * nLineWidth; - switch( moPresetDash.get() ) - { - default: - case XML_dash: - case XML_sysDash: - aLineDash.DashLen = 4 * nLineWidth; - // passthrough intended - case XML_lgDash: - aLineDash.Dots = 0; - aLineDash.Dashes = 1; - break; + // convert preset dash or custom dash + if( moPresetDash.has() ) + lclConvertPresetDash( aLineDash, moPresetDash.get() ); + else + lclConvertCustomDash( aLineDash, maCustomDash ); - case XML_dashDot: - case XML_sysDashDot: - aLineDash.DashLen = 4 * nLineWidth; - // passthrough intended - case XML_lgDashDot: - aLineDash.Dashes = 1; - break; - - case XML_sysDashDotDot: - aLineDash.DashLen = 4 * nLineWidth; - // passthrough intended - case XML_lgDashDotDot: - aLineDash.Dots = 2; - aLineDash.Dashes = 1; - break; - - case XML_dot: - case XML_sysDot: - aLineDash.Distance = aLineDash.DotLen; - break; - } + // convert relative dash/dot length to absolute length + sal_Int32 nLineWidth = GetCoordinate( moLineWidth.get( 103500 ) ); + aLineDash.DotLen *= nLineWidth; + aLineDash.DashLen *= nLineWidth; + aLineDash.Distance *= nLineWidth; if( rPropIds.mbNamedLineDash ) { @@ -409,16 +462,16 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, const LinePropertyIds } // line markers - lclPushMarkerProperties( rPropMap, maStartArrow, rPropIds, rModelObjHelper, moLineWidth.get( 0 ), false ); - lclPushMarkerProperties( rPropMap, maEndArrow, rPropIds, rModelObjHelper, moLineWidth.get( 0 ), true ); + lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), false ); + lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), true ); } } -void LineProperties::pushToPropSet( PropertySet& rPropSet, const LinePropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, sal_Int32 nPhClr ) const +void LineProperties::pushToPropSet( PropertySet& rPropSet, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const { PropertyMap aPropMap; - pushToPropMap( aPropMap, rPropIds, rFilter, rModelObjHelper, nPhClr ); + pushToPropMap( aPropMap, rFilter, rModelObjHelper, rPropIds, nPhClr ); rPropSet.setProperties( aPropMap ); } diff --git a/oox/source/drawingml/linepropertiescontext.cxx b/oox/source/drawingml/linepropertiescontext.cxx index b98f30738ec0..e6c6f76d5585 100644 --- a/oox/source/drawingml/linepropertiescontext.cxx +++ b/oox/source/drawingml/linepropertiescontext.cxx @@ -53,6 +53,7 @@ LinePropertiesContext::LinePropertiesContext( ContextHandler& rParent, const Ref { AttributeList aAttribs( xAttribs ); mrLineProperties.moLineWidth = aAttribs.getInteger( XML_w ); + mrLineProperties.moLineCompound = aAttribs.getToken( XML_cmpd ); mrLineProperties.moLineCap = aAttribs.getToken( XML_cap ); } @@ -79,6 +80,11 @@ Reference< XFastContextHandler > LinePropertiesContext::createFastChildContext( mrLineProperties.moPresetDash = aAttribs.getToken( XML_val ); break; case A_TOKEN( custDash ): // CT_DashStopList + xRet = this; + break; + case A_TOKEN( ds ): + mrLineProperties.maCustomDash.push_back( LineProperties::DashStop( + aAttribs.getInteger( XML_d, 0 ), aAttribs.getInteger( XML_sp, 0 ) ) ); break; // LineJoinPropertiesGroup diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 329aa6b36226..b1d68fabcb11 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -423,11 +423,11 @@ Reference< XShape > Shape::createAndInsert( // applying properties PropertySet aPropSet( xSet ); if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) ) - mpGraphicPropertiesPtr->pushToPropSet( aPropSet, rFilterBase, -1 ); + mpGraphicPropertiesPtr->pushToPropSet( aPropSet, rFilterBase ); if ( mpTablePropertiesPtr.get() && ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.TableShape" ) ) ) mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle ); - aFillProperties.pushToPropSet( aPropSet, FillProperties::DEFAULT_IDS, rFilterBase, rFilterBase.getModelObjectHelper(), mnRotation, nFillPhClr ); - aLineProperties.pushToPropSet( aPropSet, LineProperties::DEFAULT_IDS, rFilterBase, rFilterBase.getModelObjectHelper(), nLinePhClr ); + aFillProperties.pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper(), FillProperties::DEFAULT_IDS, mnRotation, nFillPhClr ); + aLineProperties.pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper(), LineProperties::DEFAULT_IDS, nLinePhClr ); // applying autogrowheight property before setting shape size, because // the shape size might be changed if currently autogrowheight is true diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx index 58aaf9081385..332e6f55601e 100644 --- a/oox/source/drawingml/table/tablecell.cxx +++ b/oox/source/drawingml/table/tablecell.cxx @@ -363,8 +363,7 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, ::oo aFillProperties.assignUsed( maFillProperties ); PropertySet aPropSet( xPropSet ); // TODO: phClr? - aFillProperties.pushToPropSet( aPropSet, FillProperties::DEFAULT_IDS, - rFilterBase, rFilterBase.getModelObjectHelper(), 0, -1 ); + aFillProperties.pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper() ); } } } } diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx index a5ef7558701f..41855170d26b 100644 --- a/oox/source/drawingml/textcharacterproperties.cxx +++ b/oox/source/drawingml/textcharacterproperties.cxx @@ -34,6 +34,7 @@ #include #include "oox/helper/helper.hxx" #include "oox/helper/propertyset.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "properties.hxx" #include "tokens.hxx" diff --git a/oox/source/drawingml/textparagraphproperties.cxx b/oox/source/drawingml/textparagraphproperties.cxx index c8197e3d78a3..35fe17716250 100644 --- a/oox/source/drawingml/textparagraphproperties.cxx +++ b/oox/source/drawingml/textparagraphproperties.cxx @@ -41,6 +41,7 @@ #include "oox/helper/helper.hxx" #include "oox/helper/propertyset.hxx" #include "oox/core/namespaces.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "properties.hxx" #include "tokens.hxx" diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 60cca8754a91..da21926e04bf 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -685,12 +685,12 @@ sal_uInt16 BiffObjectBase::dumpRepeatedRecId() void BiffObjectBase::dumpFrHeader( bool bWithFlags, bool bWithRange ) { - dumpHex< sal_uInt16 >( "rec-id", getRecNames() ); - sal_Int16 nFlags = bWithFlags ? dumpHex< sal_uInt16 >( "flags", "FR-FLAGS" ) : 0x0001; + dumpHex< sal_uInt16 >( "fr-rec-id", getRecNames() ); + sal_Int16 nFlags = bWithFlags ? dumpHex< sal_uInt16 >( "fr-flags", "FR-FLAGS" ) : 0x0001; if( bWithRange ) { if( getFlag< sal_uInt16 >( nFlags, 0x0001 ) ) - dumpRange( "range" ); + dumpRange( "fr-range" ); else dumpUnused( 8 ); } @@ -2698,14 +2698,23 @@ void WorkbookStreamObject::implDumpRecordBody() sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "STYLE-FLAGS" ); if( getFlag( nFlags, BIFF_STYLE_BUILTIN ) ) { - dumpDec< sal_uInt8 >( "builtin-idx", "STYLE-BUILTIN" ); - dumpDec< sal_uInt8 >( "outline-level" ); + dumpDec< sal_Int8 >( "builtin-idx", "STYLE-BUILTIN" ); + dumpDec< sal_Int8 >( "outline-level" ); } else dumpString( "style-name", BIFF_STR_8BITLENGTH ); } break; + case BIFF_ID_STYLEEXT: + dumpFrHeader( true, true ); + dumpHex< sal_uInt8 >( "flags", "STYLEEXT-FLAGS" ); + dumpDec< sal_uInt8 >( "category", "STYLEEXT-CATEGORY" ); + dumpDec< sal_Int8 >( "builtin-idx", "STYLEEXT-BUILTIN" ); + dumpDec< sal_Int8 >( "outline-level" ); + dumpUnicodeArray( "style-name", rStrm.readuInt16() ); + break; + case BIFF_ID_SXEXT: if( eBiff == BIFF8 ) { diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index 48c514b170d2..e9766865dd8b 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -347,6 +347,7 @@ multilist=RECORD-NAMES-BIFF8 0x0858=CHPIVOTREF,,,,,,, 0x0860=,,SHEETLAYOUT,,,,,SHEETPROTECTION 0x0868=,,,CHFRLABELPROPS,,,, + 0x0890=,,STYLEEXT,,,,, # chart records 0x1058=,,,,,,,CH3DDATAFORMAT 0x1060=CHFONTBASE,CHPIEEXT,CHLABELRANGE2,CHDATATABLE,CHPLOTGROWTH,CHSERINDEX,CHESCHERFORMAT,CHPIEEXTSETT @@ -1654,7 +1655,26 @@ combilist=STYLE-FLAGS 0x8000=builtin end -shortlist=STYLE-BUILTIN,0,normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink +shortlist=STYLE-BUILTIN,-1,user-defined,normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink + +# STYLEEXT ------------------------------------------------------------------- + +flagslist=STYLEEXT-FLAGS + 0x01=builtin + 0x02=hidden + 0x04=custom +end + +shortlist=STYLEEXT-CATEGORY,0,custom,good-bad-neutral,data-model,title-heading,themed,number-format + +multilist=STYLEEXT-BUILTIN + include=STYLE-BUILTIN + 10=note,warning-text,,,,title,heading-1,heading-2,heading-3,heading-4 + 20=input,output,calculation,check-cell,linked-cell,total,good,bad,neutral,accent1 + 30=20%-accent1,40%-accent1,60%-accent1,accent2,20%-accent2,40%-accent2,60%-accent2,accent3,20%-accent3,40%-accent3 + 40=60%-accent3,accent4,20%-accent4,40%-accent4,60%-accent4,accent5,20%-accent5,40%-accent5,60%-accent5,accent6 + 50=20%-accent6,40%-accent6,60%-accent6,explanatory-text +end # SXEXT ---------------------------------------------------------------------- diff --git a/oox/source/helper/propertymap.cxx b/oox/source/helper/propertymap.cxx index ccc5cfdd62b4..a40b4a737bd3 100644 --- a/oox/source/helper/propertymap.cxx +++ b/oox/source/helper/propertymap.cxx @@ -35,6 +35,7 @@ #include #include #include "properties.hxx" +#include "oox/token/propertylist.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Any; @@ -59,7 +60,7 @@ namespace oox { namespace { /** Thread-save singleton of a vector of all supported property names. */ -struct PropertyNamesPool : public ::rtl::Static< PropertyNamesList, PropertyNamesPool > {}; +struct StaticPropertyList : public ::rtl::Static< PropertyList, StaticPropertyList > {}; // ---------------------------------------------------------------------------- @@ -103,7 +104,7 @@ GenericPropertySet::GenericPropertySet() GenericPropertySet::GenericPropertySet( const PropertyMap& rPropMap ) { - const PropertyNamesList& rPropNames = PropertyNamesPool::get(); + const PropertyList& rPropNames = StaticPropertyList::get(); for( PropertyMap::const_iterator aIt = rPropMap.begin(), aEnd = rPropMap.end(); aIt != aEnd; ++aIt ) maPropMap[ rPropNames[ aIt->first ] ] = aIt->second; } @@ -170,10 +171,19 @@ sal_Bool SAL_CALL GenericPropertySet::hasPropertyByName( const OUString& rProper // ============================================================================ -const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) +PropertyMap::PropertyMap() : + mpPropNames( &StaticPropertyList::get() ) +{ +} + +PropertyMap::~PropertyMap() +{ +} + +/*static*/ const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) { OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" ); - return PropertyNamesPool::get()[ nPropId ]; + return StaticPropertyList::get()[ nPropId ]; } const Any* PropertyMap::getProperty( sal_Int32 nPropId ) const @@ -187,12 +197,11 @@ Sequence< PropertyValue > PropertyMap::makePropertyValueSequence() const Sequence< PropertyValue > aSeq( static_cast< sal_Int32 >( size() ) ); if( !empty() ) { - const PropertyNamesList& rPropNames = PropertyNamesPool::get(); PropertyValue* pValues = aSeq.getArray(); for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pValues ) { OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::makePropertyValueSequence - invalid property identifier" ); - pValues->Name = rPropNames[ aIt->first ]; + pValues->Name = (*mpPropNames)[ aIt->first ]; pValues->Value = aIt->second; pValues->State = ::com::sun::star::beans::PropertyState_DIRECT_VALUE; } @@ -206,13 +215,12 @@ void PropertyMap::fillSequences( Sequence< OUString >& rNames, Sequence< Any >& rValues.realloc( static_cast< sal_Int32 >( size() ) ); if( !empty() ) { - const PropertyNamesList& rPropNames = PropertyNamesPool::get(); OUString* pNames = rNames.getArray(); Any* pValues = rValues.getArray(); for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pNames, ++pValues ) { OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::fillSequences - invalid property identifier" ); - *pNames = rPropNames[ aIt->first ]; + *pNames = (*mpPropNames)[ aIt->first ]; *pValues = aIt->second; } } diff --git a/oox/source/ole/axcontrolhelper.cxx b/oox/source/ole/axcontrolhelper.cxx index a1bd9bfd9ac7..cd8180728074 100644 --- a/oox/source/ole/axcontrolhelper.cxx +++ b/oox/source/ole/axcontrolhelper.cxx @@ -117,12 +117,12 @@ sal_Int32 AxControlHelper::convertColor( sal_uInt32 nAxColor ) const switch( meColorMode ) { case AX_DEFAULTCOLORMODE_BGR: return lclDecodeBgrColor( nAxColor ); - case AX_DEFAULTCOLORMODE_PALETTE: return getPaletteColor( static_cast< sal_uInt16 >( nAxColor & AX_PALETTECOLOR_MASK ) ); + case AX_DEFAULTCOLORMODE_PALETTE: return mrFilter.getPaletteColor( nAxColor & AX_PALETTECOLOR_MASK ); } break; case AX_COLORTYPE_PALETTE: - return getPaletteColor( static_cast< sal_uInt16 >( nAxColor & AX_PALETTECOLOR_MASK ) ); + return mrFilter.getPaletteColor( nAxColor & AX_PALETTECOLOR_MASK ); case AX_COLORTYPE_BGR: return lclDecodeBgrColor( nAxColor ); @@ -134,12 +134,6 @@ sal_Int32 AxControlHelper::convertColor( sal_uInt32 nAxColor ) const return 0; } -sal_Int32 AxControlHelper::getPaletteColor( sal_uInt16 /*nPaletteIdx*/ ) const -{ - OSL_ENSURE( false, "AxControlHelper::getPaletteColor - palette colors not implemented" ); - return 0; -} - // ============================================================================ AxEmbeddedControlHelper::AxEmbeddedControlHelper( const FilterBase& rFilter, diff --git a/oox/source/ppt/animvariantcontext.cxx b/oox/source/ppt/animvariantcontext.cxx index e8f60d9df234..f3b9de2dbf7a 100644 --- a/oox/source/ppt/animvariantcontext.cxx +++ b/oox/source/ppt/animvariantcontext.cxx @@ -40,6 +40,7 @@ #include "oox/helper/attributelist.hxx" #include "oox/core/namespaces.hxx" #include "oox/core/fragmenthandler.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/colorchoicecontext.hxx" #include "pptfilterhelpers.hxx" #include "tokens.hxx" diff --git a/oox/source/ppt/pptimport.cxx b/oox/source/ppt/pptimport.cxx index f772a9236785..0e463099e9c5 100644 --- a/oox/source/ppt/pptimport.cxx +++ b/oox/source/ppt/pptimport.cxx @@ -88,12 +88,7 @@ bool PowerPointImport::exportDocument() throw() return false; } -const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const -{ - return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : 0; -} - -sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const +sal_Int32 PowerPointImport::getSchemeColor( sal_Int32 nToken ) const { sal_Int32 nColor = 0; if ( mpActualSlidePersist ) @@ -101,7 +96,7 @@ sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const sal_Bool bColorMapped = sal_False; oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() ); if ( pClrMapPtr ) - bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken ); + bColorMapped = pClrMapPtr->getColorMap( nToken ); if ( !bColorMapped ) // try masterpage mapping { @@ -110,18 +105,18 @@ sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const { pClrMapPtr = pMasterPersist->getClrMap(); if ( pClrMapPtr ) - bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken ); + bColorMapped = pClrMapPtr->getColorMap( nToken ); } } oox::drawingml::ClrSchemePtr pClrSchemePtr( mpActualSlidePersist->getClrScheme() ); if ( pClrSchemePtr ) - pClrSchemePtr->getColor( nColorSchemeToken, nColor ); + pClrSchemePtr->getColor( nToken, nColor ); else { ::oox::drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme(); if( pTheme ) { - pTheme->getClrScheme().getColor( nColorSchemeToken, nColor ); + pTheme->getClrScheme().getColor( nToken, nColor ); } else { @@ -132,6 +127,11 @@ sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const return nColor; } +const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const +{ + return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : 0; +} + ::oox::vml::Drawing* PowerPointImport::getVmlDrawing() { return mpActualSlidePersist ? mpActualSlidePersist->getDrawing() : 0; diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx index 5ce09bbbdbd5..f85e5ec72876 100644 --- a/oox/source/ppt/slidepersist.cxx +++ b/oox/source/ppt/slidepersist.cxx @@ -180,9 +180,7 @@ void SlidePersist::createBackground( const XmlFilterBase& rFilterBase ) uno::Reference< beans::XPropertySet > xPagePropSet( mxPage, uno::UNO_QUERY_THROW ); uno::Reference< beans::XPropertySet > xPropertySet( aPropMap.makePropertySet() ); PropertySet aPropSet( xPropertySet ); - mpBackgroundPropertiesPtr->pushToPropSet( - aPropSet, ::oox::drawingml::FillProperties::DEFAULT_IDS, - rFilterBase, rFilterBase.getModelObjectHelper(), 0, -1 ); + mpBackgroundPropertiesPtr->pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper() ); xPagePropSet->setPropertyValue( sBackground, Any( xPropertySet ) ); } catch( Exception ) diff --git a/oox/source/ppt/timenodelistcontext.cxx b/oox/source/ppt/timenodelistcontext.cxx index 70da57a52bd4..12fe9809ba5d 100644 --- a/oox/source/ppt/timenodelistcontext.cxx +++ b/oox/source/ppt/timenodelistcontext.cxx @@ -51,6 +51,7 @@ #include "oox/helper/attributelist.hxx" #include "oox/core/namespaces.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "oox/drawingml/colorchoicecontext.hxx" #include "oox/ppt/slidetransition.hxx" diff --git a/oox/source/shape/FastTokenHandlerService.hxx b/oox/source/shape/FastTokenHandlerService.hxx index 64b79ab943ee..c41403539d11 100644 --- a/oox/source/shape/FastTokenHandlerService.hxx +++ b/oox/source/shape/FastTokenHandlerService.hxx @@ -27,17 +27,16 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#ifndef OOX_SHAPE_FAST_TOKEN_HANDLER_SERVICE_HXX -#define OOX_SHAPE_FAST_TOKEN_HANDLER_SERVICE_HXX -#include +#ifndef OOX_SHAPE_FASTTOKENHANDLERSERVICE_HXX +#define OOX_SHAPE_FASTTOKENHANDLERSERVICE_HXX -#include "sal/config.h" -#include "cppuhelper/factory.hxx" -#include "cppuhelper/implementationentry.hxx" -#include "cppuhelper/implbase2.hxx" -#include "com/sun/star/lang/XServiceInfo.hpp" -#include "com/sun/star/xml/sax/XFastTokenHandler.hpp" +#include +#include +#include +#include +#include +#include "oox/core/fasttokenhandler.hxx" namespace css = ::com::sun::star; @@ -70,7 +69,7 @@ private: virtual ~FastTokenHandlerService() {} css::uno::Reference< css::uno::XComponentContext > m_xContext; - FastTokenHandler mFastTokenHandler; + ::oox::core::FastTokenHandler mFastTokenHandler; }; ::rtl::OUString SAL_CALL FastTokenHandlerService_getImplementationName(); diff --git a/oox/source/shape/ShapeFilterBase.cxx b/oox/source/shape/ShapeFilterBase.cxx index 0933af28ffd5..9105b6ca38eb 100644 --- a/oox/source/shape/ShapeFilterBase.cxx +++ b/oox/source/shape/ShapeFilterBase.cxx @@ -53,11 +53,6 @@ const ::oox::drawingml::Theme* ShapeFilterBase::getCurrentTheme() const return 0; } -sal_Int32 ShapeFilterBase::getSchemeClr(sal_Int32 /*nColorSchemeToken*/ ) const -{ - return 0; -} - ::oox::vml::Drawing* ShapeFilterBase::getVmlDrawing() { return 0; diff --git a/oox/source/shape/ShapeFilterBase.hxx b/oox/source/shape/ShapeFilterBase.hxx index d90904ed22cc..1a2edcb461f2 100644 --- a/oox/source/shape/ShapeFilterBase.hxx +++ b/oox/source/shape/ShapeFilterBase.hxx @@ -55,9 +55,6 @@ public: /** Has to be implemented by each filter, returns the current theme. */ virtual const ::oox::drawingml::Theme* getCurrentTheme() const; - /** Has to be implemented by each filter to resolve scheme colors. */ - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; - /** Has to be implemented by each filter to return the collection of VML shapes. */ virtual ::oox::vml::Drawing* getVmlDrawing(); diff --git a/oox/source/token/gentoken.pl b/oox/source/token/gentoken.pl index 6c7c126bc4e2..196ac37ebb5c 100644 --- a/oox/source/token/gentoken.pl +++ b/oox/source/token/gentoken.pl @@ -3,7 +3,7 @@ $ARGV1 = shift @ARGV; $ARGV2 = shift @ARGV; $ARGV3 = shift @ARGV; -open ( TOKENS, $ARGV0 ) || die "can't open token file: $!"; +open ( TOKENS, $ARGV0 ) || die "can't open $ARGV0 file: $!"; my %tokens; while ( ) @@ -17,15 +17,15 @@ while ( ) } close ( TOKENS ); -open ( HXX, ">$ARGV1" ) or die "can't open tokens.hxx file: $!"; -open ( WORDS, ">$ARGV2" ) or die "can't open tokenwords.inl file: $!"; -open ( GPERF, ">$ARGV3" ) or die "can't open tokens.gperf file: $!"; +open ( HXX, ">$ARGV1" ) or die "can't open $ARGV1 file: $!"; +open ( WORDS, ">$ARGV2" ) or die "can't open $ARGV2 file: $!"; +open ( GPERF, ">$ARGV3" ) or die "can't open $ARGV3 file: $!"; print ( HXX "#ifndef OOX_TOKENS_HXX\n" ); print ( HXX "#define OOX_TOKENS_HXX\n\n" ); -print ( HXX "#include \n" ); +print ( HXX "#include \n" ); -print ( WORDS "static const sal_Char* tokentowordlist[] = {\n" ); +print ( WORDS "static const sal_Char* xmltokenwordlist[] = {\n" ); print ( GPERF "%language=C++\n" ); print ( GPERF "%global-table\n" ); @@ -47,7 +47,7 @@ foreach( sort( keys( %tokens ) ) ) } print ( HXX "const sal_Int32 XML_TOKEN_COUNT = $i;\n" ); -print ( HXX "const sal_Int32 XML_TOKEN_INVALID = -1;\n\n" ); +print ( HXX "const sal_Int32 XML_TOKEN_INVALID = ::com::sun::star::xml::sax::FastToken::DONTKNOW;\n\n" ); print ( HXX "const sal_Int32 XML_ROOT_CONTEXT = SAL_MAX_INT32;\n\n" ); print ( HXX "#endif\n" ); diff --git a/oox/source/token/propertylist.cxx b/oox/source/token/propertylist.cxx index b6be034daabc..153b15f32461 100644 --- a/oox/source/token/propertylist.cxx +++ b/oox/source/token/propertylist.cxx @@ -28,23 +28,31 @@ * ************************************************************************/ -#include +#include "oox/token/propertylist.hxx" #include "properties.hxx" -#include "oox/helper/propertymap.hxx" namespace oox { +namespace { + +// include auto-generated property name lists #include "propertywords.inc" +} // namespace + // ============================================================================ -PropertyNamesList::PropertyNamesList() +PropertyList::PropertyList() { reserve( static_cast< size_t >( PROP_COUNT ) ); for( sal_Int32 nIdx = 0; nIdx < PROP_COUNT; ++nIdx ) push_back( ::rtl::OUString::createFromAscii( propertywordlist[ nIdx ] ) ); } +PropertyList::~PropertyList() +{ +} + // ============================================================================ } // namespace oox diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx index 93da78313a69..733b18fd1f01 100644 --- a/oox/source/token/tokenmap.cxx +++ b/oox/source/token/tokenmap.cxx @@ -28,104 +28,84 @@ * ************************************************************************/ -#include -#include +#include "oox/token/tokenmap.hxx" #include -#include -#include "oox/core/fasttokenhandler.hxx" +#include #include "tokens.hxx" +#include "oox/helper/containerhelper.hxx" using ::rtl::OString; -using ::rtl::OStringBuffer; using ::rtl::OUString; -using ::rtl::OUStringToOString; -using ::osl::Mutex; -using ::osl::MutexGuard; using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::xml::sax::FastToken::DONTKNOW; namespace oox { -#include "tokens.inc" -#include "tokenwords.inc" - // ============================================================================ namespace { -Mutex& lclGetTokenMutex() -{ - static Mutex aMutex; - return aMutex; -} +// include auto-generated token lists +#include "tokens.inc" +#include "tokenwords.inc" } // namespace // ============================================================================ -FastTokenHandler::FastTokenHandler() +TokenMap::TokenMap() : + maTokenNames( static_cast< size_t >( XML_TOKEN_COUNT ) ) { + const sal_Char* const* ppcTokenWord = xmltokenwordlist; + for( TokenNameVector::iterator aIt = maTokenNames.begin(), aEnd = maTokenNames.end(); aIt != aEnd; ++aIt, ++ppcTokenWord ) + { + OString aUtf8Token( *ppcTokenWord ); + aIt->maUniName = OStringToOUString( aUtf8Token, RTL_TEXTENCODING_UTF8 ); + aIt->maUtf8Name = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUtf8Token.getStr() ), aUtf8Token.getLength() ); + } + #if OSL_DEBUG_LEVEL > 0 - MutexGuard aGuard( lclGetTokenMutex() ); + // check that the perfect_hash is in sync with the token name list bool bOk = true; - for( sal_Int32 nIdx = 0; bOk && (nIdx < XML_TOKEN_COUNT); ++nIdx ) + for( sal_Int32 nToken = 0; bOk && (nToken < XML_TOKEN_COUNT); ++nToken ) { // check that the getIdentifier <-> getToken roundtrip works - OUString aToken = getIdentifier( nIdx ); - bOk = getToken( aToken ) == nIdx; - OSL_ENSURE( bOk, OStringBuffer( "FastTokenHandler::FastTokenHandler - token list broken, #" ). - append( nIdx ).append( ", '" ). - append( OUStringToOString( aToken, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); + OString aUtf8Name = OUStringToOString( maTokenNames[ nToken ].maUniName, RTL_TEXTENCODING_UTF8 ); + struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); + bOk = pToken && (pToken->nToken == nToken); + OSL_ENSURE( bOk, ::rtl::OStringBuffer( "FastTokenHandler::FastTokenHandler - token list broken, #" ). + append( nToken ).append( ", '" ).append( aUtf8Name ).append( '\'' ).getStr() ); } #endif } -FastTokenHandler::~FastTokenHandler() +TokenMap::~TokenMap() { } -sal_Int32 FastTokenHandler::getToken( const OUString& rIdentifier ) throw( RuntimeException ) +OUString TokenMap::getUnicodeTokenName( sal_Int32 nToken ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - OString aUTF8 = OUStringToOString( rIdentifier, RTL_TEXTENCODING_UTF8 ); - - struct xmltoken * t = Perfect_Hash::in_word_set( aUTF8.getStr(), aUTF8.getLength() ); - return t ? t->nToken : DONTKNOW; + const TokenName* pTokenName = ContainerHelper::getVectorElement( maTokenNames, nToken ); + return pTokenName ? pTokenName->maUniName : OUString(); } -OUString FastTokenHandler::getIdentifier( sal_Int32 nToken ) throw( RuntimeException ) +sal_Int32 TokenMap::getTokenFromUnicode( const OUString& rUnicodeName ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - if( nToken >= XML_TOKEN_COUNT ) - return OUString(); - - static OUString aTokens[XML_TOKEN_COUNT]; - - if( aTokens[nToken].getLength() == 0 ) - aTokens[nToken] = OUString::createFromAscii( tokentowordlist[nToken] ); - - return aTokens[nToken]; + OString aUtf8Name = OUStringToOString( rUnicodeName, RTL_TEXTENCODING_UTF8 ); + struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); + return pToken ? pToken->nToken : XML_TOKEN_INVALID; } -Sequence< sal_Int8 > FastTokenHandler::getUTF8Identifier( sal_Int32 nToken ) throw( RuntimeException ) +Sequence< sal_Int8 > TokenMap::getUtf8TokenName( sal_Int32 nToken ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - if( nToken >= XML_TOKEN_COUNT ) - return Sequence< sal_Int8 >(); - - return Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8 *>(tokentowordlist[nToken]), strlen(tokentowordlist[nToken])); + const TokenName* pTokenName = ContainerHelper::getVectorElement( maTokenNames, nToken ); + return pTokenName ? pTokenName->maUtf8Name : Sequence< sal_Int8 >(); } -sal_Int32 FastTokenHandler::getTokenFromUTF8( const Sequence< sal_Int8 >& rIdentifier ) throw( RuntimeException ) +sal_Int32 TokenMap::getTokenFromUtf8( const Sequence< sal_Int8 >& rUtf8Name ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - struct xmltoken * t = Perfect_Hash::in_word_set( reinterpret_cast< const char* >( rIdentifier.getConstArray() ), rIdentifier.getLength()); - return t ? t->nToken : DONTKNOW; + struct xmltoken* pToken = Perfect_Hash::in_word_set( + reinterpret_cast< const char* >( rUtf8Name.getConstArray() ), rUtf8Name.getLength() ); + return pToken ? pToken->nToken : XML_TOKEN_INVALID; } // ============================================================================ diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 36e33e9d3f1a..4bf407747d95 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -1541,6 +1541,7 @@ dashLongHeavy dashSmallGap dashUpDiag dashVert +dashdot dashed dashedHeavy dashedSmall @@ -3063,6 +3064,9 @@ long longCurve longFileNames longText +longdash +longdashdot +longdashdotdot loop low lowKashida @@ -4448,6 +4452,10 @@ shininess shorebirdTracks short shortcutKey +shortdash +shortdashdot +shortdashdotdot +shortdot show showAll showAnimation diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk index 305353eb8f02..e4bc963cb1f6 100644 --- a/oox/source/vml/makefile.mk +++ b/oox/source/vml/makefile.mk @@ -47,6 +47,7 @@ ENABLE_EXCEPTIONS=TRUE SLOFILES = \ $(SLO)$/vmldrawing.obj \ $(SLO)$/vmldrawingfragment.obj \ + $(SLO)$/vmlformatting.obj \ $(SLO)$/vmlinputstream.obj \ $(SLO)$/vmlshape.obj \ $(SLO)$/vmlshapecontainer.obj \ diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx index 42529ea4a351..f7d9827851f9 100644 --- a/oox/source/vml/vmldrawing.cxx +++ b/oox/source/vml/vmldrawing.cxx @@ -147,6 +147,11 @@ const ControlInfo* Drawing::getControlInfo( const OUString& rShapeId ) const return ContainerHelper::getMapElement( maControls, rShapeId ); } +bool Drawing::isShapeSupported( const ShapeBase& /*rShape*/ ) const +{ + return true; +} + bool Drawing::convertShapeClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const { return false; diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index b622df39941c..6eab7efdba0e 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -63,7 +63,7 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At // DOCX filter handles plain shape elements with this fragment handler case VMLDRAWING_WORD: if( isRootElement() ) - return ShapeContextBase::createContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); + return ShapeContextBase::createShapeContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); break; // XLSX and PPTX filters load the entire VML fragment @@ -75,7 +75,7 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At if( nElement == XML_xml ) return this; break; case XML_xml: - return ShapeContextBase::createContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); + return ShapeContextBase::createShapeContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); } break; } diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx new file mode 100644 index 000000000000..a45054a77b52 --- /dev/null +++ b/oox/source/vml/vmlformatting.cxx @@ -0,0 +1,585 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: vmlformatting.cxx,v $ + * $Revision: 1.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/vml/vmlformatting.hxx" +#include +#include "tokens.hxx" +#include "oox/token/tokenmap.hxx" +#include "oox/helper/propertymap.hxx" +#include "oox/core/filterbase.hxx" +#include "oox/drawingml/color.hxx" +#include "oox/drawingml/drawingmltypes.hxx" +#include "oox/drawingml/fillproperties.hxx" +#include "oox/drawingml/lineproperties.hxx" + +using ::rtl::OStringBuffer; +using ::rtl::OUString; +using ::com::sun::star::geometry::IntegerRectangle2D; +using ::oox::core::FilterBase; +using ::oox::drawingml::Color; +using ::oox::drawingml::FillProperties; +using ::oox::drawingml::LineArrowProperties; +using ::oox::drawingml::LineProperties; + +namespace oox { +namespace vml { + +// ============================================================================ + +namespace { + +bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& rValue ) +{ + // extract the double value and find start position of unit characters + rtl_math_ConversionStatus eConvStatus = rtl_math_ConversionStatus_Ok; + orfValue = ::rtl::math::stringToDouble( rValue, '.', '\0', &eConvStatus, &ornEndPos ); + return eConvStatus == rtl_math_ConversionStatus_Ok; +} + +} // namespace + +// ---------------------------------------------------------------------------- + +/*static*/ bool ConversionHelper::separatePair( OUString& orValue1, OUString& orValue2, + const OUString& rValue, sal_Unicode cSep ) +{ + sal_Int32 nSepPos = rValue.indexOf( cSep ); + if( nSepPos >= 0 ) + { + orValue1 = rValue.copy( 0, nSepPos ).trim(); + orValue2 = rValue.copy( nSepPos + 1 ).trim(); + } + else + { + orValue1 = rValue.trim(); + } + return (orValue1.getLength() > 0) && (orValue2.getLength() > 0); +} + +/*static*/ bool ConversionHelper::decodeBool( const OUString& rValue ) +{ + // anything else than 't' or 'true' is considered to be false, as specified + return ((rValue.getLength() == 1) && (rValue[ 0 ] == 't')) || (rValue == CREATE_OUSTRING( "true" )); +} + +/*static*/ double ConversionHelper::decodePercent( const OUString& rValue, double fDefValue ) +{ + if( rValue.getLength() == 0 ) + return fDefValue; + + double fValue = 0.0; + sal_Int32 nEndPos = 0; + if( !lclExtractDouble( fValue, nEndPos, rValue ) ) + return fDefValue; + + if( nEndPos == rValue.getLength() ) + return fValue; + + if( (nEndPos + 1 == rValue.getLength()) && (rValue[ nEndPos ] == '%') ) + return fValue / 100.0; + + OSL_ENSURE( false, "ConversionHelper::decodePercent - unknown measure unit" ); + return fDefValue; +} + +/*static*/ sal_Int32 ConversionHelper::decodeMeasureToEmu( const FilterBase& rFilter, + const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel ) +{ + // default for missing values is 0 + if( rValue.getLength() == 0 ) + return 0; + + // TODO: according to spec, value may contain "auto" + if( rValue.equalsAscii( "auto" ) ) + { + OSL_ENSURE( false, "ConversionHelper::decodeMeasureToEmu - special value 'auto' must be handled by caller" ); + return nRefValue; + } + + // extract the double value and find start position of unit characters + double fValue = 0.0; + sal_Int32 nEndPos = 0; + if( !lclExtractDouble( fValue, nEndPos, rValue ) || (fValue == 0.0) ) + return 0; + + // process trailing unit, convert to EMU + static const OUString saPx = CREATE_OUSTRING( "px" ); + OUString aUnit; + if( (0 < nEndPos) && (nEndPos < rValue.getLength()) ) + aUnit = rValue.copy( nEndPos ); + else if( bDefaultAsPixel ) + aUnit = saPx; + // else default is EMU + + if( aUnit.getLength() == 2 ) + { + sal_Unicode cChar1 = aUnit[ 0 ]; + sal_Unicode cChar2 = aUnit[ 1 ]; + if( (cChar1 == 'i') && (cChar2 == 'n') ) // 1 inch = 914,400 EMU + fValue *= 914400.0; + else if( (cChar1 == 'c') && (cChar2 == 'm') ) // 1 cm = 360,000 EMU + fValue *= 360000.0; + else if( (cChar1 == 'm') && (cChar2 == 'm') ) // 1 mm = 36,000 EMU + fValue *= 36000.0; + else if( (cChar1 == 'p') && (cChar2 == 't') ) // 1 point = 1/72 inch = 12,700 MEU + fValue *= 12700.0; + else if( (cChar1 == 'p') && (cChar2 == 'c') ) // 1 pica = 1/6 inch = 152,400 EMU + fValue *= 152400.0; + else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device, factor 360 to convert 1/100mm to EMU + fValue = bPixelX ? rFilter.convertScreenPixelX( 360.0 * fValue ) : rFilter.convertScreenPixelY( 360.0 * fValue ); + } + else if( (aUnit.getLength() == 1) && (aUnit[ 0 ] == '%') ) + { + fValue *= nRefValue / 100.0; + } + else if( bDefaultAsPixel || (aUnit.getLength() > 0) ) // default as EMU and no unit -> do nothing + { + OSL_ENSURE( false, "ConversionHelper::decodeMeasureToEmu - unknown measure unit" ); + fValue = nRefValue; + } + return static_cast< sal_Int32 >( fValue + 0.5 ); +} + +/*static*/ sal_Int32 ConversionHelper::decodeMeasureToHmm( const FilterBase& rFilter, + const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel ) +{ + return (decodeMeasureToEmu( rFilter, rValue, nRefValue, bPixelX, bDefaultAsPixel ) + 180) / 360; +} + +// ============================================================================ + +namespace { + +/** Converts a VML color attribute to a DrawingML color. + + @param orDmlColor (out-parameter) The destination DrawingML color. + + @param roVmlColor The VML string representation of the color. If existing, + this can be a 6-digit hexadecimal RGB value with leading '#' character, + a predefined color name (e.g. 'black', 'red', etc.), the index into an + application defined color palette in brackets with leading color name + (e.g. 'red [9]' or 'windowColor [64]'), or a color modifier used in + one-color gradients (e.g. 'fill darken(128)' or 'fill lighten(0)'. + + @param roVmlOpacity The opacity of the color. If existing, this should be + a floating-point value in the range [0.0;1.0]. + + @param nDefaultRgb Deafult RGB color used if the parameter roVmlColor is + empty. + + @param nPrimaryRgb If set to something else than API_RGB_TRANSPARENT, + specifies the color to be used to resolve the color modifiers used in + one-color gradients. + */ +void lclGetColor( Color& orDmlColor, const FilterBase& rFilter, + const OptValue< OUString >& roVmlColor, const OptValue< double >& roVmlOpacity, + sal_Int32 nDefaultRgb, sal_Int32 nPrimaryRgb = API_RGB_TRANSPARENT ) +{ + // convert opacity + const sal_Int32 DML_FULL_OPAQUE = ::oox::drawingml::MAX_PERCENT; + double fOpacity = roVmlOpacity.get( 1.0 ); + sal_Int32 nOpacity = getLimitedValue< sal_Int32, double >( fOpacity * DML_FULL_OPAQUE, 0, DML_FULL_OPAQUE ); + if( nOpacity < DML_FULL_OPAQUE ) + orDmlColor.addTransformation( XML_alpha, nOpacity ); + + // color attribute not present - set passed default color + if( !roVmlColor.has() ) + { + orDmlColor.setSrgbClr( nDefaultRgb ); + return; + } + + // separate leading color name or RGB value from following palette index + OUString aColorName, aColorIndex; + ConversionHelper::separatePair( aColorName, aColorIndex, roVmlColor.get(), ' ' ); + + // RGB colors in the format '#RRGGBB' + if( (aColorName.getLength() == 7) && (aColorName[ 0 ] == '#') ) + { + orDmlColor.setSrgbClr( aColorName.copy( 1 ).toInt32( 16 ) ); + return; + } + + // RGB colors in the format '#RGB' + if( (aColorName.getLength() == 4) && (aColorName[ 0 ] == '#') ) + { + sal_Int32 nR = aColorName.copy( 1, 1 ).toInt32( 16 ) * 0x11; + sal_Int32 nG = aColorName.copy( 2, 1 ).toInt32( 16 ) * 0x11; + sal_Int32 nB = aColorName.copy( 3, 1 ).toInt32( 16 ) * 0x11; + orDmlColor.setSrgbClr( (nR << 16) | (nG << 8) | nB ); + return; + } + + /* Predefined color names or system color names (resolve to RGB to detect + valid color name). */ + sal_Int32 nColorToken = StaticTokenMap::get().getTokenFromUnicode( aColorName ); + sal_Int32 nRgbValue = Color::getVmlPresetColor( nColorToken, API_RGB_TRANSPARENT ); + if( nRgbValue == API_RGB_TRANSPARENT ) + nRgbValue = rFilter.getSystemColor( nColorToken, API_RGB_TRANSPARENT ); + if( nRgbValue != API_RGB_TRANSPARENT ) + { + orDmlColor.setSrgbClr( nRgbValue ); + return; + } + + // try palette colors enclosed in brackets + if( (aColorIndex.getLength() >= 3) && (aColorIndex[ 0 ] == '[') && (aColorIndex[ aColorIndex.getLength() - 1 ] == ']') ) + { + orDmlColor.setPaletteClr( aColorIndex.copy( 1, aColorIndex.getLength() - 2 ).toInt32() ); + return; + } + + // try fill gradient modificator 'fill ()' + if( (nPrimaryRgb != API_RGB_TRANSPARENT) && (nColorToken == XML_fill) ) + { + sal_Int32 nOpenParen = aColorIndex.indexOf( '(' ); + sal_Int32 nCloseParen = aColorIndex.indexOf( ')' ); + if( (2 <= nOpenParen) && (nOpenParen + 1 < nCloseParen) && (nCloseParen + 1 == aColorIndex.getLength()) ) + { + sal_Int32 nModToken = XML_TOKEN_INVALID; + switch( StaticTokenMap::get().getTokenFromUnicode( aColorIndex.copy( 0, nOpenParen ) ) ) + { + case XML_darken: nModToken = XML_shade; + case XML_lighten: nModToken = XML_tint; + } + sal_Int32 nValue = aColorIndex.copy( nOpenParen + 1, nCloseParen - nOpenParen - 1 ).toInt32(); + if( (nModToken != XML_TOKEN_INVALID) && (0 <= nValue) && (nValue < 255) ) + { + /* Simulate this modifier color by a color with related transformation. + The modifier amount has to be converted from the range [0;255] to + percentage [0;100000] used by DrawingML. */ + orDmlColor.setSrgbClr( nPrimaryRgb ); + orDmlColor.addTransformation( nModToken, static_cast< sal_Int32 >( nValue * ::oox::drawingml::MAX_PERCENT / 255 ) ); + return; + } + } + } + + OSL_ENSURE( false, OStringBuffer( "lclGetColor - invalid VML color name '" ). + append( OUStringToOString( roVmlColor.get(), RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); + orDmlColor.setSrgbClr( nDefaultRgb ); +} + +sal_Int32 lclGetEmu( const FilterBase& rFilter, const OptValue< OUString >& roValue, sal_Int32 nDefValue ) +{ + return roValue.has() ? ConversionHelper::decodeMeasureToEmu( rFilter, roValue.get(), 0, false, false ) : nDefValue; +} + +void lclGetDmlLineDash( OptValue< sal_Int32 >& oroPresetDash, LineProperties::DashStopVector& orCustomDash, const OptValue< OUString >& roDashStyle ) +{ + if( roDashStyle.has() ) + { + const OUString& rDashStyle = roDashStyle.get(); + switch( StaticTokenMap::get().getTokenFromUnicode( rDashStyle ) ) + { + case XML_solid: oroPresetDash = XML_solid; return; + case XML_shortdot: oroPresetDash = XML_sysDot; return; + case XML_shortdash: oroPresetDash = XML_sysDash; return; + case XML_shortdashdot: oroPresetDash = XML_sysDashDot; return; + case XML_shortdashdotdot: oroPresetDash = XML_sysDashDotDot; return; + case XML_dot: oroPresetDash = XML_dot; return; + case XML_dash: oroPresetDash = XML_dash; return; + case XML_dashdot: oroPresetDash = XML_dashDot; return; + case XML_longdash: oroPresetDash = XML_lgDash; return; + case XML_longdashdot: oroPresetDash = XML_lgDashDot; return; + case XML_longdashdotdot: oroPresetDash = XML_lgDashDotDot; return; + + // try to convert user-defined dash style + default: + { + ::std::vector< sal_Int32 > aValues; + sal_Int32 nIndex = 0; + while( nIndex >= 0 ) + aValues.push_back( rDashStyle.getToken( 0, ' ', nIndex ).toInt32() ); + size_t nPairs = aValues.size() / 2; // ignore last value if size is odd + for( size_t nPairIdx = 0; nPairIdx < nPairs; ++nPairIdx ) + orCustomDash.push_back( LineProperties::DashStop( aValues[ 2 * nPairIdx ], aValues[ 2 * nPairIdx + 1 ] ) ); + } + } + } +} + +sal_Int32 lclGetDmlArrowType( const OptValue< sal_Int32 >& roArrowType ) +{ + if( roArrowType.has() ) switch( roArrowType.get() ) + { + case XML_none: return XML_none; + case XML_block: return XML_triangle; + case XML_classic: return XML_stealth; + case XML_diamond: return XML_diamond; + case XML_oval: return XML_oval; + case XML_open: return XML_arrow; + } + return XML_none; +} + +sal_Int32 lclGetDmlArrowWidth( const OptValue< sal_Int32 >& roArrowWidth ) +{ + if( roArrowWidth.has() ) switch( roArrowWidth.get() ) + { + case XML_narrow: return XML_sm; + case XML_medium: return XML_med; + case XML_wide: return XML_lg; + } + return XML_med; +} + +sal_Int32 lclGetDmlArrowLength( const OptValue< sal_Int32 >& roArrowLength ) +{ + if( roArrowLength.has() ) switch( roArrowLength.get() ) + { + case XML_short: return XML_sm; + case XML_medium: return XML_med; + case XML_long: return XML_lg; + } + return XML_med; +} + +void lclConvertArrow( LineArrowProperties& orArrowProp, const StrokeArrowModel& rStrokeArrow ) +{ + orArrowProp.moArrowType = lclGetDmlArrowType( rStrokeArrow.moArrowType ); + orArrowProp.moArrowWidth = lclGetDmlArrowWidth( rStrokeArrow.moArrowWidth ); + orArrowProp.moArrowLength = lclGetDmlArrowLength( rStrokeArrow.moArrowLength ); +} + +sal_Int32 lclGetDmlLineCompound( const OptValue< sal_Int32 >& roLineStyle ) +{ + if( roLineStyle.has() ) switch( roLineStyle.get() ) + { + case XML_single: return XML_sng; + case XML_thinThin: return XML_dbl; + case XML_thinThick: return XML_thinThick; + case XML_thickThin: return XML_thickThin; + case XML_thickBetweenThin: return XML_tri; + } + return XML_sng; +} + +sal_Int32 lclGetDmlLineCap( const OptValue< sal_Int32 >& roEndCap ) +{ + if( roEndCap.has() ) switch( roEndCap.get() ) + { + case XML_flat: return XML_flat; + case XML_square: return XML_sq; + case XML_round: return XML_rnd; + } + return XML_flat; // different defaults in VML (flat) and DrawingML (square) +} + +sal_Int32 lclGetDmlLineJoint( const OptValue< sal_Int32 >& roJoinStyle ) +{ + if( roJoinStyle.has() ) switch( roJoinStyle.get() ) + { + case XML_round: return XML_round; + case XML_bevel: return XML_bevel; + case XML_miter: return XML_miter; + } + return XML_round; +} + +} // namespace + +// ============================================================================ + +void StrokeArrowModel::assignUsed( const StrokeArrowModel& rSource ) +{ + moArrowType.assignIfUsed( rSource.moArrowType ); + moArrowWidth.assignIfUsed( rSource.moArrowWidth ); + moArrowLength.assignIfUsed( rSource.moArrowLength ); +} + +// ============================================================================ + +void StrokeModel::assignUsed( const StrokeModel& rSource ) +{ + moStroked.assignIfUsed( rSource.moStroked ); + maStartArrow.assignUsed( rSource.maStartArrow ); + maEndArrow.assignUsed( rSource.maEndArrow ); + moColor.assignIfUsed( rSource.moColor ); + moOpacity.assignIfUsed( rSource.moOpacity ); + moWeight.assignIfUsed( rSource.moWeight ); + moDashStyle.assignIfUsed( rSource.moDashStyle ); + moLineStyle.assignIfUsed( rSource.moLineStyle ); + moEndCap.assignIfUsed( rSource.moEndCap ); + moJoinStyle.assignIfUsed( rSource.moJoinStyle ); +} + +void StrokeModel::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter ) const +{ + /* Convert VML line formatting to DrawingML line formatting and let the + DrawingML code do the hard work. */ + LineProperties aLineProps; + + if( moStroked.get( true ) ) + { + aLineProps.maLineFill.moFillType = XML_solidFill; + lclConvertArrow( aLineProps.maStartArrow, maStartArrow ); + lclConvertArrow( aLineProps.maEndArrow, maEndArrow ); + lclGetColor( aLineProps.maLineFill.maFillColor, rFilter, moColor, moOpacity, API_RGB_BLACK ); + aLineProps.moLineWidth = lclGetEmu( rFilter, moWeight, 1 ); + lclGetDmlLineDash( aLineProps.moPresetDash, aLineProps.maCustomDash, moDashStyle ); + aLineProps.moLineCompound = lclGetDmlLineCompound( moLineStyle ); + aLineProps.moLineCap = lclGetDmlLineCap( moEndCap ); + aLineProps.moLineJoint = lclGetDmlLineJoint( moJoinStyle ); + } + else + { + aLineProps.maLineFill.moFillType = XML_noFill; + } + + aLineProps.pushToPropMap( rPropMap, rFilter, rFilter.getModelObjectHelper() ); +} + +// ============================================================================ + +void FillModel::assignUsed( const FillModel& rSource ) +{ + moFilled.assignIfUsed( rSource.moFilled ); + moColor.assignIfUsed( rSource.moColor ); + moOpacity.assignIfUsed( rSource.moOpacity ); + moColor2.assignIfUsed( rSource.moColor2 ); + moOpacity2.assignIfUsed( rSource.moOpacity2 ); + moType.assignIfUsed( rSource.moType ); + moAngle.assignIfUsed( rSource.moAngle ); + moFocus.assignIfUsed( rSource.moFocus ); + moFocusPos.assignIfUsed( rSource.moFocusPos ); + moFocusSize.assignIfUsed( rSource.moFocusSize ); + moRotate.assignIfUsed( rSource.moRotate ); +} + +void FillModel::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter ) const +{ + /* Convert VML fill formatting to DrawingML fill formatting and let the + DrawingML code do the hard work. */ + FillProperties aFillProps; + + if( moFilled.get( true ) ) + { + sal_Int32 nFillType = moType.get( XML_solid ); + switch( nFillType ) + { + case XML_gradient: + case XML_gradientRadial: + { + aFillProps.moFillType = XML_gradFill; + aFillProps.maGradientProps.moRotateWithShape = moRotate.get( false ); + double fFocus = moFocus.get( 0.0 ); + + // prepare colors + Color aColor1, aColor2; + lclGetColor( aColor1, rFilter, moColor, moOpacity, API_RGB_WHITE ); + lclGetColor( aColor2, rFilter, moColor2, moOpacity2, API_RGB_WHITE, aColor1.getColor( rFilter ) ); + + // type XML_gradient is linear or axial gradient + if( nFillType == XML_gradient ) + { + // normalize angle to range [0;360) degrees + sal_Int32 nVmlAngle = getIntervalValue< sal_Int32, sal_Int32 >( moAngle.get( 0 ), 0, 360 ); + + // focus of -50% or 50% is axial gradient + if( ((-0.75 <= fFocus) && (fFocus <= -0.25)) || ((0.25 <= fFocus) && (fFocus <= 0.75)) ) + { + /* According to spec, focus of 50% is outer-to-inner, + and -50% is inner-to-outer (color to color2). + BUT: For angles >= 180 deg., the behaviour is + reversed... that's not spec'ed of course. So, + [0;180) deg. and 50%, or [180;360) deg. and -50% is + outer-to-inner in fact. */ + bool bOuterToInner = (fFocus > 0.0) == (nVmlAngle < 180); + // simulate axial gradient by 3-step DrawingML gradient + const Color& rOuterColor = bOuterToInner ? aColor1 : aColor2; + const Color& rInnerColor = bOuterToInner ? aColor2 : aColor1; + aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aFillProps.maGradientProps.maGradientStops[ 1.0 ] = rOuterColor; + aFillProps.maGradientProps.maGradientStops[ 0.5 ] = rInnerColor; + } + else // focus of -100%, 0%, and 100% is linear gradient + { + /* According to spec, focus of -100% or 100% swaps the + start and stop colors, effectively reversing the + gradient. BUT: For angles >= 180 deg., the + behaviour is reversed. This means that in this case + a focus of 0% swaps the gradient. */ + if( ((fFocus < -0.75) || (fFocus > 0.75)) == (nVmlAngle < 180) ) + (nVmlAngle += 180) %= 360; + // set the start and stop colors + aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aColor1; + aFillProps.maGradientProps.maGradientStops[ 1.0 ] = aColor2; + } + + // VML counts counterclockwise from bottom, DrawingML clockwise from left + sal_Int32 nDmlAngle = (630 - nVmlAngle) % 360; + aFillProps.maGradientProps.moShadeAngle = nDmlAngle * ::oox::drawingml::PER_DEGREE; + } + else // XML_gradientRadial is rectangular gradient + { + aFillProps.maGradientProps.moGradientPath = XML_rect; + // convert VML focus position and size to DrawingML fill-to-rect + DoublePair aFocusPos = moFocusPos.get( DoublePair( 0.0, 0.0 ) ); + DoublePair aFocusSize = moFocusSize.get( DoublePair( 0.0, 0.0 ) ); + double fLeft = getLimitedValue< double, double >( aFocusPos.first, 0.0, 1.0 ); + double fTop = getLimitedValue< double, double >( aFocusPos.second, 0.0, 1.0 ); + double fRight = getLimitedValue< double, double >( fLeft + aFocusSize.first, fLeft, 1.0 ); + double fBottom = getLimitedValue< double, double >( fTop + aFocusSize.second, fTop, 1.0 ); + aFillProps.maGradientProps.moFillToRect = IntegerRectangle2D( + static_cast< sal_Int32 >( fLeft * ::oox::drawingml::MAX_PERCENT ), + static_cast< sal_Int32 >( fTop * ::oox::drawingml::MAX_PERCENT ), + static_cast< sal_Int32 >( (1.0 - fRight) * ::oox::drawingml::MAX_PERCENT ), + static_cast< sal_Int32 >( (1.0 - fBottom) * ::oox::drawingml::MAX_PERCENT ) ); + + // set the start and stop colors (focus of 0% means outer-to-inner) + bool bOuterToInner = (-0.5 <= fFocus) && (fFocus <= 0.5); + aFillProps.maGradientProps.maGradientStops[ 0.0 ] = bOuterToInner ? aColor2 : aColor1; + aFillProps.maGradientProps.maGradientStops[ 1.0 ] = bOuterToInner ? aColor1 : aColor2; + } + } + break; + + case XML_solid: + default: + { + aFillProps.moFillType = XML_solidFill; + // fill color (default is white) + lclGetColor( aFillProps.maFillColor, rFilter, moColor, moOpacity, API_RGB_WHITE ); + } + } + } + else + { + aFillProps.moFillType = XML_noFill; + } + + aFillProps.pushToPropMap( rPropMap, rFilter, rFilter.getModelObjectHelper() ); +} + +// ============================================================================ + +} // namespace vml +} // namespace oox + diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index d586196acee4..fe07172599a9 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -75,57 +74,6 @@ namespace vml { namespace { -sal_Int32 lclGetMeasure( const XmlFilterBase& /*rFilter*/, const OUString& rValue, sal_Int32 nRefValue ) -{ - // default for missing values is 0 - if( rValue.getLength() == 0 ) - return 0; - - // TODO: according to spec, value may contain "auto" - if( rValue.equalsAscii( "auto" ) ) - return nRefValue; - - // extract the double value and find start position of unit characters - rtl_math_ConversionStatus eConvStatus = rtl_math_ConversionStatus_Ok; - sal_Int32 nEndPos = 0; - double fValue = ::rtl::math::stringToDouble( rValue, '.', '\0', &eConvStatus, &nEndPos ); - if( (eConvStatus != rtl_math_ConversionStatus_Ok) || (fValue == 0.0) ) - return 0; - - // process trailing unit, convert to 1/100 mm - static const OUString saPx = CREATE_OUSTRING( "px" ); - OUString aUnit = ((0 < nEndPos) && (nEndPos < rValue.getLength())) ? rValue.copy( nEndPos ) : saPx; - if( aUnit.getLength() == 2 ) - { - sal_Unicode cChar1 = aUnit[ 0 ]; - sal_Unicode cChar2 = aUnit[ 1 ]; - if( (cChar1 == 'i') && (cChar2 == 'n') ) // 1 inch = 2540 1/100mm - fValue *= 2540.0; - else if( (cChar1 == 'c') && (cChar2 == 'm') ) // 1 cm = 1000 1/100mm - fValue *= 1000.0; - else if( (cChar1 == 'm') && (cChar2 == 'm') ) // 1 mm = 100 1/100mm - fValue *= 100.0; - else if( (cChar1 == 'p') && (cChar2 == 't') ) // 1 point = 1/72 inch - fValue *= 2540.0 / 72.0; - else if( (cChar1 == 'p') && (cChar2 == 'c') ) // 1 pica = 1/6 inch - fValue *= 2540.0 / 6.0; - else if( (cChar1 == 'e') && (cChar2 == 'm') ) // relative to refvalue - fValue *= nRefValue; - else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device - fValue *= 1.0; - } - else if( (aUnit.getLength() == 1) && (aUnit[ 0 ] == '%') ) - { - fValue *= nRefValue / 100.0; - } - else - { - OSL_ENSURE( false, "lclGetMeasure - unknown measure unit" ); - fValue = nRefValue; - } - return static_cast< sal_Int32 >( fValue + 0.5 ); -} - Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys ) { double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width; @@ -164,7 +112,7 @@ Reference< XShape > lclCreateXShape( const XmlFilterBase& rFilter, const OUStrin return xShape; } -void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XShape >& rxShape, const Rectangle& rShapeRect ) +void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XShape >& rxShape ) { OSL_ENSURE( rxShapes.is(), "lclInsertXShape - missing XShapes container" ); OSL_ENSURE( rxShape.is(), "lclInsertXShape - missing XShape" ); @@ -172,20 +120,28 @@ void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XSh { // insert shape into passed shape collection (maybe drawpage or group shape) rxShapes->add( rxShape ); - // set position/size - rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); - rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); } catch( Exception& ) { } } +void lclSetXShapeRect( const Reference< XShape >& rxShape, const Rectangle& rShapeRect ) +{ + OSL_ENSURE( rxShape.is(), "lclSetXShapeRect - missing XShape" ); + if( rxShape.is() ) + { + rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); + rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); + } +} + Reference< XShape > lclCreateAndInsertXShape( const XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes, const OUString& rService, const Rectangle& rShapeRect ) { Reference< XShape > xShape = lclCreateXShape( rFilter, rService ); - lclInsertXShape( rxShapes, xShape, rShapeRect ); + lclInsertXShape( rxShapes, xShape ); + lclSetXShapeRect( xShape, rShapeRect ); return xShape; } @@ -199,17 +155,13 @@ ShapeTypeModel::ShapeTypeModel() void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource ) { - monShapeType.assignIfUsed( rSource.monShapeType ); - monCoordLeft.assignIfUsed( rSource.monCoordLeft ); - monCoordTop.assignIfUsed( rSource.monCoordTop ); - monCoordWidth.assignIfUsed( rSource.monCoordWidth ); - monCoordHeight.assignIfUsed( rSource.monCoordHeight ); + moShapeType.assignIfUsed( rSource.moShapeType ); + moCoordPos.assignIfUsed( rSource.moCoordPos ); + moCoordSize.assignIfUsed( rSource.moCoordSize ); /* The style properties position, left, top, width, height, margin-left, margin-top are not derived from shape template to shape. */ - mobStroked.assignIfUsed( rSource.mobStroked ); - moStrokeColor.assignIfUsed( rSource.moStrokeColor ); - mobFilled.assignIfUsed( rSource.mobFilled ); - moFillColor.assignIfUsed( rSource.moFillColor ); + maStrokeModel.assignUsed( rSource.maStrokeModel ); + maFillModel.assignUsed( rSource.maFillModel ); moGraphicPath.assignIfUsed( rSource.moGraphicPath ); moGraphicTitle.assignIfUsed( rSource.moGraphicTitle ); } @@ -232,11 +184,9 @@ OUString ShapeType::getGraphicPath() const Rectangle ShapeType::getCoordSystem() const { - return Rectangle( - maTypeModel.monCoordLeft.get( 0 ), - maTypeModel.monCoordTop.get( 0 ), - maTypeModel.monCoordWidth.get( 1000 ), - maTypeModel.monCoordHeight.get( 1000 ) ); + Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) ); + Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) ); + return Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second ); } Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const @@ -250,10 +200,10 @@ Rectangle ShapeType::getAbsRectangle() const { const XmlFilterBase& rFilter = mrDrawing.getFilter(); return Rectangle( - lclGetMeasure( rFilter, maTypeModel.maLeft, 0 ) + lclGetMeasure( rFilter, maTypeModel.maMarginLeft, 0 ), - lclGetMeasure( rFilter, maTypeModel.maTop, 0 ) + lclGetMeasure( rFilter, maTypeModel.maMarginTop, 0 ), - lclGetMeasure( rFilter, maTypeModel.maWidth, 0 ), - lclGetMeasure( rFilter, maTypeModel.maHeight, 0 ) ); + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maLeft, 0, true, true ) + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maMarginLeft, 0, true, true ), + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maMarginTop, 0, false, true ), + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maWidth, 0, true, true ), + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maHeight, 0, false, true ) ); } Rectangle ShapeType::getRelRectangle() const @@ -269,7 +219,10 @@ Rectangle ShapeType::getRelRectangle() const ShapeClientData::ShapeClientData() : mnObjType( XML_TOKEN_INVALID ), - mbPrintObject( true ) + mnCol( -1 ), + mnRow( -1 ), + mbPrintObject( true ), + mbVisible( false ) { } @@ -313,27 +266,55 @@ const ShapeBase* ShapeBase::getChildById( const OUString& ) const Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const { Reference< XShape > xShape; + if( mrDrawing.isShapeSupported( *this ) ) + { + /* Calculate shape rectangle. Applications may do something special + according to some imported shape client data (e.g. Excel cell anchor). */ + Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); + // convert the shape, if the calculated rectangle is not empty + if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) + xShape = implConvertAndInsert( rxShapes, aShapeRect ); + } + return xShape; +} + +void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const +{ + if( rxShape.is() ) + { + /* Calculate shape rectangle. Applications may do something special + according to some imported shape client data (e.g. Excel cell anchor). */ + Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); + // convert the shape, if the calculated rectangle is not empty + if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) ) + { + lclSetXShapeRect( rxShape, aShapeRect ); + convertShapeProperties( rxShape ); + } + } +} + +// protected ------------------------------------------------------------------ + +Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const +{ /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ Rectangle aShapeRect; if( !maShapeModel.mxClientData.get() || !mrDrawing.convertShapeClientAnchor( aShapeRect, maShapeModel.mxClientData->maAnchor ) ) aShapeRect = getRectangle( pParentAnchor ); - // convert the shape, if the calculated rectangle is not empty - if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) - xShape = implConvertAndInsert( rxShapes, aShapeRect ); - return xShape; + return aShapeRect; } -// protected ------------------------------------------------------------------ - void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const { - // shape properties - PropertySet aPropSet( rxShape ); + PropertyMap aPropMap; - // fill style - bool bFilled = maTypeModel.mobFilled.get( true ); - aPropSet.setProperty( PROP_FillStyle, bFilled ? ::com::sun::star::drawing::FillStyle_SOLID : ::com::sun::star::drawing::FillStyle_NONE ); + maTypeModel.maStrokeModel.pushToPropMap( aPropMap, mrDrawing.getFilter() ); + maTypeModel.maFillModel.pushToPropMap( aPropMap, mrDrawing.getFilter() ); + + PropertySet aPropSet( rxShape ); + aPropSet.setProperties( aPropMap ); } // ============================================================================ @@ -405,7 +386,7 @@ Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes { // create the custom shape geometry Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW ); - xDefaulter->createCustomShapeDefaults( OUString::valueOf( maTypeModel.monShapeType.get( 0 ) ) ); + xDefaulter->createCustomShapeDefaults( OUString::valueOf( maTypeModel.moShapeType.get( 0 ) ) ); // convert common properties convertShapeProperties( xShape ); } @@ -537,21 +518,27 @@ const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - Reference< XShape > xShape; + Reference< XShape > xGroupShape; // check that this shape contains children and a valid coordinate system ShapeParentAnchor aParentAnchor; aParentAnchor.maShapeRect = rShapeRect; aParentAnchor.maCoordSys = getCoordSystem(); if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try { - xShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rShapeRect ); - Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW ); - mxChildren->convertAndInsert( xShapes, &aParentAnchor ); + xGroupShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rShapeRect ); + Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW ); + mxChildren->convertAndInsert( xChildShapes, &aParentAnchor ); + // no child shape has been created - delete the group shape + if( !xChildShapes->hasElements() ) + { + rxShapes->remove( xGroupShape ); + xGroupShape.clear(); + } } catch( Exception& ) { } - return xShape; + return xGroupShape; } // ============================================================================ diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index dcf842a67a8f..725af97777c3 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -45,19 +45,62 @@ namespace vml { namespace { -bool lclSeparateValue( OUString& orName, OUString& orValue, const OUString& rAttrib, sal_Unicode cSep = ':' ) +/** Returns the boolean value from the specified VML attribute (if present). + */ +OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nElement ) { - sal_Int32 nSepPos = rAttrib.indexOf( cSep ); - if( nSepPos <= 0 ) return false; - orName = rAttrib.copy( 0, nSepPos ).trim(); - orValue = rAttrib.copy( nSepPos + 1 ).trim(); - return (orName.getLength() > 0) && (orValue.getLength() > 0); + OptValue< OUString > oValue = rAttribs.getString( nElement ); + if( oValue.has() ) return OptValue< bool >( ConversionHelper::decodeBool( oValue.get() ) ); + return OptValue< bool >(); } -/** Returns the boolean value from the passed string (supported: f, t, False, True). +/** Returns the percentage value from the specified VML attribute (if present). + The value will be normalized (1.0 is returned for 100%). + */ +OptValue< double > lclDecodePercent( const AttributeList& rAttribs, sal_Int32 nElement, double fDefValue ) +{ + OptValue< OUString > oValue = rAttribs.getString( nElement ); + if( oValue.has() ) return OptValue< double >( ConversionHelper::decodePercent( oValue.get(), fDefValue ) ); + return OptValue< double >(); +} + +/** Returns the integer value pair from the specified VML attribute (if present). + */ +OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int32 nElement ) +{ + OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< Int32Pair > oRetValue; + if( oValue.has() ) + { + OUString aValue1, aValue2; + ConversionHelper::separatePair( aValue1, aValue2, oValue.get(), ',' ); + oRetValue = Int32Pair( aValue1.toInt32(), aValue2.toInt32() ); + } + return oRetValue; +} + +/** Returns the percentage pair from the specified VML attribute (if present). + */ +OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_Int32 nElement ) +{ + OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< DoublePair > oRetValue; + if( oValue.has() ) + { + OUString aValue1, aValue2; + ConversionHelper::separatePair( aValue1, aValue2, oValue.get(), ',' ); + oRetValue = DoublePair( + ConversionHelper::decodePercent( aValue1, 0.0 ), + ConversionHelper::decodePercent( aValue2, 0.0 ) ); + } + return oRetValue; +} + +/** Returns the boolean value from the passed string of an attribute in the x: + namespace (VML for spreadsheets). Supported values: f, t, False, True. @param bDefaultForEmpty Default value for the empty string. */ -bool lclDecodeBool( const OUString& rValue, bool bDefaultForEmpty ) +bool lclDecodeVmlxBool( const OUString& rValue, bool bDefaultForEmpty ) { if( rValue.getLength() == 0 ) return bDefaultForEmpty; // anything else than 't' or 'True' is considered to be false, as specified @@ -85,11 +128,14 @@ void ShapeClientDataContext::onEndElement( const OUString& rChars ) { switch( getCurrentElement() ) { - case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = rChars; break; - case VMLX_TOKEN( FmlaLink ): mrClientData.maLinkedCell = rChars; break; - case VMLX_TOKEN( FmlaPict ): mrClientData.maPictureLink = rChars; break; - case VMLX_TOKEN( FmlaRange ): mrClientData.maSourceRange = rChars; break; - case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeBool( rChars, true ); break; + case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = rChars; break; + case VMLX_TOKEN( FmlaPict ): mrClientData.maPictureLink = rChars; break; + case VMLX_TOKEN( FmlaLink ): mrClientData.maLinkedCell = rChars; break; + case VMLX_TOKEN( FmlaRange ): mrClientData.maSourceRange = rChars; break; + case VMLX_TOKEN( Column ): mrClientData.mnCol = rChars.toInt32(); break; + case VMLX_TOKEN( Row ): mrClientData.mnRow = rChars.toInt32(); break; + case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeVmlxBool( rChars, true ); break; + case VMLX_TOKEN( Visible ): mrClientData.mbVisible = true; break; } } @@ -100,7 +146,7 @@ ShapeContextBase::ShapeContextBase( ContextHandler2Helper& rParent ) : { } -/*static*/ ContextHandlerRef ShapeContextBase::createContext( ContextHandler2Helper& rParent, +/*static*/ ContextHandlerRef ShapeContextBase::createShapeContext( ContextHandler2Helper& rParent, sal_Int32 nElement, const AttributeList& rAttribs, ShapeContainer& rShapes ) { switch( nElement ) @@ -144,24 +190,56 @@ ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, const Attrib if( bHasOspid ) mrTypeModel.maName = rAttribs.getXString( XML_id, OUString() ); // builtin shape type identifier - mrTypeModel.monShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); - // coordinate system position/size - setCoordOrigin( rAttribs.getString( XML_coordorigin, OUString() ) ); - setCoordSize( rAttribs.getString( XML_coordsize, OUString() ) ); - // CSS style + mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); + + // coordinate system position/size, CSS style + mrTypeModel.moCoordPos = lclDecodeInt32Pair( rAttribs, XML_coordorigin ); + mrTypeModel.moCoordSize = lclDecodeInt32Pair( rAttribs, XML_coordsize ); setStyle( rAttribs.getString( XML_style, OUString() ) ); - // border line - mrTypeModel.mobStroked = rAttribs.getBool( XML_stroked ); - mrTypeModel.moStrokeColor = rAttribs.getString( XML_strokecolor ); - // shape fill - mrTypeModel.mobFilled = rAttribs.getBool( XML_filled ); - mrTypeModel.moFillColor = rAttribs.getString( XML_fillcolor ); + + // stroke settings (may be overridden by v:stroke element later) + mrTypeModel.maStrokeModel.moStroked = lclDecodeBool( rAttribs, XML_stroked ); + mrTypeModel.maStrokeModel.moColor = rAttribs.getString( XML_strokecolor ); + mrTypeModel.maStrokeModel.moWeight = rAttribs.getString( XML_strokeweight ); + + // fill settings (may be overridden by v:fill element later) + mrTypeModel.maFillModel.moFilled = lclDecodeBool( rAttribs, XML_filled ); + mrTypeModel.maFillModel.moColor = rAttribs.getString( XML_fillcolor ); } ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { if( isRootElement() ) switch( nElement ) { + case VML_TOKEN( stroke ): + mrTypeModel.maStrokeModel.moStroked.assignIfUsed( lclDecodeBool( rAttribs, XML_on ) ); + mrTypeModel.maStrokeModel.maStartArrow.moArrowType = rAttribs.getToken( XML_startarrow ); + mrTypeModel.maStrokeModel.maStartArrow.moArrowWidth = rAttribs.getToken( XML_startarrowwidth ); + mrTypeModel.maStrokeModel.maStartArrow.moArrowLength = rAttribs.getToken( XML_startarrowlength ); + mrTypeModel.maStrokeModel.maEndArrow.moArrowType = rAttribs.getToken( XML_endarrow ); + mrTypeModel.maStrokeModel.maEndArrow.moArrowWidth = rAttribs.getToken( XML_endarrowwidth ); + mrTypeModel.maStrokeModel.maEndArrow.moArrowLength = rAttribs.getToken( XML_endarrowlength ); + mrTypeModel.maStrokeModel.moColor.assignIfUsed( rAttribs.getString( XML_color ) ); + mrTypeModel.maStrokeModel.moOpacity = lclDecodePercent( rAttribs, XML_opacity, 1.0 ); + mrTypeModel.maStrokeModel.moWeight.assignIfUsed( rAttribs.getString( XML_weight ) ); + mrTypeModel.maStrokeModel.moDashStyle = rAttribs.getString( XML_dashstyle ); + mrTypeModel.maStrokeModel.moLineStyle = rAttribs.getToken( XML_linestyle ); + mrTypeModel.maStrokeModel.moEndCap = rAttribs.getToken( XML_endcap ); + mrTypeModel.maStrokeModel.moJoinStyle = rAttribs.getToken( XML_joinstyle ); + break; + case VML_TOKEN( fill ): + mrTypeModel.maFillModel.moFilled.assignIfUsed( lclDecodeBool( rAttribs, XML_on ) ); + mrTypeModel.maFillModel.moColor.assignIfUsed( rAttribs.getString( XML_color ) ); + mrTypeModel.maFillModel.moOpacity = lclDecodePercent( rAttribs, XML_opacity, 1.0 ); + mrTypeModel.maFillModel.moColor2 = rAttribs.getString( XML_color2 ); + mrTypeModel.maFillModel.moOpacity2 = lclDecodePercent( rAttribs, XML_opacity2, 1.0 ); + mrTypeModel.maFillModel.moType = rAttribs.getToken( XML_type ); + mrTypeModel.maFillModel.moAngle = rAttribs.getInteger( XML_angle ); + mrTypeModel.maFillModel.moFocus = lclDecodePercent( rAttribs, XML_focus, 0.0 ); + mrTypeModel.maFillModel.moFocusPos = lclDecodePercentPair( rAttribs, XML_focusposition ); + mrTypeModel.maFillModel.moFocusSize = lclDecodePercentPair( rAttribs, XML_focussize ); + mrTypeModel.maFillModel.moRotate = lclDecodeBool( rAttribs, XML_rotate ); + break; case VML_TOKEN( imagedata ): OptValue< OUString > oGraphicRelId = rAttribs.getString( O_TOKEN( relid ) ); if( oGraphicRelId.has() ) @@ -172,33 +250,13 @@ ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const A return 0; } -void ShapeTypeContext::setCoordOrigin( const OUString& rCoordOrigin ) -{ - OUString aCoordL, aCoordT; - if( lclSeparateValue( aCoordL, aCoordT, rCoordOrigin, ',' ) ) - { - mrTypeModel.monCoordLeft = aCoordL.toInt32(); - mrTypeModel.monCoordTop = aCoordT.toInt32(); - } -} - -void ShapeTypeContext::setCoordSize( const OUString& rCoordSize ) -{ - OUString aCoordW, aCoordH; - if( lclSeparateValue( aCoordW, aCoordH, rCoordSize, ',' ) ) - { - mrTypeModel.monCoordWidth = aCoordW.toInt32(); - mrTypeModel.monCoordHeight = aCoordH.toInt32(); - } -} - void ShapeTypeContext::setStyle( const OUString& rStyle ) { sal_Int32 nIndex = 0; while( nIndex >= 0 ) { OUString aName, aValue; - if( lclSeparateValue( aName, aValue, rStyle.getToken( 0, ';', nIndex ) ) ) + if( ConversionHelper::separatePair( aName, aValue, rStyle.getToken( 0, ';', nIndex ), ':' ) ) { if( aName.equalsAscii( "position" ) ) mrTypeModel.maPosition = aValue; else if( aName.equalsAscii( "left" ) ) mrTypeModel.maLeft = aValue; @@ -255,7 +313,7 @@ GroupShapeContext::GroupShapeContext( ContextHandler2Helper& rParent, const Attr ContextHandlerRef GroupShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { // try to create a context of an embedded shape - ContextHandlerRef xContext = ShapeContextBase::createContext( *this, nElement, rAttribs, mrShapes ); + ContextHandlerRef xContext = createShapeContext( *this, nElement, rAttribs, mrShapes ); // handle remaining stuff of this shape in base class return xContext.get() ? xContext : ShapeContext::onCreateContext( nElement, rAttribs ); } diff --git a/oox/source/xls/chartsheetfragment.cxx b/oox/source/xls/chartsheetfragment.cxx index 3df5ff9c3e2a..7e5b9198c1da 100644 --- a/oox/source/xls/chartsheetfragment.cxx +++ b/oox/source/xls/chartsheetfragment.cxx @@ -47,7 +47,7 @@ namespace xls { // ============================================================================ OoxChartsheetFragment::OoxChartsheetFragment( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, sal_Int32 nSheet ) : + const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, sal_Int16 nSheet ) : OoxWorksheetFragmentBase( rHelper, rFragmentPath, xProgressBar, SHEETTYPE_CHARTSHEET, nSheet ) { } @@ -185,7 +185,7 @@ void OoxChartsheetFragment::importDrawing( RecordInputStream& rStrm ) // ============================================================================ BiffChartsheetFragment::BiffChartsheetFragment( const BiffWorkbookFragmentBase& rParent, - ISegmentProgressBarRef xProgressBar, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, sal_Int16 nSheet ) : BiffWorksheetFragmentBase( rParent, xProgressBar, SHEETTYPE_CHARTSHEET, nSheet ) { } diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index 1f725bfd7fbc..c8f11d55154e 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -33,22 +33,24 @@ #include #include #include -#include #include "oox/helper/attributelist.hxx" #include "oox/helper/recordinputstream.hxx" +#include "oox/vml/vmlshape.hxx" #include "oox/xls/addressconverter.hxx" +#include "oox/xls/drawingfragment.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::drawing::XShape; using ::com::sun::star::table::CellAddress; +using ::com::sun::star::sheet::XSheetAnnotation; using ::com::sun::star::sheet::XSheetAnnotationAnchor; using ::com::sun::star::sheet::XSheetAnnotationShapeSupplier; using ::com::sun::star::sheet::XSheetAnnotations; using ::com::sun::star::sheet::XSheetAnnotationsSupplier; -using ::com::sun::star::text::XText; namespace oox { namespace xls { @@ -98,16 +100,29 @@ void Comment::finalizeImport() if( getAddressConverter().checkCellAddress( aNotePos, true ) && maModel.mxText.get() ) try { maModel.mxText->finalizeImport(); - Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); - Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); - // create note with dummy non-empty string (required by implementation) - xAnnos->insertNew( aNotePos, OUString( sal_Unicode( ' ' ) ) ); - // receive craeted note from cell (insertNew does not return the note) -// Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); -// Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnnoAnchor->getAnnotation(), UNO_QUERY_THROW ); -// Reference< XText > xNoteText( xAnnoShapeSupp->getAnnotationShape(), UNO_QUERY_THROW ); -// xNoteText->setString( OUString() ); -// maModel.mxText->convert( xNoteText, -1 ); + OUString aNoteText = maModel.mxText->getPlainText(); + // non-empty string required by note implementation + if( aNoteText.getLength() > 0 ) + { + Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); + Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); + xAnnos->insertNew( aNotePos, aNoteText ); + // receive craeted note from cell (insertNew does not return the note) + Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); + Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); + Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); + Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); + // convert shape formatting + if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) + { + // position and formatting + pNoteShape->convertFormatting( xAnnoShape ); + // visibility + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; + bool bVisible = rxClientData.get() && rxClientData->mbVisible; + xAnno->setIsVisible( bVisible ); + } + } } catch( Exception& ) { diff --git a/oox/source/xls/defnamesbuffer.cxx b/oox/source/xls/defnamesbuffer.cxx index 786d0cd41334..b2c724b6728d 100644 --- a/oox/source/xls/defnamesbuffer.cxx +++ b/oox/source/xls/defnamesbuffer.cxx @@ -31,6 +31,7 @@ #include "oox/xls/defnamesbuffer.hxx" #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include "oox/xls/biffinputstream.hxx" #include "oox/xls/externallinkbuffer.hxx" #include "oox/xls/formulaparser.hxx" +#include "oox/xls/worksheetbuffer.hxx" using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -52,10 +54,10 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::table::CellAddress; using ::com::sun::star::table::CellRangeAddress; using ::com::sun::star::sheet::ComplexReference; +using ::com::sun::star::sheet::ExternalReference; using ::com::sun::star::sheet::SingleReference; using ::com::sun::star::sheet::XFormulaTokens; using ::com::sun::star::sheet::XPrintAreas; -using namespace ::com::sun::star::sheet::ReferenceFlags; namespace oox { namespace xls { @@ -205,6 +207,7 @@ void lclConvertRefFlags( sal_Int32& ornFlags, sal_Int32& ornAbsPos, sal_Int32& o void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBaseAddress, bool bColRel, bool bRowRel ) { + using namespace ::com::sun::star::sheet::ReferenceFlags; lclConvertRefFlags( orApiRef.Flags, orApiRef.Column, orApiRef.RelativeColumn, rBaseAddress.Column, COLUMN_RELATIVE, bColRel ); @@ -213,14 +216,33 @@ void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBa rBaseAddress.Row, ROW_RELATIVE, bRowRel ); } +Any lclConvertReference( const Any& rRefAny, const CellAddress& rBaseAddress, sal_uInt16 nRelFlags ) +{ + if( rRefAny.has< SingleReference >() && !getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ) && !getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) ) + { + SingleReference aApiRef; + rRefAny >>= aApiRef; + lclConvertSingleRefFlags( aApiRef, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); + return Any( aApiRef ); + } + if( rRefAny.has< ComplexReference >() ) + { + ComplexReference aApiRef; + rRefAny >>= aApiRef; + lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); + lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) ); + return Any( aApiRef ); + } + return Any(); +} + } // namespace // ---------------------------------------------------------------------------- -DefinedNameBase::DefinedNameBase( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ) : +DefinedNameBase::DefinedNameBase( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ) { - maModel.mnSheet = nLocalSheet; } const OUString& DefinedNameBase::getUpcaseModelName() const @@ -237,62 +259,63 @@ Any DefinedNameBase::getReference( const CellAddress& rBaseAddress ) const sal_Unicode cFlagsChar = getUpcaseModelName()[ 1 ]; if( ('A' <= cFlagsChar) && (cFlagsChar <= 'P') ) { - sal_uInt16 nFlags = static_cast< sal_uInt16 >( cFlagsChar - 'A' ); - if( maRefAny.has< SingleReference >() && (cFlagsChar <= 'D') ) + sal_uInt16 nRelFlags = static_cast< sal_uInt16 >( cFlagsChar - 'A' ); + if( maRefAny.has< ExternalReference >() ) { - SingleReference aApiRef; - maRefAny >>= aApiRef; - lclConvertSingleRefFlags( aApiRef, rBaseAddress, getFlag( nFlags, BIFF_REFFLAG_COL1REL ), getFlag( nFlags, BIFF_REFFLAG_ROW1REL ) ); - return Any( aApiRef ); + ExternalReference aApiExtRef; + maRefAny >>= aApiExtRef; + Any aRefAny = lclConvertReference( aApiExtRef.Reference, rBaseAddress, nRelFlags ); + if( aRefAny.hasValue() ) + { + aApiExtRef.Reference <<= aRefAny; + return Any( aApiExtRef ); + } } - if( maRefAny.has< ComplexReference >() ) + else { - ComplexReference aApiRef; - maRefAny >>= aApiRef; - lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddress, getFlag( nFlags, BIFF_REFFLAG_COL1REL ), getFlag( nFlags, BIFF_REFFLAG_ROW1REL ) ); - lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddress, getFlag( nFlags, BIFF_REFFLAG_COL2REL ), getFlag( nFlags, BIFF_REFFLAG_ROW2REL ) ); - return Any( aApiRef ); + return lclConvertReference( maRefAny, rBaseAddress, nRelFlags ); } } } return Any(); } -void DefinedNameBase::importOoxFormula( FormulaContext& rContext ) +void DefinedNameBase::importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet ) { if( maModel.maFormula.getLength() > 0 ) { - rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maModel.mnSheet ), 0, 0 ) ); + rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); getFormulaParser().importFormula( rContext, maModel.maFormula ); } else getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME ); } -void DefinedNameBase::importOobFormula( FormulaContext& rContext, RecordInputStream& rStrm ) +void DefinedNameBase::importOobFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, RecordInputStream& rStrm ) { - rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maModel.mnSheet ), 0, 0 ) ); + rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); getFormulaParser().importFormula( rContext, rStrm ); } -void DefinedNameBase::importBiffFormula( FormulaContext& rContext, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) +void DefinedNameBase::importBiffFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) { - rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maModel.mnSheet ), 0, 0 ) ); + rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); if( !pnFmlaSize || (*pnFmlaSize > 0) ) getFormulaParser().importFormula( rContext, rStrm, pnFmlaSize ); else getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME ); } -void DefinedNameBase::setReference( const ApiTokenSequence& rTokens ) +void DefinedNameBase::extractReference( const ApiTokenSequence& rTokens ) { + OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "DefinedNameBase::extractReference - unexpected call" ); maRefAny = getFormulaParser().extractReference( rTokens ); } // ============================================================================ -DefinedName::DefinedName( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ) : - DefinedNameBase( rHelper, nLocalSheet ), +DefinedName::DefinedName( const WorkbookHelper& rHelper ) : + DefinedNameBase( rHelper ), mnTokenIndex( -1 ), mcBuiltinId( OOX_DEFNAME_UNKNOWN ), mnFmlaSize( 0 ) @@ -309,6 +332,7 @@ void DefinedName::importDefinedName( const AttributeList& rAttribs ) maModel.mbVBName = rAttribs.getBool( XML_vbProcedure, false ); maModel.mbHidden = rAttribs.getBool( XML_hidden, false ); mcBuiltinId = lclGetBuiltinIdFromOox( maModel.maName ); + mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1; } void DefinedName::setFormula( const OUString& rFormula ) @@ -322,6 +346,7 @@ void DefinedName::importDefinedName( RecordInputStream& rStrm ) rStrm >> nFlags; rStrm.skip( 1 ); // keyboard shortcut rStrm >> maModel.mnSheet >> maModel.maName; + mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1; // macro function/command, hidden flag maModel.mnFuncGroupId = extractValue< sal_Int32 >( nFlags, 6, 9 ); @@ -351,7 +376,7 @@ void DefinedName::importDefinedName( RecordInputStream& rStrm ) } } -void DefinedName::importDefinedName( BiffInputStream& rStrm ) +void DefinedName::importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet ) { BiffType eBiff = getBiff(); sal_uInt16 nFlags = 0; @@ -421,26 +446,45 @@ void DefinedName::importDefinedName( BiffInputStream& rStrm ) case BIFF2: case BIFF3: case BIFF4: + // BIFF2-BIFF4: all defined names are sheet-local + mnCalcSheet = nCalcSheet; break; case BIFF5: // #i44019# nTabId may be invalid, resolve nRefId to sheet index if( nRefId != BIFF_DEFNAME_GLOBAL ) if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() ) if( pExtLink->getLinkType() == LINKTYPE_INTERNAL ) - maModel.mnSheet = pExtLink->getSheetIndex(); + mnCalcSheet = pExtLink->getCalcSheetIndex(); break; case BIFF8: - // convert one-based sheet index to zero-based + // convert one-based worksheet index to zero-based Calc sheet index OSL_ENSURE( nTabId >= 0, "DefinedName::importDefinedName - invalid local sheet index" ); if( nTabId != BIFF_DEFNAME_GLOBAL ) - maModel.mnSheet = nTabId - 1; + mnCalcSheet = getWorksheets().getCalcSheetIndex( nTabId - 1 ); break; case BIFF_UNKNOWN: break; } - // store record position to be able to import token array later - mxBiffStrm.reset( new BiffInputStreamPos( rStrm ) ); + if( (getBiff() <= BIFF4) && maModel.mbHidden && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') ) + { + /* Read the token array of special internal names containing addresses + for BIFF3-BIFF4 3D references immediately. It is expected that + these names contain a simple cell reference or range reference. + Other regular defined names and external names rely on existence of + this reference. */ + TokensFormulaContext aContext( true, true ); + importBiffFormula( aContext, mnCalcSheet, rStrm, &mnFmlaSize ); + extractReference( aContext.getTokens() ); + } + else + { + /* Store record position of other defined names to be able to import + token array later. This is needed to correctly resolve references + to names that are stored later in the defined names list following + this name. */ + mxBiffStrm.reset( new BiffInputStreamPos( rStrm ) ); + } } void DefinedName::createNameObject() @@ -459,7 +503,8 @@ void DefinedName::createNameObject() // append sheet index for local names in multi-sheet documents if( isWorkbookFile() && !isGlobalName() ) - maCalcName = OUStringBuffer( maCalcName ).append( sal_Unicode( '_' ) ).append( maModel.mnSheet + 1 ).makeStringAndClear(); + maCalcName = OUStringBuffer( maCalcName ).append( sal_Unicode( '_' ) ). + append( static_cast< sal_Int32 >( mnCalcSheet + 1 ) ).makeStringAndClear(); // special flags for this name sal_Int32 nNameFlags = 0; @@ -506,18 +551,18 @@ void DefinedName::convertFormula() { case OOX_DEFNAME_PRINTAREA: { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( maModel.mnSheet ), UNO_QUERY ); + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); ApiCellRangeList aPrintRanges; - getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, maModel.mnSheet ); + getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, mnCalcSheet ); if( xPrintAreas.is() && !aPrintRanges.empty() ) xPrintAreas->setPrintAreas( ContainerHelper::vectorToSequence( aPrintRanges ) ); } break; case OOX_DEFNAME_PRINTTITLES: { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( maModel.mnSheet ), UNO_QUERY ); + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); ApiCellRangeList aTitleRanges; - getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, maModel.mnSheet ); + getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, mnCalcSheet ); if( xPrintAreas.is() && !aTitleRanges.empty() ) { bool bHasRowTitles = false; @@ -545,13 +590,6 @@ void DefinedName::convertFormula() break; } } - else if( mxBiffStrm.get() && maModel.mbHidden && (maModel.maName.getLength() > 0) && (maModel.maName[ 0 ] == '\x01') ) - { - // import BIFF2-BIFF4 external references - TokensFormulaContext aContext( true, true ); - implImportBiffFormula( aContext ); - setReference( aContext.getTokens() ); - } } bool DefinedName::getAbsoluteRange( CellRangeAddress& orRange ) const @@ -567,32 +605,34 @@ void DefinedName::implImportOoxFormula( FormulaContext& rContext ) if( mxFormula.get() ) { RecordInputStream aStrm( *mxFormula ); - importOobFormula( rContext, aStrm ); + importOobFormula( rContext, mnCalcSheet, aStrm ); } else - importOoxFormula( rContext ); + importOoxFormula( rContext, mnCalcSheet ); } void DefinedName::implImportBiffFormula( FormulaContext& rContext ) { - OSL_ENSURE( mxBiffStrm.get(), "DefinedName::importBiffFormula - missing BIFF stream" ); + OSL_ENSURE( mxBiffStrm.get(), "DefinedName::implImportBiffFormula - missing BIFF stream" ); BiffInputStream& rStrm = mxBiffStrm->getStream(); BiffInputStreamPosGuard aStrmGuard( rStrm ); if( mxBiffStrm->restorePosition() ) - importBiffFormula( rContext, rStrm, &mnFmlaSize ); + importBiffFormula( rContext, mnCalcSheet, rStrm, &mnFmlaSize ); } // ============================================================================ DefinedNamesBuffer::DefinedNamesBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ), - mnLocalSheet( -1 ) + mnCalcSheet( -1 ) { } -void DefinedNamesBuffer::setLocalSheetIndex( sal_Int32 nLocalSheet ) +void DefinedNamesBuffer::setLocalCalcSheet( sal_Int16 nCalcSheet ) { - mnLocalSheet = nLocalSheet; + OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), + "DefinedNamesBuffer::setLocalCalcSheet - invalid call" ); + mnCalcSheet = nCalcSheet; } DefinedNameRef DefinedNamesBuffer::importDefinedName( const AttributeList& rAttribs ) @@ -609,7 +649,7 @@ void DefinedNamesBuffer::importDefinedName( RecordInputStream& rStrm ) void DefinedNamesBuffer::importDefinedName( BiffInputStream& rStrm ) { - createDefinedName()->importDefinedName( rStrm ); + createDefinedName()->importDefinedName( rStrm, mnCalcSheet ); } void DefinedNamesBuffer::finalizeImport() @@ -639,7 +679,7 @@ DefinedNameRef DefinedNamesBuffer::getByTokenIndex( sal_Int32 nIndex ) const return maDefNameMap.get( nIndex ); } -DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, sal_Int32 nSheet ) const +DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, sal_Int16 nCalcSheet ) const { DefinedNameRef xGlobalName; // a found global name DefinedNameRef xLocalName; // a found local name @@ -648,7 +688,7 @@ DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, s DefinedNameRef xCurrName = *aIt; if( xCurrName->getModelName() == rModelName ) { - if( xCurrName->getSheetIndex() == nSheet ) + if( xCurrName->getLocalCalcSheet() == nCalcSheet ) xLocalName = xCurrName; else if( xCurrName->isGlobalName() ) xGlobalName = xCurrName; @@ -659,7 +699,7 @@ DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, s DefinedNameRef DefinedNamesBuffer::createDefinedName() { - DefinedNameRef xDefName( new DefinedName( *this, mnLocalSheet ) ); + DefinedNameRef xDefName( new DefinedName( *this ) ); maDefNames.push_back( xDefName ); return xDefName; } diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index 7c338c55af6f..3b72126f7df6 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -43,7 +43,9 @@ #include "oox/drawingml/shapecontext.hxx" #include "oox/drawingml/shapegroupcontext.hxx" #include "oox/vml/vmlshape.hxx" +#include "oox/vml/vmlshapecontainer.hxx" #include "oox/xls/formulaparser.hxx" +#include "oox/xls/stylesbuffer.hxx" #include "oox/xls/themebuffer.hxx" #include "oox/xls/unitconverter.hxx" @@ -537,12 +539,52 @@ void OoxDrawingFragment::onEndElement( const OUString& rChars ) // ============================================================================ +namespace { + +class VmlFindNoteFunc +{ +public: + explicit VmlFindNoteFunc( const CellAddress& rPos ); + bool operator()( const ::oox::vml::ShapeBase& rShape ) const; + +private: + sal_Int32 mnCol; + sal_Int32 mnRow; +}; + +VmlFindNoteFunc::VmlFindNoteFunc( const CellAddress& rPos ) : + mnCol( rPos.Column ), + mnRow( rPos.Row ) +{ +} + +bool VmlFindNoteFunc::operator()( const ::oox::vml::ShapeBase& rShape ) const +{ + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = rShape.getShapeModel().mxClientData; + return rxClientData.get() && (rxClientData->mnCol == mnCol) && (rxClientData->mnRow == mnRow); +} + +} // namespace + +// ---------------------------------------------------------------------------- + VmlDrawing::VmlDrawing( const WorksheetHelper& rHelper ) : ::oox::vml::Drawing( rHelper.getOoxFilter(), rHelper.getDrawPage(), ::oox::vml::VMLDRAWING_EXCEL ), WorksheetHelper( rHelper ) { } +const ::oox::vml::ShapeBase* VmlDrawing::getNoteShape( const CellAddress& rPos ) const +{ + return getShapes().findShape( VmlFindNoteFunc( rPos ) ); +} + +bool VmlDrawing::isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const +{ + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = rShape.getShapeModel().mxClientData; + return !rxClientData.get() || (rxClientData->mnObjType != XML_Note); +} + bool VmlDrawing::convertShapeClientAnchor( Rectangle& orShapeRect, const OUString& rShapeAnchor ) const { if( rShapeAnchor.getLength() == 0 ) diff --git a/oox/source/xls/excelfilter.cxx b/oox/source/xls/excelfilter.cxx index f460f3e8fdcb..a5bfe5e3d1d9 100644 --- a/oox/source/xls/excelfilter.cxx +++ b/oox/source/xls/excelfilter.cxx @@ -58,6 +58,34 @@ namespace xls { // ============================================================================ +ExcelFilterBase::ExcelFilterBase() : + mpHelper( 0 ) +{ +} + +ExcelFilterBase::~ExcelFilterBase() +{ + OSL_ENSURE( !mpHelper, "ExcelFilterBase::~ExcelFilterBase - workbook helper not cleared" ); +} + +void ExcelFilterBase::setWorkbookHelper( WorkbookHelper& rHelper ) +{ + mpHelper = &rHelper; +} + +WorkbookHelper& ExcelFilterBase::getWorkbookHelper() const +{ + OSL_ENSURE( mpHelper, "ExcelFilterBase::getWorkbookHelper - missing workbook helper" ); + return *mpHelper; +} + +void ExcelFilterBase::clearWorkbookHelper() +{ + mpHelper = 0; +} + +// ============================================================================ + OUString SAL_CALL ExcelFilter_getImplementationName() throw() { return CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilter" ); @@ -79,8 +107,7 @@ Reference< XInterface > SAL_CALL ExcelFilter_createInstance( // ---------------------------------------------------------------------------- ExcelFilter::ExcelFilter( const Reference< XMultiServiceFactory >& rxGlobalFactory ) : - XmlFilterBase( rxGlobalFactory ), - mpHelper( 0 ) + XmlFilterBase( rxGlobalFactory ) { } @@ -102,9 +129,9 @@ bool ExcelFilter::importDocument() throw() WorkbookHelperRoot aHelper( *this ); if( aHelper.isValid() ) { - mpHelper = &aHelper; // needed for callbacks + setWorkbookHelper( aHelper ); // needed for callbacks bRet = importFragment( new OoxWorkbookFragment( aHelper, aWorkbookPath ) ); - mpHelper = 0; + clearWorkbookHelper(); } } return bRet; @@ -115,15 +142,19 @@ bool ExcelFilter::exportDocument() throw() return false; } -const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const +sal_Int32 ExcelFilter::getSchemeColor( sal_Int32 nToken ) const { - return &mpHelper->getTheme(); + return getWorkbookHelper().getTheme().getColorByToken( nToken ); } -sal_Int32 ExcelFilter::getSchemeClr( sal_Int32 nColorSchemeToken ) const +sal_Int32 ExcelFilter::getPaletteColor( sal_Int32 nPaletteIdx ) const { - OSL_ENSURE( mpHelper, "ExcelFilter::getSchemeClr - no workbook helper" ); - return mpHelper->getTheme().getColorByToken( nColorSchemeToken ); + return getWorkbookHelper().getStyles().getPaletteColor( nPaletteIdx ); +} + +const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const +{ + return &getWorkbookHelper().getTheme(); } ::oox::vml::Drawing* ExcelFilter::getVmlDrawing() @@ -138,8 +169,7 @@ const TableStyleListPtr ExcelFilter::getTableStyles() ::oox::drawingml::chart::ChartConverter& ExcelFilter::getChartConverter() { - OSL_ENSURE( mpHelper, "ExcelFilter::getChartConverter - no workbook helper" ); - return mpHelper->getChartConverter(); + return getWorkbookHelper().getChartConverter(); } OUString ExcelFilter::implGetImplementationName() const @@ -202,7 +232,12 @@ bool ExcelBiffFilter::importDocument() throw() if( eBiff != BIFF_UNKNOWN ) { WorkbookHelperRoot aHelper( *this, eBiff ); - bRet = aHelper.isValid() && BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment(); + if( aHelper.isValid() ) + { + setWorkbookHelper( aHelper ); // needed for callbacks + bRet = BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment(); + clearWorkbookHelper(); + } } return bRet; } @@ -212,6 +247,11 @@ bool ExcelBiffFilter::exportDocument() throw() return false; } +sal_Int32 ExcelBiffFilter::getPaletteColor( sal_Int32 nPaletteIdx ) const +{ + return getWorkbookHelper().getStyles().getPaletteColor( nPaletteIdx ); +} + OUString ExcelBiffFilter::implGetImplementationName() const { return ExcelBiffFilter_getImplementationName(); diff --git a/oox/source/xls/excelhandlers.cxx b/oox/source/xls/excelhandlers.cxx index 3941bb306177..aa5a8634a60d 100644 --- a/oox/source/xls/excelhandlers.cxx +++ b/oox/source/xls/excelhandlers.cxx @@ -52,7 +52,7 @@ OoxWorkbookFragmentBase::OoxWorkbookFragmentBase( // ============================================================================ OoxWorksheetFragmentBase::OoxWorksheetFragmentBase( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ), WorksheetHelperRoot( rHelper, xProgressBar, eSheetType, nSheet ) { @@ -228,7 +228,7 @@ BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelpe // ============================================================================ BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const BiffWorkbookFragmentBase& rParent, - ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : BiffFragmentHandler( rParent ), WorksheetHelperRoot( rParent, xProgressBar, eSheetType, nSheet ) { @@ -237,7 +237,7 @@ BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const BiffWorkbookFragment // ============================================================================ BiffSkipWorksheetFragment::BiffSkipWorksheetFragment( - const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, sal_Int32 nSheet ) : + const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, sal_Int16 nSheet ) : BiffWorksheetFragmentBase( rParent, xProgressBar, SHEETTYPE_EMPTYSHEET, nSheet ) { } diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx index 564775228d2a..26a1df09cc69 100644 --- a/oox/source/xls/externallinkbuffer.cxx +++ b/oox/source/xls/externallinkbuffer.cxx @@ -30,8 +30,12 @@ #include "oox/xls/externallinkbuffer.hxx" #include +#include #include #include +#include +#include +#include #include #include #include @@ -55,9 +59,12 @@ using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::table::CellAddress; +using ::com::sun::star::sheet::ComplexReference; using ::com::sun::star::sheet::DDEItemInfo; using ::com::sun::star::sheet::DDELinkInfo; using ::com::sun::star::sheet::ExternalLinkInfo; +using ::com::sun::star::sheet::ExternalReference; +using ::com::sun::star::sheet::SingleReference; using ::com::sun::star::sheet::XDDELinks; using ::com::sun::star::sheet::XDDELinkResults; using ::com::sun::star::sheet::XExternalDocLinks; @@ -105,8 +112,8 @@ ExternalNameModel::ExternalNameModel() : // ============================================================================ -ExternalName::ExternalName( const ExternalLink& rParentLink, sal_Int32 nLocalSheet ) : - DefinedNameBase( rParentLink, nLocalSheet ), +ExternalName::ExternalName( const ExternalLink& rParentLink ) : + DefinedNameBase( rParentLink ), mrParentLink( rParentLink ), mnStorageId( 0 ), mbDdeLinkCreated( false ) @@ -239,16 +246,27 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) rStrm.readByteStringUC( false, getTextEncoding() ); OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importExternalName - empty name" ); + // load cell references that are stored in hidden external names (seen in BIFF3-BIFF4) + bool bHiddenRef = (getBiff() <= BIFF4) && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') && (rStrm.getRemaining() > 2); switch( mrParentLink.getLinkType() ) { case LINKTYPE_INTERNAL: - case LINKTYPE_EXTERNAL: - // cell references that are stored in hidden external names (seen in BIFF3-BIFF4) - if( (getBiff() <= BIFF4) && (maModel.maName.getLength() > 0) && (maModel.maName[ 0 ] == '\x01') && (rStrm.getRemaining() > 2) ) + // cell references to other internal sheets are stored in hidden external names + if( bHiddenRef && (getBiff() == BIFF4) && isWorkbookFile() ) { TokensFormulaContext aContext( true, true ); - importBiffFormula( aContext, rStrm ); - setReference( aContext.getTokens() ); + importBiffFormula( aContext, mrParentLink.getCalcSheetIndex(), rStrm ); + extractReference( aContext.getTokens() ); + } + break; + + case LINKTYPE_EXTERNAL: + // cell references to other documents are stored in hidden external names + if( bHiddenRef ) + { + TokensFormulaContext aContext( true, true ); + importBiffFormula( aContext, 0, rStrm ); + extractExternalReference( aContext.getTokens() ); } break; @@ -300,6 +318,7 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) } } +#if 0 sal_Int32 ExternalName::getSheetCacheIndex() const { OSL_ENSURE( mrParentLink.getLinkType() == LINKTYPE_DDE, "ExternalName::getSheetCacheIndex - unexpected link type" ); @@ -337,6 +356,7 @@ sal_Int32 ExternalName::getSheetCacheIndex() const } return nCacheIdx; } +#endif bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const { @@ -381,6 +401,51 @@ bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, return false; } +// private -------------------------------------------------------------------- + +namespace { + +void lclSetSheetCacheIndex( SingleReference& orApiRef, sal_Int32 nCacheIdx ) +{ + using namespace ::com::sun::star::sheet::ReferenceFlags; + setFlag( orApiRef.Flags, SHEET_RELATIVE, false ); + setFlag( orApiRef.Flags, SHEET_3D, true ); + orApiRef.Sheet = nCacheIdx; +} + +} // namespace + +void ExternalName::extractExternalReference( const ApiTokenSequence& rTokens ) +{ + OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "ExternalName::setExternalReference - unexpected call" ); + sal_Int32 nDocLinkIdx = mrParentLink.getDocumentLinkIndex(); + sal_Int32 nCacheIdx = mrParentLink.getSheetCacheIndex(); + if( (nDocLinkIdx >= 0) && (nCacheIdx >= 0) ) + { + ExternalReference aExtApiRef; + aExtApiRef.Index = nDocLinkIdx; + + Any aRefAny = getFormulaParser().extractReference( rTokens ); + if( aRefAny.has< SingleReference >() ) + { + SingleReference aApiRef; + aRefAny >>= aApiRef; + lclSetSheetCacheIndex( aApiRef, nCacheIdx ); + aExtApiRef.Reference <<= aApiRef; + maRefAny <<= aExtApiRef; + } + else if( aRefAny.has< ComplexReference >() ) + { + ComplexReference aApiRef; + aRefAny >>= aApiRef; + lclSetSheetCacheIndex( aApiRef.Reference1, nCacheIdx ); + lclSetSheetCacheIndex( aApiRef.Reference2, nCacheIdx ); + aExtApiRef.Reference <<= aApiRef; + maRefAny <<= aExtApiRef; + } + } +} + void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows ) { OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_DDE) || (mrParentLink.getLinkType() == LINKTYPE_OLE) || @@ -564,10 +629,10 @@ void ExternalLink::importExternSheet( BiffInputStream& rStrm ) switch( meLinkType ) { case LINKTYPE_INTERNAL: - maIndexes.push_back( getWorksheets().getCalcSheetIndex( aSheetName ) ); + maCalcSheets.push_back( getWorksheets().getCalcSheetIndex( aSheetName ) ); break; case LINKTYPE_EXTERNAL: - insertExternalSheet( aSheetName ); + insertExternalSheet( (aSheetName.getLength() > 0) ? aSheetName : WorksheetBuffer::getBaseFileName( maTargetUrl ) ); break; default:; } @@ -659,11 +724,41 @@ FunctionLibraryType ExternalLink::getFuncLibraryType() const return (meLinkType == LINKTYPE_LIBRARY) ? meFuncLibType : FUNCLIB_UNKNOWN; } -sal_Int32 ExternalLink::getSheetIndex( sal_Int32 nTabId ) const +sal_Int16 ExternalLink::getCalcSheetIndex( sal_Int32 nTabId ) const { + OSL_ENSURE( meLinkType == LINKTYPE_INTERNAL, "ExternalLink::getCalcSheetIndex - invalid link type" ); OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOX) || (getBiff() == BIFF8), - "ExternalLink::getSheetIndex - invalid sheet index" ); - return ContainerHelper::getVectorElement< sal_Int32 >( maIndexes, nTabId, -1 ); + "ExternalLink::getCalcSheetIndex - invalid sheet index" ); + return ContainerHelper::getVectorElement< sal_Int16 >( maCalcSheets, nTabId, -1 ); +} + +sal_Int32 ExternalLink::getDocumentLinkIndex() const +{ + OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getDocumentLinkIndex - invalid link type" ); + return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1; +} + +sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const +{ + OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getSheetCacheIndex - invalid link type" ); + OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOX) || (getBiff() == BIFF8), + "ExternalLink::getSheetCacheIndex - invalid sheet index" ); + return ContainerHelper::getVectorElement< sal_Int32 >( maSheetCaches, nTabId, -1 ); +} + +Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const +{ + sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId ); + if( mxDocLink.is() && (nCacheIdx >= 0) ) try + { + // existing mxDocLink implies that this is an external link + Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW ); + return xSheetCache; + } + catch( Exception& ) + { + } + return 0; } void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const @@ -681,12 +776,12 @@ void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId case LINKTYPE_EXTERNAL: { - sal_Int32 nDocLinkIndex = mxDocLink.is() ? mxDocLink->getTokenIndex() : -1; + sal_Int32 nDocLinkIdx = getDocumentLinkIndex(); switch( getFilterType() ) { case FILTER_OOX: // OOBIN: passed indexes point into sheet list of EXTSHEETLIST - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) ); break; case FILTER_BIFF: switch( getBiff() ) @@ -694,17 +789,17 @@ void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId case BIFF2: case BIFF3: case BIFF4: - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) ); break; case BIFF5: // BIFF5: first sheet from this external link, last sheet is passed in nTabId2 if( const ExternalLink* pExtLink2 = getExternalLinks().getExternalLink( nTabId2 ).get() ) if( (pExtLink2->getLinkType() == LINKTYPE_EXTERNAL) && (maTargetUrl == pExtLink2->getTargetUrl()) ) - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex(), pExtLink2->getSheetIndex() ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex(), pExtLink2->getSheetCacheIndex() ); break; case BIFF8: // BIFF8: passed indexes point into sheet list of EXTERNALBOOK - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) ); break; case BIFF_UNKNOWN: break; } @@ -720,21 +815,6 @@ void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId } } -Reference< XExternalSheetCache > ExternalLink::getExternalSheetCache( sal_Int32 nTabId ) -{ - const sal_Int32* pnCacheId = ContainerHelper::getVectorElement( maIndexes, nTabId ); - if( mxDocLink.is() && pnCacheId ) try - { - // existing mxDocLink implies that this is an external link - Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( *pnCacheId ), UNO_QUERY_THROW ); - return xSheetCache; - } - catch( Exception& ) - { - } - return 0; -} - ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const { return maExtNames.get( nIndex ); @@ -790,21 +870,21 @@ OUString ExternalLink::parseBiffTargetUrl( const OUString& rBiffTargetUrl ) OUString aClassName, aTargetUrl, aSheetName; switch( getAddressConverter().parseBiffTargetUrl( aClassName, aTargetUrl, aSheetName, rBiffTargetUrl ) ) - { + { case BIFF_TARGETTYPE_URL: if( aTargetUrl.getLength() == 0 ) - { + { meLinkType = (aSheetName.getLength() > 0) ? LINKTYPE_INTERNAL : LINKTYPE_SELF; - } - else if( (aTargetUrl.getLength() == 1) && (aTargetUrl[ 0 ] == ':') ) - { - if( getBiff() >= BIFF4 ) - meLinkType = LINKTYPE_ANALYSIS; - } + } + else if( (aTargetUrl.getLength() == 1) && (aTargetUrl[ 0 ] == ':') ) + { + if( getBiff() >= BIFF4 ) + meLinkType = LINKTYPE_ANALYSIS; + } else if( (aTargetUrl.getLength() > 1) || (aTargetUrl[ 0 ] != ' ') ) - { + { setExternalTargetUrl( aTargetUrl, OOX_TARGETTYPE_EXTLINK ); - } + } break; case BIFF_TARGETTYPE_SAMESHEET: @@ -834,13 +914,13 @@ void ExternalLink::insertExternalSheet( const OUString& rSheetName ) { Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName ); sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1; - maIndexes.push_back( nCacheIdx ); + maSheetCaches.push_back( nCacheIdx ); } } ExternalNameRef ExternalLink::createExternalName() { - ExternalNameRef xExtName( new ExternalName( *this, getSheetIndex() ) ); + ExternalNameRef xExtName( new ExternalName( *this ) ); maExtNames.push_back( xExtName ); return xExtName; } diff --git a/oox/source/xls/externallinkfragment.cxx b/oox/source/xls/externallinkfragment.cxx index 0245c44eb13c..39686ae7cb64 100644 --- a/oox/source/xls/externallinkfragment.cxx +++ b/oox/source/xls/externallinkfragment.cxx @@ -338,7 +338,7 @@ ContextHandlerRef OoxExternalLinkFragment::onCreateRecordContext( sal_Int32 nRec ContextHandlerRef OoxExternalLinkFragment::createSheetDataContext( sal_Int32 nSheetId ) { - return new OoxExternalSheetDataContext( *this, mrExtLink.getExternalSheetCache( nSheetId ) ); + return new OoxExternalSheetDataContext( *this, mrExtLink.getSheetCache( nSheetId ) ); } // oox.core.FragmentHandler2 interface ---------------------------------------- @@ -475,11 +475,11 @@ void BiffExternalLinkFragment::importXct() case BIFF3: case BIFF4: case BIFF5: - mxSheetCache = mxExtLink->getExternalSheetCache( 0 ); + mxSheetCache = mxExtLink->getSheetCache( 0 ); break; case BIFF8: mrStrm.skip( 2 ); - mxSheetCache = mxExtLink->getExternalSheetCache( mrStrm.readInt16() ); + mxSheetCache = mxExtLink->getSheetCache( mrStrm.readInt16() ); break; case BIFF_UNKNOWN: break; } diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx index 33465d81d466..7b503142a89e 100644 --- a/oox/source/xls/pivotcachebuffer.cxx +++ b/oox/source/xls/pivotcachebuffer.cxx @@ -1369,7 +1369,7 @@ void PivotCache::importDConUrl( BiffInputStream& rStrm ) void PivotCache::finalizeInternalSheetSource() { // resolve sheet name to sheet index - sal_Int32 nSheet = getWorksheets().getCalcSheetIndex( maSheetSrcModel.maSheet ); + sal_Int16 nSheet = getWorksheets().getCalcSheetIndex( maSheetSrcModel.maSheet ); // if cache is based on a defined name or table, try to resolve to cell range if( maSheetSrcModel.maDefName.getLength() > 0 ) @@ -1393,7 +1393,7 @@ void PivotCache::finalizeInternalSheetSource() else if( nSheet >= 0 ) { // insert sheet index into the range, range address will be checked below - maSheetSrcModel.maRange.Sheet = static_cast< sal_Int16 >( nSheet ); + maSheetSrcModel.maRange.Sheet = nSheet; mbValidSource = true; } // else sheet has been deleted, generate the source data from cache diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx index d4e93f4bf47a..a4f8f1379654 100644 --- a/oox/source/xls/richstring.cxx +++ b/oox/source/xls/richstring.cxx @@ -29,6 +29,7 @@ ************************************************************************/ #include "oox/xls/richstring.hxx" +#include #include #include "oox/helper/attributelist.hxx" #include "oox/helper/propertyset.hxx" @@ -37,6 +38,7 @@ using ::rtl::OString; using ::rtl::OUString; +using ::rtl::OUStringBuffer; using ::com::sun::star::uno::Reference; using ::com::sun::star::text::XText; using ::com::sun::star::text::XTextRange; @@ -490,12 +492,20 @@ void RichString::finalizeImport() maFontPortions.forEachMem( &RichStringPortion::finalizeImport ); } +OUString RichString::getPlainText() const +{ + OUStringBuffer aBuffer; + for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt ) + aBuffer.append( (*aIt)->getText() ); + return aBuffer.makeStringAndClear(); +} + void RichString::convert( const Reference< XText >& rxText, sal_Int32 nXfId ) const { for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt ) { (*aIt)->convert( rxText, nXfId ); - nXfId = -1; + nXfId = -1; // use passed XF identifier for first portion only } } diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx index 64d660f5c559..dc7456e1e4c9 100644 --- a/oox/source/xls/stylesbuffer.cxx +++ b/oox/source/xls/stylesbuffer.cxx @@ -29,7 +29,8 @@ ************************************************************************/ #include "oox/xls/stylesbuffer.hxx" -#include +#include +#include #include #include #include @@ -59,14 +60,22 @@ using ::rtl::OUString; using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::container::XNameAccess; +using ::com::sun::star::container::XNamed; using ::com::sun::star::awt::FontDescriptor; using ::com::sun::star::awt::XDevice; using ::com::sun::star::awt::XFont2; using ::com::sun::star::table::BorderLine; using ::com::sun::star::text::XText; using ::com::sun::star::style::XStyle; +using ::oox::core::FilterBase; namespace oox { namespace xls { @@ -257,6 +266,11 @@ const sal_uInt32 BIFF_XF_DIAG_BLTR = 0x80000000; /// Bottom-left to t const sal_uInt16 BIFF_STYLE_BUILTIN = 0x8000; const sal_uInt16 BIFF_STYLE_XFMASK = 0x0FFF; +// BIFF STYLEEXT flags +const sal_uInt8 BIFF_STYLEEXT_BUILTIN = 0x01; +const sal_uInt8 BIFF_STYLEEXT_HIDDEN = 0x02; +const sal_uInt8 BIFF_STYLEEXT_CUSTOM = 0x04; + // BIFF conditional formatting const sal_uInt32 BIFF_CFRULE_BORDER_LEFT = 0x00000400; const sal_uInt32 BIFF_CFRULE_BORDER_RIGHT = 0x00000800; @@ -280,8 +294,7 @@ const sal_uInt32 BIFF_CFRULE_FONT_ESCAPEM = 0x00000001; /// Font escapement // ---------------------------------------------------------------------------- -template< typename StreamType > -sal_Int32 lclReadRgbColor( StreamType& rStrm ) +sal_Int32 lclReadRgbColor( BinaryInputStream& rStrm ) { sal_uInt8 nR, nG, nB, nA; rStrm >> nR >> nG >> nB >> nA; @@ -299,39 +312,34 @@ sal_Int32 lclReadRgbColor( StreamType& rStrm ) // ---------------------------------------------------------------------------- -Color::Color() : - meMode( COLOR_AUTO ), - mnValue( 0 ), - mfTint( 0.0 ) -{ -} - void Color::setAuto() { - meMode = COLOR_AUTO; - mnValue = 0; - mfTint = 0.0; + clearTransformations(); + setSchemeClr( XML_phClr ); } void Color::setRgb( sal_Int32 nRgbValue, double fTint ) { - meMode = COLOR_RGB; - mnValue = nRgbValue; - mfTint = fTint; + clearTransformations(); + setSrgbClr( nRgbValue & 0xFFFFFF ); + if( fTint != 0.0 ) addExcelTintTransformation( fTint ); } void Color::setTheme( sal_Int32 nThemeIdx, double fTint ) { - meMode = COLOR_THEME; - mnValue = nThemeIdx; - mfTint = fTint; + clearTransformations(); + static const sal_Int32 spnColorTokens[] = { + XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2, + XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink }; + setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) ); + if( fTint != 0.0 ) addExcelTintTransformation( fTint ); } void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint ) { - meMode = COLOR_INDEXED; - mnValue = nPaletteIdx; - mfTint = fTint; + clearTransformations(); + setPaletteClr( nPaletteIdx ); + if( fTint != 0.0 ) addExcelTintTransformation( fTint ); } void Color::importColor( const AttributeList& rAttribs ) @@ -408,38 +416,6 @@ void Color::importColorRgb( BiffInputStream& rStrm ) setRgb( lclReadRgbColor( rStrm ) ); } -bool Color::isAuto() const -{ - return meMode == COLOR_AUTO; -} - -sal_Int32 Color::getColor( const WorkbookHelper& rHelper, sal_Int32 nAuto ) const -{ - switch( meMode ) - { - case COLOR_AUTO: return nAuto; - case COLOR_FINAL: return mnValue; - - case COLOR_RGB: mnValue &= 0xFFFFFF; break; - case COLOR_THEME: mnValue = rHelper.getTheme().getColorByIndex( mnValue ); break; - case COLOR_INDEXED: mnValue = rHelper.getStyles().getPaletteColor( mnValue ); break; - } - - // color tint - OSL_ENSURE( (rHelper.getFilterType() == FILTER_OOX) || (mfTint == 0.0), - "Color::getColor - color tint only supported in OOX filter" ); - if( (mnValue >= 0) && (rHelper.getFilterType() == FILTER_OOX) && (mfTint != 0.0) ) - { - ::oox::drawingml::Color aTransformColor; - aTransformColor.setSrgbClr( mnValue ); - aTransformColor.addExcelTintTransformation( mfTint ); - mnValue = aTransformColor.getColor( rHelper.getOoxFilter() ); - } - - meMode = COLOR_FINAL; - return mnValue; -} - RecordInputStream& operator>>( RecordInputStream& rStrm, Color& orColor ) { orColor.importColor( rStrm ); @@ -532,14 +508,13 @@ ColorPalette::ColorPalette( const WorkbookHelper& rHelper ) : void ColorPalette::importPaletteColor( const AttributeList& rAttribs ) { - appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ) ); + appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_WHITE ) ); } void ColorPalette::importPaletteColor( RecordInputStream& rStrm ) { - Color aColor; - aColor.importColorRgb( rStrm ); - appendColor( aColor.getColor( *this ) ); + sal_Int32 nRgb = lclReadRgbColor( rStrm ); + appendColor( nRgb & 0xFFFFFF ); } void ColorPalette::importPalette( BiffInputStream& rStrm ) @@ -550,11 +525,10 @@ void ColorPalette::importPalette( BiffInputStream& rStrm ) // fill palette from BIFF_COLOR_USEROFFSET mnAppendIndex = BIFF_COLOR_USEROFFSET; - Color aColor; for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex ) { - aColor.importColorRgb( rStrm ); - appendColor( aColor.getColor( *this ) ); + sal_Int32 nRgb = lclReadRgbColor( rStrm ); + appendColor( nRgb & 0xFFFFFF ); } } @@ -574,7 +548,7 @@ sal_Int32 ColorPalette::getColor( sal_Int32 nPaletteIdx ) const case OOX_COLOR_WINDOWBACK: case OOX_COLOR_CHWINDOWBACK: nColor = getBaseFilter().getSystemColor( XML_window ); break; case OOX_COLOR_BUTTONBACK: nColor = getBaseFilter().getSystemColor( XML_btnFace ); break; - case OOX_COLOR_CHBORDERAUTO: nColor = 0x000000; /* really always black? */ break; + case OOX_COLOR_CHBORDERAUTO: nColor = API_RGB_BLACK; /* really always black? */ break; case OOX_COLOR_NOTEBACK: nColor = getBaseFilter().getSystemColor( XML_infoBk ); break; case OOX_COLOR_NOTETEXT: nColor = getBaseFilter().getSystemColor( XML_infoText ); break; case OOX_COLOR_FONTAUTO: nColor = API_RGB_TRANSPARENT; break; @@ -1013,7 +987,7 @@ void Font::finalizeImport() rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) ); // color, height, weight, slant, strikeout, outline, shadow - maApiData.mnColor = maModel.maColor.getColor( *this, API_RGB_TRANSPARENT ); + maApiData.mnColor = maModel.maColor.getColor( getBaseFilter() ); maApiData.maDesc.Height = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 ); maApiData.maDesc.Weight = maModel.mbBold ? cssawt::FontWeight::BOLD : cssawt::FontWeight::NORMAL; maApiData.maDesc.Slant = maModel.mbItalic ? cssawt::FontSlant_ITALIC : cssawt::FontSlant_NONE; @@ -1750,7 +1724,7 @@ BorderLineModel* Border::getBorderLine( sal_Int32 nElement ) bool Border::convertBorderLine( BorderLine& rBorderLine, const BorderLineModel& rModel ) { - rBorderLine.Color = rModel.maColor.getColor( *this, API_RGB_BLACK ); + rBorderLine.Color = rModel.maColor.getColor( getBaseFilter(), API_RGB_BLACK ); switch( rModel.mnStyle ) { case XML_dashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; @@ -2046,6 +2020,8 @@ void Fill::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) void Fill::finalizeImport() { + const FilterBase& rFilter = getBaseFilter(); + if( mxPatternModel.get() ) { // finalize the OOX data struct @@ -2096,15 +2072,16 @@ void Fill::finalizeImport() case XML_solid: nAlpha = 0x80; break; } + sal_Int32 nWinTextColor = rFilter.getSystemColor( XML_windowText ); + sal_Int32 nWinColor = rFilter.getSystemColor( XML_window ); + if( !rModel.mbPattColorUsed ) rModel.maPatternColor.setAuto(); - sal_Int32 nPattColor = rModel.maPatternColor.getColor( - *this, getBaseFilter().getSystemColor( XML_windowText ) ); + sal_Int32 nPattColor = rModel.maPatternColor.getColor( rFilter, nWinTextColor ); if( !rModel.mbFillColorUsed ) rModel.maFillColor.setAuto(); - sal_Int32 nFillColor = rModel.maFillColor.getColor( - *this, getBaseFilter().getSystemColor( XML_window ) ); + sal_Int32 nFillColor = rModel.maFillColor.getColor( rFilter, nWinColor ); maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha ); maApiData.mbTransparent = false; @@ -2116,11 +2093,11 @@ void Fill::finalizeImport() maApiData.mbUsed = true; // no support for differential attributes GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin(); OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); - maApiData.mnColor = aIt->second.getColor( *this ); + maApiData.mnColor = aIt->second.getColor( rFilter, API_RGB_WHITE ); if( ++aIt != rModel.maColors.end() ) { OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); - sal_Int32 nEndColor = aIt->second.getColor( *this ); + sal_Int32 nEndColor = aIt->second.getColor( rFilter, API_RGB_WHITE ); maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 ); maApiData.mbTransparent = false; } @@ -2369,10 +2346,7 @@ void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const // create and set cell style if( maModel.mbCellXf ) - { - const OUString& rStyleName = rStyles.createCellStyle( maModel.mnStyleXfId ); - rPropMap[ PROP_CellStyle ] <<= rStyleName; - } + rPropMap[ PROP_CellStyle ] <<= rStyles.createCellStyle( maModel.mnStyleXfId ); if( maModel.mbFontUsed ) rStyles.writeFontToPropertyMap( rPropMap, maModel.mnFontId ); @@ -2585,11 +2559,7 @@ namespace { const sal_Char* const spcLegacyStyleNamePrefix = "Excel_BuiltIn_"; const sal_Char* const sppcLegacyStyleNames[] = { -#if OOX_XLS_USE_DEFAULT_STYLE - "", // use existing "Default" style -#else "Normal", -#endif "RowLevel_", // outline level will be appended "ColumnLevel_", // outline level will be appended "Comma", @@ -2605,11 +2575,7 @@ const sal_Int32 snLegacyStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY const sal_Char* const spcStyleNamePrefix = "Excel Built-in "; const sal_Char* const sppcStyleNames[] = { -#if OOX_XLS_USE_DEFAULT_STYLE - "", // use existing "Default" style -#else "Normal", -#endif "RowLevel_", // outline level will be appended "ColLevel_", // outline level will be appended "Comma", @@ -2666,50 +2632,32 @@ const sal_Char* const sppcStyleNames[] = }; const sal_Int32 snStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( sppcStyleNames ) ); -#if OOX_XLS_USE_DEFAULT_STYLE -const sal_Char* const spcDefaultStyleName = "Default"; -#endif - OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 ) { + OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" ); OUStringBuffer aStyleName; - OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown builtin style" ); -#if OOX_XLS_USE_DEFAULT_STYLE - if( nBuiltinId == OOX_STYLE_NORMAL ) // "Normal" becomes "Default" style - { - aStyleName.appendAscii( spcDefaultStyleName ); - } + aStyleName.appendAscii( spcStyleNamePrefix ); + if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ][ 0 ] != 0) ) + aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] ); + else if( rName.getLength() > 0 ) + aStyleName.append( rName ); else - { -#endif - aStyleName.appendAscii( spcStyleNamePrefix ); - if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ][ 0 ] != 0) ) - aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] ); - else if( rName.getLength() > 0 ) - aStyleName.append( rName ); - else - aStyleName.append( nBuiltinId ); - if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) - aStyleName.append( nLevel ); -#if OOX_XLS_USE_DEFAULT_STYLE - } -#endif + aStyleName.append( nBuiltinId ); + if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) + aStyleName.append( nLevel ); + return aStyleName.makeStringAndClear(); +} + +OUString lclGetBuiltInStyleName( const OUString& rName ) +{ + OUStringBuffer aStyleName; + aStyleName.appendAscii( spcStyleNamePrefix ).append( rName ); return aStyleName.makeStringAndClear(); } bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar ) { -#if OOX_XLS_USE_DEFAULT_STYLE - // "Default" becomes "Normal" - if( rStyleName.equalsIgnoreAsciiCaseAscii( spcDefaultStyleName ) ) - { - if( pnBuiltinId ) *pnBuiltinId = OOX_STYLE_NORMAL; - if( pnNextChar ) *pnNextChar = rStyleName.getLength(); - return true; - } -#endif - - // try the other builtin styles + // try the other built-in styles OUString aPrefix = OUString::createFromAscii( spcStyleNamePrefix ); sal_Int32 nPrefixLen = aPrefix.getLength(); sal_Int32 nFoundId = 0; @@ -2719,20 +2667,13 @@ bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, OUString aShortName; for( sal_Int32 nId = 0; nId < snStyleNamesCount; ++nId ) { -#if OOX_XLS_USE_DEFAULT_STYLE - if( nId != OOX_STYLE_NORMAL ) + aShortName = OUString::createFromAscii( sppcStyleNames[ nId ] ); + if( rStyleName.matchIgnoreAsciiCase( aShortName, nPrefixLen ) && + (nNextChar < nPrefixLen + aShortName.getLength()) ) { -#endif - aShortName = OUString::createFromAscii( sppcStyleNames[ nId ] ); - if( rStyleName.matchIgnoreAsciiCase( aShortName, nPrefixLen ) && - (nNextChar < nPrefixLen + aShortName.getLength()) ) - { - nFoundId = nId; - nNextChar = nPrefixLen + aShortName.getLength(); - } -#if OOX_XLS_USE_DEFAULT_STYLE + nFoundId = nId; + nNextChar = nPrefixLen + aShortName.getLength(); } -#endif } } @@ -2796,15 +2737,11 @@ bool CellStyleModel::isDefaultStyle() const return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL); } -OUString CellStyleModel::createStyleName() const -{ - return isBuiltin() ? lclGetBuiltinStyleName( mnBuiltinId, maName, mnLevel ) : maName; -} - // ============================================================================ CellStyle::CellStyle( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ) + WorkbookHelper( rHelper ), + mbCreated( false ) { } @@ -2823,8 +2760,8 @@ void CellStyle::importCellStyle( RecordInputStream& rStrm ) { sal_uInt16 nFlags; rStrm >> maModel.mnXfId >> nFlags; - maModel.mnBuiltinId = rStrm.readuInt8(); - maModel.mnLevel = rStrm.readuInt8(); + maModel.mnBuiltinId = rStrm.readInt8(); + maModel.mnLevel = rStrm.readInt8(); rStrm >> maModel.maName; maModel.mbBuiltin = getFlag( nFlags, OOBIN_CELLSTYLE_BUILTIN ); maModel.mbCustom = getFlag( nFlags, OOBIN_CELLSTYLE_CUSTOM ); @@ -2839,62 +2776,74 @@ void CellStyle::importStyle( BiffInputStream& rStrm ) maModel.mbBuiltin = getFlag( nStyleXf, BIFF_STYLE_BUILTIN ); if( maModel.mbBuiltin ) { - maModel.mnBuiltinId = rStrm.readuInt8(); - maModel.mnLevel = rStrm.readuInt8(); + maModel.mnBuiltinId = rStrm.readInt8(); + maModel.mnLevel = rStrm.readInt8(); } else { maModel.maName = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() ); - } -} - -const OUString& CellStyle::createCellStyle( sal_Int32 nXfId, bool bSkipDefaultBuiltin ) -{ - if( maCalcName.getLength() == 0 ) - { - bool bBuiltin = maModel.isBuiltin(); - if( !bSkipDefaultBuiltin || !bBuiltin || maModel.mbCustom ) + // #i103281# check if this is a new built-in style introduced in XL2007 + if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_STYLEEXT) && rStrm.startNextRecord() ) { - // name of the style (generate unique name for builtin styles) - maCalcName = maModel.createStyleName(); - // #i1624# #i1768# ignore unnamed user styles - if( maCalcName.getLength() > 0 ) + sal_uInt8 nExtFlags; + rStrm.skip( 12 ); + rStrm >> nExtFlags; + maModel.mbBuiltin = getFlag( nExtFlags, BIFF_STYLEEXT_BUILTIN ); + maModel.mbCustom = getFlag( nExtFlags, BIFF_STYLEEXT_CUSTOM ); + maModel.mbHidden = getFlag( nExtFlags, BIFF_STYLEEXT_HIDDEN ); + if( maModel.mbBuiltin ) { - Reference< XStyle > xStyle; -#if OOX_XLS_USE_DEFAULT_STYLE - // special handling for default style (do not create, but use existing) - if( isDefaultStyle() ) - { - /* Set all flags to true to have all properties in the style, - even if the used flags are not set (that's what Excel does). */ - if( Xf* pXf = getStyles().getStyleXf( nXfId ).get() ) - pXf->setAllUsedFlags( true ); - // use existing built-in style - xStyle = getStyleObject( maCalcName, false ); - } - else -#endif - { - /* Insert into cell styles collection, rename existing user styles, - if this is a built-in style, but do not do this in BIFF4 workspace - files, where built-in styles occur repeatedly. */ - bool bRenameExisting = bBuiltin && (getBiff() != BIFF4); - xStyle = createStyleObject( maCalcName, false, bRenameExisting ); - } - - // write style formatting properties - PropertySet aPropSet( xStyle ); - getStyles().writeStyleXfToPropertySet( aPropSet, nXfId ); -#if OOX_XLS_USE_DEFAULT_STYLE -#else - if( !isDefaultStyle() && xStyle.is() ) - xStyle->setParentStyle( getStyles().getDefaultStyleName() ); -#endif + maModel.mnBuiltinId = rStrm.readInt8(); + maModel.mnLevel = rStrm.readInt8(); } } } - return maCalcName; +} + +OUString CellStyle::calcInitialStyleName() const +{ + return isBuiltin() ? lclGetBuiltinStyleName( maModel.mnBuiltinId, maModel.maName, maModel.mnLevel ) : maModel.maName; +} + +void CellStyle::createCellStyle() +{ + // #i1624# #i1768# ignore unnamed user styles + if( !mbCreated ) + mbCreated = maFinalName.getLength() == 0; + + /* #i103281# do not create another style of the same name, if it exists + already. This is needed to prevent that styles pasted from clipboard + get duplicated over and over. */ + if( !mbCreated ) try + { + Reference< XNameAccess > xCellStylesNA( getStyleFamily( false ), UNO_QUERY_THROW ); + mbCreated = xCellStylesNA->hasByName( maFinalName ); + } + catch( Exception& ) + { + } + + // create the style object in the document + if( !mbCreated ) try + { + mbCreated = true; + Reference< XStyle > xStyle( createStyleObject( maFinalName, false ), UNO_SET_THROW ); + // write style formatting properties + PropertySet aPropSet( xStyle ); + getStyles().writeStyleXfToPropertySet( aPropSet, maModel.mnXfId ); + if( !isDefaultStyle() ) + xStyle->setParentStyle( getStyles().getDefaultStyleName() ); + } + catch( Exception& ) + { + } +} + +void CellStyle::finalizeImport() +{ + if( !isBuiltin() || maModel.mbCustom ) + createCellStyle(); } // ============================================================================ @@ -2906,6 +2855,32 @@ StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) : maDefStyleName( lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ) ), mnDefStyleXf( -1 ) { + /* Reserve style names that are built-in in Calc. This causes that + imported cell styles get different unused names and thus do not try to + overwrite these built-in styles. For BIFF4 workbooks (which contain a + separate list of cell styles per sheet), reserve all existing names if + current sheet is not the first sheet (this styles buffer will be + constructed again for every new sheet). This will create unique names + for styles in different sheets with the same name. */ + bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0); + try + { + Reference< XEnumerationAccess > xCellStylesEA( getStyleFamily( false ), UNO_QUERY_THROW ); + Reference< XEnumeration > xCellStylesEnum( xCellStylesEA->createEnumeration(), UNO_SET_THROW ); + while( xCellStylesEnum->hasMoreElements() ) + { + Reference< XStyle > xCellStyle( xCellStylesEnum->nextElement(), UNO_QUERY_THROW ); + if( bReserveAll || !xCellStyle->isUserDefined() ) + { + Reference< XNamed > xCellStyleName( xCellStyle, UNO_QUERY_THROW ); + // create an empty entry by using ::std::map<>::operator[] + maCellStylesByName[ xCellStyleName->getName() ]; + } + } + } + catch( Exception& ) + { + } } FontRef StylesBuffer::createFont( sal_Int32* opnFontId ) @@ -3075,12 +3050,10 @@ void StylesBuffer::finalizeImport() maDxfs.forEachMem( &Dxf::finalizeImport ); // create the default cell style first - if( CellStyle* pDefStyle = maCellStyles.get( mnDefStyleXf ).get() ) - pDefStyle->createCellStyle( mnDefStyleXf ); - /* Create user-defined and modified builtin cell styles, passing true to - createStyleSheet() skips unchanged builtin styles. */ - for( CellStyleMap::iterator aIt = maCellStyles.begin(), aEnd = maCellStyles.end(); aIt != aEnd; ++aIt ) - aIt->second->createCellStyle( aIt->first, true ); + if( CellStyle* pDefStyle = maCellStylesById.get( mnDefStyleXf ).get() ) + pDefStyle->createCellStyle(); + // create user-defined and modified built-in cell styles + maCellStylesById.forEachMem( &CellStyle::finalizeImport ); } sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const @@ -3136,8 +3109,13 @@ const FontModel& StylesBuffer::getDefaultFontModel() const const OUString& StylesBuffer::createCellStyle( sal_Int32 nXfId ) const { - if( CellStyle* pCellStyle = maCellStyles.get( nXfId ).get() ) - return pCellStyle->createCellStyle( nXfId ); + if( CellStyle* pCellStyle = maCellStylesById.get( nXfId ).get() ) + { + pCellStyle->createCellStyle(); + const OUString& rStyleName = pCellStyle->getFinalStyleName(); + if( rStyleName.getLength() > 0 ) + return rStyleName; + } // on error: fallback to default style return maDefStyleName; } @@ -3150,13 +3128,10 @@ const OUString& StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const return maDefStyleName; } -#if OOX_XLS_USE_DEFAULT_STYLE -#else const OUString& StylesBuffer::getDefaultStyleName() const { return createCellStyle( mnDefStyleXf ); } -#endif void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const { @@ -3207,11 +3182,38 @@ void StylesBuffer::writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 n void StylesBuffer::insertCellStyle( CellStyleRef xCellStyle ) { - if( xCellStyle->getXfId() >= 0 ) + sal_Int32 nXfId = xCellStyle->getXfId(); + OUString aStyleName = xCellStyle->calcInitialStyleName(); + // #i1624# #i1768# ignore unnamed user styles + if( (nXfId >= 0) && (aStyleName.getLength() > 0) ) { - maCellStyles[ xCellStyle->getXfId() ] = xCellStyle; + // insert into the XF identifier map + maCellStylesById[ nXfId ] = xCellStyle; + + // find an unused name + OUString aUnusedName = aStyleName; + sal_Int32 nIndex = 0; + while( maCellStylesByName.count( aUnusedName ) > 0 ) + aUnusedName = OUStringBuffer( aStyleName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear(); + + // move old existing style to new unused name, if new style is built-in + if( xCellStyle->isBuiltin() && (aStyleName != aUnusedName) ) + { + CellStyleRef& rxCellStyle = maCellStylesByName[ aUnusedName ]; + rxCellStyle = maCellStylesByName[ aStyleName ]; + // the entry may be empty if the style name has been reserved in c'tor + if( rxCellStyle.get() ) + rxCellStyle->setFinalStyleName( aUnusedName ); + aUnusedName = aStyleName; + } + + // insert new style + maCellStylesByName[ aUnusedName ] = xCellStyle; + xCellStyle->setFinalStyleName( aUnusedName ); + + // remember XF identifier of default cell style if( xCellStyle->isDefaultStyle() ) - mnDefStyleXf = xCellStyle->getXfId(); + mnDefStyleXf = nXfId; } } diff --git a/oox/source/xls/themebuffer.cxx b/oox/source/xls/themebuffer.cxx index b2baefccd5a5..e089e5fece77 100644 --- a/oox/source/xls/themebuffer.cxx +++ b/oox/source/xls/themebuffer.cxx @@ -117,14 +117,6 @@ sal_Int32 ThemeBuffer::getColorByToken( sal_Int32 nToken ) const return getClrScheme().getColor( nToken, nColor ) ? nColor : API_RGB_TRANSPARENT; } -sal_Int32 ThemeBuffer::getColorByIndex( sal_Int32 nIndex ) const -{ - static const sal_Int32 spnColorTokens[] = { - XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2, - XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink }; - return getColorByToken( STATIC_ARRAY_SELECT( spnColorTokens, nIndex, XML_TOKEN_INVALID ) ); -} - // ============================================================================ } // namespace xls diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx index caeacaf6d45d..2d53541b404c 100644 --- a/oox/source/xls/viewsettings.cxx +++ b/oox/source/xls/viewsettings.cxx @@ -56,7 +56,8 @@ using ::com::sun::star::container::XNameContainer; using ::com::sun::star::container::XIndexContainer; using ::com::sun::star::container::XIndexAccess; using ::com::sun::star::document::XViewDataSupplier; -using ::com::sun::star::table::CellAddress; +using ::com::sun::star::table::CellAddress; +using ::oox::core::FilterBase; namespace oox { namespace xls { @@ -199,6 +200,11 @@ sal_Int32 SheetViewModel::getPageBreakZoom() const return getLimitedValue< sal_Int32 >( nZoom, API_ZOOMVALUE_MIN, API_ZOOMVALUE_MAX ); } +sal_Int32 SheetViewModel::getGridColor( const FilterBase& rFilter ) const +{ + return mbDefGridColor ? API_RGB_TRANSPARENT : maGridColor.getColor( rFilter ); +} + const PaneSelectionModel* SheetViewModel::getPaneSelection( sal_Int32 nPaneId ) const { return maPaneSelMap.get( nPaneId ).get(); @@ -500,7 +506,7 @@ void SheetViewSettings::finalizeImport() } // sheet selected (active sheet must be selected) - bool bSelected = xModel->mbSelected || (getSheetIndex() == getViewSettings().getActiveSheetIndex()); + bool bSelected = xModel->mbSelected || (getSheetIndex() == getViewSettings().getActiveCalcSheet()); // visible area and current cursor position (selection not supported via API) CellAddress aFirstPos = xModel->maFirstPos; @@ -560,10 +566,6 @@ void SheetViewSettings::finalizeImport() break; } - // automatic grid color - if( xModel->mbDefGridColor ) - xModel->maGridColor.setAuto(); - // write the sheet view settings into the property sequence PropertyMap aPropMap; aPropMap[ PROP_TableSelected ] <<= bSelected; @@ -581,7 +583,7 @@ void SheetViewSettings::finalizeImport() aPropMap[ PROP_ZoomType ] <<= API_ZOOMTYPE_PERCENT; aPropMap[ PROP_ZoomValue ] <<= static_cast< sal_Int16 >( xModel->getNormalZoom() ); aPropMap[ PROP_PageViewZoomValue ] <<= static_cast< sal_Int16 >( xModel->getPageBreakZoom() ); - aPropMap[ PROP_GridColor ] <<= xModel->maGridColor.getColor( *this ); + aPropMap[ PROP_GridColor ] <<= xModel->getGridColor( getBaseFilter() ); aPropMap[ PROP_ShowPageBreakPreview ] <<= xModel->isPageBreakPreview(); aPropMap[ PROP_ShowFormulas ] <<= xModel->mbShowFormulas; aPropMap[ PROP_ShowGrid ] <<= xModel->mbShowGrid; @@ -692,7 +694,7 @@ void ViewSettings::importWindow1( BiffInputStream& rStrm ) } } -void ViewSettings::setSheetViewSettings( sal_Int32 nSheet, const SheetViewModelRef& rxSheetView, const Any& rProperties ) +void ViewSettings::setSheetViewSettings( sal_Int16 nSheet, const SheetViewModelRef& rxSheetView, const Any& rProperties ) { maSheetViews[ nSheet ] = rxSheetView; maSheetProps[ nSheet ] = rProperties; @@ -701,7 +703,7 @@ void ViewSettings::setSheetViewSettings( sal_Int32 nSheet, const SheetViewModelR void ViewSettings::finalizeImport() { const WorksheetBuffer& rWorksheets = getWorksheets(); - if( rWorksheets.getSheetCount() <= 0 ) return; + if( rWorksheets.getWorksheetCount() <= 0 ) return; // force creation of workbook view model to get the Excel defaults const WorkbookViewModel& rModel = maBookViews.empty() ? createWorkbookView() : *maBookViews.front(); @@ -716,7 +718,7 @@ void ViewSettings::finalizeImport() ContainerHelper::insertByName( xSheetsNC, rWorksheets.getCalcSheetName( aIt->first ), aIt->second ); // use active sheet to set sheet properties that are document-global in Calc - sal_Int32 nActiveSheet = getActiveSheetIndex(); + sal_Int16 nActiveSheet = getActiveCalcSheet(); SheetViewModelRef& rxActiveSheetView = maSheetViews[ nActiveSheet ]; OSL_ENSURE( rxActiveSheetView.get(), "ViewSettings::finalizeImport - missing active sheet view settings" ); if( !rxActiveSheetView ) @@ -735,7 +737,7 @@ void ViewSettings::finalizeImport() aPropMap[ PROP_ShowObjects ] <<= nShowMode; aPropMap[ PROP_ShowCharts ] <<= nShowMode; aPropMap[ PROP_ShowDrawing ] <<= nShowMode; - aPropMap[ PROP_GridColor ] <<= rxActiveSheetView->maGridColor.getColor( *this ); + aPropMap[ PROP_GridColor ] <<= rxActiveSheetView->getGridColor( getBaseFilter() ); aPropMap[ PROP_ShowPageBreakPreview ] <<= rxActiveSheetView->isPageBreakPreview(); aPropMap[ PROP_ShowFormulas ] <<= rxActiveSheetView->mbShowFormulas; aPropMap[ PROP_ShowGrid ] <<= rxActiveSheetView->mbShowGrid; @@ -754,10 +756,9 @@ void ViewSettings::finalizeImport() } } -sal_Int32 ViewSettings::getActiveSheetIndex() const +sal_Int16 ViewSettings::getActiveCalcSheet() const { - sal_Int32 nSheetCount = getLimitedValue< sal_Int32, sal_Int32 >( getWorksheets().getSheetCount(), 1, SAL_MAX_INT32 ); - return maBookViews.empty() ? 0 : getLimitedValue< sal_Int32, sal_Int32 >( maBookViews.front()->mnActiveSheet, 0, nSheetCount - 1 ); + return maBookViews.empty() ? 0 : ::std::max< sal_Int16 >( getWorksheets().getCalcSheetIndex( maBookViews.front()->mnActiveSheet ), 0 ); } // private -------------------------------------------------------------------- diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 1779cb4a7691..6a78c838838e 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -233,13 +233,15 @@ void OoxWorkbookFragment::finalizeImport() some preprocessing in the fragment constructors, e.g. loading the table fragments for all sheets that are needed before the cell formulas are loaded. */ - typedef ::std::map< sal_Int32, FragmentHandlerRef > SheetFragmentMap; - SheetFragmentMap aSheetFragments; + typedef ::std::vector< FragmentHandlerRef > SheetFragmentVector; + SheetFragmentVector aSheetFragments; WorksheetBuffer& rWorksheets = getWorksheets(); - sal_Int32 nSheetCount = rWorksheets.getSheetCount(); - for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet ) + sal_Int32 nWorksheetCount = rWorksheets.getWorksheetCount(); + for( sal_Int32 nWorksheet = 0; nWorksheet < nWorksheetCount; ++nWorksheet ) { - if( const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getSheetRelId( nSheet ) ) ) + sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); + const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getWorksheetRelId( nWorksheet ) ); + if( (nCalcSheet >= 0) && pRelation ) { // get fragment path of the sheet OUString aFragmentPath = getFragmentPathFromRelation( *pRelation ); @@ -247,33 +249,33 @@ void OoxWorkbookFragment::finalizeImport() if( aFragmentPath.getLength() > 0 ) { ::rtl::Reference< OoxWorksheetFragmentBase > xFragment; - double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet); + double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength ); // create the fragment according to the sheet type if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "worksheet" ) ) { - xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nSheet ) ); + xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nCalcSheet ) ); } else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "chartsheet" ) ) { - xFragment.set( new OoxChartsheetFragment( *this, aFragmentPath, xSheetSegment, nSheet ) ); + xFragment.set( new OoxChartsheetFragment( *this, aFragmentPath, xSheetSegment, nCalcSheet ) ); } else if( (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlMacrosheet" )) || (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlIntlMacrosheet" )) ) { - xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nSheet ) ); + xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nCalcSheet ) ); } else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "dialogsheet" ) ) { - xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nSheet ) ); + xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nCalcSheet ) ); } // insert the fragment into the map OSL_ENSURE( xFragment.is(), "OoxWorkbookFragment::finalizeImport - unknown sheet type" ); OSL_ENSURE( !xFragment.is() || xFragment->isValidSheet(), "OoxWorkbookFragment::finalizeImport - missing sheet in document" ); if( xFragment.is() && xFragment->isValidSheet() ) - aSheetFragments[ nSheet ].set( xFragment.get() ); + aSheetFragments.push_back( xFragment.get() ); } } } @@ -283,17 +285,13 @@ void OoxWorkbookFragment::finalizeImport() getTables().finalizeImport(); // load all worksheets - for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet ) + for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt ) { - SheetFragmentMap::iterator aIt = aSheetFragments.find( nSheet ); - if( aIt != aSheetFragments.end() ) - { - OOX_LOADSAVE_TIMER( IMPORTSHEETFRAGMENT ); - // import the sheet fragment - importOoxFragment( aIt->second ); - // delete fragment object, will free all allocated sheet buffers - aSheetFragments.erase( aIt ); - } + OOX_LOADSAVE_TIMER( IMPORTSHEETFRAGMENT ); + // import the sheet fragment + importOoxFragment( *aIt ); + // delete fragment object, will free all allocated sheet buffers + aIt->clear(); } // final conversions, e.g. calculation settings and view settings @@ -368,13 +366,14 @@ bool BiffWorkbookFragment::importFragment() // load sheet fragments (do not return false in bRet on missing/broken sheets) WorksheetBuffer& rWorksheets = getWorksheets(); bool bNextSheet = bRet; - for( sal_Int32 nSheet = 0, nSheetCount = rWorksheets.getSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet ) + for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet ) { // try to start a new sheet fragment - double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet); + double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); BiffFragmentType eSheetFragment = startFragment( getBiff() ); - bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nSheet ); + sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); + bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet ); } } break; @@ -435,19 +434,19 @@ bool BiffWorkbookFragment::importWorkspaceFragment() // load sheet fragments (do not return false in bRet on missing/broken sheets) bool bNextSheet = bRet; - for( sal_Int32 nSheet = 0, nSheetCount = rWorksheets.getSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet ) + for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet ) { // try to start a new sheet fragment (with leading SHEETHEADER record) bNextSheet = mrStrm.startNextRecord() && (mrStrm.getRecId() == BIFF_ID_SHEETHEADER); if( bNextSheet ) { - double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet); + double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); /* Read current sheet name (sheet substreams may not be in the same order as SHEET records are). */ mrStrm.skip( 4 ); OUString aSheetName = mrStrm.readByteStringUC( false, getTextEncoding() ); - sal_Int32 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName ); + sal_Int16 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName ); // load the sheet fragment records BiffFragmentType eSheetFragment = startFragment( getBiff() ); bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCurrSheet ); @@ -630,8 +629,12 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress return bRet; } -bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int32 nSheet ) +bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int16 nCalcSheet ) { + // no Calc sheet - skip the fragment + if( nCalcSheet < 0 ) + return skipFragment(); + // find the sheet type for this fragment WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET; switch( eFragment ) @@ -646,7 +649,7 @@ bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBa /* #i11183# Clear buffers that are used per-sheet, e.g. external links in BIFF4W and BIFF5 files, or defined names in BIFF4W files. */ - createBuffersPerSheet(); + createBuffersPerSheet( nCalcSheet ); // preprocess some records switch( getBiff() ) @@ -656,8 +659,6 @@ bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBa case BIFF3: case BIFF4: { - // set sheet index in defined names buffer to handle built-in names correctly - getDefinedNames().setLocalSheetIndex( nSheet ); // remember current record to seek back below sal_Int64 nRecHandle = mrStrm.getRecHandle(); // import the global records @@ -695,14 +696,14 @@ bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBa case SHEETTYPE_WORKSHEET: case SHEETTYPE_MACROSHEET: case SHEETTYPE_DIALOGSHEET: - xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nSheet ) ); + xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nCalcSheet ) ); break; case SHEETTYPE_CHARTSHEET: - xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nSheet ) ); + xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nCalcSheet ) ); break; case SHEETTYPE_MODULESHEET: case SHEETTYPE_EMPTYSHEET: - xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nSheet ) ); + xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nCalcSheet ) ); break; } // load the sheet fragment records diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx index 7cce9db80352..2b337050a996 100644 --- a/oox/source/xls/workbookhelper.cxx +++ b/oox/source/xls/workbookhelper.cxx @@ -298,8 +298,8 @@ public: Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const; /** Creates and returns a defined name on-the-fly in the Calc document. */ Reference< XNamedRange > createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const; - /** Creates a com.sun.star.style.Style object and returns its final name. */ - Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting ) const; + /** Creates and returns a com.sun.star.style.Style object for cells or pages. */ + Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle ) const; // buffers ---------------------------------------------------------------- @@ -367,7 +367,7 @@ public: /** Enables workbook file mode, used for BIFF4 workspace files. */ void setIsWorkbookFile(); /** Recreates global buffers that are used per sheet in specific BIFF versions. */ - void createBuffersPerSheet(); + void createBuffersPerSheet( sal_Int16 nSheet ); /** Returns the codec helper that stores the encoder/decoder object. */ inline BiffCodecHelper& getCodecHelper() { return *mxCodecHelper; } @@ -563,14 +563,14 @@ Reference< XNamedRange > WorkbookData::createNamedRangeObject( OUString& orName, return xNamedRange; } -Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting ) const +Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle ) const { Reference< XStyle > xStyle; try { Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW ); xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW ); - orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), bRenameOldExisting ); + orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), false ); } catch( Exception& ) { @@ -605,22 +605,28 @@ void WorkbookData::setIsWorkbookFile() mbWorkbook = true; } -void WorkbookData::createBuffersPerSheet() +void WorkbookData::createBuffersPerSheet( sal_Int16 nSheet ) { + // set mnCurrSheet to enable usage of WorkbookHelper::getCurrentSheetIndex() + mnCurrSheet = nSheet; switch( meBiff ) { case BIFF2: case BIFF3: + OSL_ENSURE( mnCurrSheet == 0, "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); + mxDefNames->setLocalCalcSheet( mnCurrSheet ); break; case BIFF4: - // #i11183# sheets in BIFF4W files have own styles or names - if( mbWorkbook ) + OSL_ENSURE( mbWorkbook || (mnCurrSheet == 0), "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); + // #i11183# sheets in BIFF4W files have own styles and names + if( mbWorkbook && (mnCurrSheet > 0) ) { mxStyles.reset( new StylesBuffer( *this ) ); mxDefNames.reset( new DefinedNamesBuffer( *this ) ); mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); } + mxDefNames->setLocalCalcSheet( mnCurrSheet ); break; case BIFF5: @@ -634,6 +640,7 @@ void WorkbookData::createBuffersPerSheet() case BIFF_UNKNOWN: break; } + mnCurrSheet = -1; } // private -------------------------------------------------------------------- @@ -850,7 +857,7 @@ Reference< XNameAccess > WorkbookHelper::getDdeLinks() const return mrBookData.getDdeLinks(); } -Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int32 nSheet ) const +Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const { Reference< XSpreadsheet > xSheet; try @@ -921,9 +928,9 @@ Reference< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orNam return mrBookData.createNamedRangeObject( orName, nNameFlags ); } -Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting ) const +Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const { - return mrBookData.createStyleObject( orStyleName, bPageStyle, bRenameOldExisting ); + return mrBookData.createStyleObject( orStyleName, bPageStyle ); } // buffers -------------------------------------------------------------------- @@ -1078,9 +1085,9 @@ void WorkbookHelper::setIsWorkbookFile() mrBookData.setIsWorkbookFile(); } -void WorkbookHelper::createBuffersPerSheet() +void WorkbookHelper::createBuffersPerSheet( sal_Int16 nSheet ) { - mrBookData.createBuffersPerSheet(); + mrBookData.createBuffersPerSheet( nSheet ); } BiffCodecHelper& WorkbookHelper::getCodecHelper() const diff --git a/oox/source/xls/worksheetbuffer.cxx b/oox/source/xls/worksheetbuffer.cxx index 64e8acbb6c9c..ee2491880c4e 100644 --- a/oox/source/xls/worksheetbuffer.cxx +++ b/oox/source/xls/worksheetbuffer.cxx @@ -38,7 +38,6 @@ #include #include "properties.hxx" #include "oox/helper/attributelist.hxx" -#include "oox/helper/containerhelper.hxx" #include "oox/helper/propertyset.hxx" #include "oox/helper/recordinputstream.hxx" #include "oox/core/filterbase.hxx" @@ -61,21 +60,6 @@ namespace xls { // ============================================================================ -namespace { - -/** Returns the base file name without path and extension. */ -OUString lclGetBaseFileName( const OUString& rUrl ) -{ - sal_Int32 nFileNamePos = ::std::max< sal_Int32 >( rUrl.lastIndexOf( '/' ) + 1, 0 ); - sal_Int32 nExtPos = rUrl.lastIndexOf( '.' ); - if( nExtPos <= nFileNamePos ) nExtPos = rUrl.getLength(); - return rUrl.copy( nFileNamePos, nExtPos - nFileNamePos ); -} - -} // namespace - -// ============================================================================ - SheetInfoModel::SheetInfoModel() : mnSheetId( -1 ), mnState( XML_visible ) @@ -89,11 +73,19 @@ WorksheetBuffer::WorksheetBuffer( const WorkbookHelper& rHelper ) : { } +/*static*/ OUString WorksheetBuffer::getBaseFileName( const OUString& rUrl ) +{ + sal_Int32 nFileNamePos = ::std::max< sal_Int32 >( rUrl.lastIndexOf( '/' ) + 1, 0 ); + sal_Int32 nExtPos = rUrl.lastIndexOf( '.' ); + if( nExtPos <= nFileNamePos ) nExtPos = rUrl.getLength(); + return rUrl.copy( nFileNamePos, nExtPos - nFileNamePos ); +} + void WorksheetBuffer::initializeSingleSheet() { OSL_ENSURE( maSheetInfos.empty(), "WorksheetBuffer::initializeSingleSheet - invalid call" ); SheetInfoModel aModel; - aModel.maName = lclGetBaseFileName( getBaseFilter().getFileUrl() ); + aModel.maName = getBaseFileName( getBaseFilter().getFileUrl() ); insertSheet( aModel ); } @@ -137,107 +129,132 @@ void WorksheetBuffer::importSheet( BiffInputStream& rStrm ) sal_Int16 WorksheetBuffer::insertEmptySheet( const OUString& rPreferredName, bool bVisible ) { - IndexNamePair aIndexName = insertSheet( rPreferredName, SAL_MAX_INT16, bVisible ); - return aIndexName.first; + return createSheet( rPreferredName, SAL_MAX_INT32, bVisible ).first; } -sal_Int32 WorksheetBuffer::getSheetCount() const +sal_Int32 WorksheetBuffer::getWorksheetCount() const { return static_cast< sal_Int32 >( maSheetInfos.size() ); } -OUString WorksheetBuffer::getSheetRelId( sal_Int32 nSheet ) const +OUString WorksheetBuffer::getWorksheetRelId( sal_Int32 nWorksheet ) const { - OUString aRelId; - if( const SheetInfoModel* pModel = getSheetInfo( nSheet ) ) - aRelId = pModel->maRelId; - return aRelId; + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->maRelId : OUString(); } -OUString WorksheetBuffer::getCalcSheetName( sal_Int32 nSheet ) const +sal_Int16 WorksheetBuffer::getCalcSheetIndex( sal_Int32 nWorksheet ) const { - OUString aName; - if( const SheetInfoModel* pModel = getSheetInfo( nSheet ) ) - aName = pModel->maFinalName; - return aName; + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->mnCalcSheet : -1; } -OUString WorksheetBuffer::getCalcSheetName( const OUString& rModelName ) const +OUString WorksheetBuffer::getCalcSheetName( sal_Int32 nWorksheet ) const { - for( SheetInfoModelVec::const_iterator aIt = maSheetInfos.begin(), aEnd = maSheetInfos.end(); aIt != aEnd; ++aIt ) - // TODO: handle encoded characters - if( aIt->maName.equalsIgnoreAsciiCase( rModelName ) ) - return aIt->maFinalName; + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->maCalcName : OUString(); +} + +sal_Int16 WorksheetBuffer::getCalcSheetIndex( const OUString& rWorksheetName ) const +{ + const SheetInfo* pSheetInfo = maSheetInfosByName.get( rWorksheetName ).get(); + return pSheetInfo ? pSheetInfo->mnCalcSheet : -1; +} + +OUString WorksheetBuffer::getCalcSheetName( const OUString& rWorksheetName ) const +{ + if( const SheetInfo* pSheetInfo = maSheetInfosByName.get( rWorksheetName ).get() ) + { + bool bIsQuoted = pSheetInfo->maName != rWorksheetName; + return bIsQuoted ? pSheetInfo->maCalcQuotedName : pSheetInfo->maCalcName; + } return OUString(); } -sal_Int32 WorksheetBuffer::getCalcSheetIndex( const OUString& rModelName ) const -{ - for( SheetInfoModelVec::const_iterator aIt = maSheetInfos.begin(), aEnd = maSheetInfos.end(); aIt != aEnd; ++aIt ) - // TODO: handle encoded characters - if( aIt->maName.equalsIgnoreAsciiCase( rModelName ) ) - return static_cast< sal_Int32 >( aIt - maSheetInfos.begin() ); - return -1; -} - // private -------------------------------------------------------------------- -const SheetInfoModel* WorksheetBuffer::getSheetInfo( sal_Int32 nSheet ) const +namespace { + +OUString lclQuoteName( const OUString& rName ) { - return ContainerHelper::getVectorElement( maSheetInfos, nSheet ); + OUStringBuffer aBuffer( rName ); + // duplicate all quote characters + for( sal_Int32 nPos = aBuffer.getLength() - 1; nPos >= 0; --nPos ) + if( aBuffer.charAt( nPos ) == '\'' ) + aBuffer.insert( nPos, sal_Unicode( '\'' ) ); + // add outer quotes and return + return aBuffer.insert( 0, sal_Unicode( '\'' ) ).append( sal_Unicode( '\'' ) ).makeStringAndClear(); } -WorksheetBuffer::IndexNamePair WorksheetBuffer::insertSheet( const OUString& rPreferredName, sal_Int16 nSheet, bool bVisible ) +} // namespace + +WorksheetBuffer::SheetInfo::SheetInfo( const SheetInfoModel& rModel, sal_Int16 nCalcSheet, const OUString& rCalcName ) : + SheetInfoModel( rModel ), + maCalcName( rCalcName ), + maCalcQuotedName( lclQuoteName( rCalcName ) ), + mnCalcSheet( nCalcSheet ) +{ +} + +WorksheetBuffer::IndexNamePair WorksheetBuffer::createSheet( const OUString& rPreferredName, sal_Int32 nSheetPos, bool bVisible ) { - IndexNamePair aIndexName; - aIndexName.first = -1; - aIndexName.second = (rPreferredName.getLength() == 0) ? CREATE_OUSTRING( "Sheet" ) : rPreferredName; try { Reference< XSpreadsheets > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW ); Reference< XIndexAccess > xSheetsIA( xSheets, UNO_QUERY_THROW ); Reference< XNameAccess > xSheetsNA( xSheets, UNO_QUERY_THROW ); + sal_Int16 nCalcSheet = -1; + OUString aSheetName = (rPreferredName.getLength() == 0) ? CREATE_OUSTRING( "Sheet" ) : rPreferredName; PropertySet aPropSet; - if( nSheet < xSheetsIA->getCount() ) + if( nSheetPos < xSheetsIA->getCount() ) { + nCalcSheet = static_cast< sal_Int16 >( nSheetPos ); // existing sheet - try to rename - Reference< XNamed > xSheetName( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW ); - if( xSheetName->getName() != aIndexName.second ) + Reference< XNamed > xSheetName( xSheetsIA->getByIndex( nSheetPos ), UNO_QUERY_THROW ); + if( xSheetName->getName() != aSheetName ) { - aIndexName.second = ContainerHelper::getUnusedName( xSheetsNA, aIndexName.second, ' ' ); - xSheetName->setName( aIndexName.second ); + aSheetName = ContainerHelper::getUnusedName( xSheetsNA, aSheetName, ' ' ); + xSheetName->setName( aSheetName ); } aPropSet.set( xSheetName ); } else { + nCalcSheet = static_cast< sal_Int16 >( xSheetsIA->getCount() ); // new sheet - insert with unused name - aIndexName.second = ContainerHelper::getUnusedName( xSheetsNA, aIndexName.second, ' ' ); - nSheet = static_cast< sal_Int16 >( xSheetsIA->getCount() ); - xSheets->insertNewByName( aIndexName.second, nSheet ); - aPropSet.set( xSheetsIA->getByIndex( nSheet ) ); + aSheetName = ContainerHelper::getUnusedName( xSheetsNA, aSheetName, ' ' ); + xSheets->insertNewByName( aSheetName, nCalcSheet ); + aPropSet.set( xSheetsIA->getByIndex( nCalcSheet ) ); } // sheet properties aPropSet.setProperty( PROP_IsVisible, bVisible ); // return final sheet index if sheet exists - aIndexName.first = nSheet; + return IndexNamePair( nCalcSheet, aSheetName ); } catch( Exception& ) { - OSL_ENSURE( false, "WorksheetBuffer::insertSheet - cannot insert or rename worksheet" ); + OSL_ENSURE( false, "WorksheetBuffer::createSheet - cannot insert or rename worksheet" ); } - return aIndexName; + return IndexNamePair( -1, OUString() ); } void WorksheetBuffer::insertSheet( const SheetInfoModel& rModel ) { - sal_Int16 nSheet = static_cast< sal_Int16 >( maSheetInfos.size() ); - maSheetInfos.push_back( rModel ); - IndexNamePair aIndexName = insertSheet( rModel.maName, nSheet, rModel.mnState == XML_visible ); - if( aIndexName.first >= 0 ) - maSheetInfos.back().maFinalName = aIndexName.second; + sal_Int32 nWorksheet = static_cast< sal_Int32 >( maSheetInfos.size() ); + IndexNamePair aIndexName = createSheet( rModel.maName, nWorksheet, rModel.mnState == XML_visible ); + ::boost::shared_ptr< SheetInfo > xSheetInfo( new SheetInfo( rModel, aIndexName.first, aIndexName.second ) ); + maSheetInfos.push_back( xSheetInfo ); + maSheetInfosByName[ rModel.maName ] = xSheetInfo; + maSheetInfosByName[ lclQuoteName( rModel.maName ) ] = xSheetInfo; +} + +bool WorksheetBuffer::SheetNameCompare::operator()( const OUString& rName1, const OUString& rName2 ) const +{ + // there is no wrapper in rtl::OUString, TODO: compare with collator + return ::rtl_ustr_compareIgnoreAsciiCase_WithLength( + rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0; } // ============================================================================ diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index 4b754114b031..ed8907cb5f03 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -228,7 +228,7 @@ void OoxDataValidationsContext::importDataValidation( RecordInputStream& rStrm ) // ============================================================================ OoxWorksheetFragment::OoxWorksheetFragment( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : OoxWorksheetFragmentBase( rHelper, rFragmentPath, xProgressBar, eSheetType, nSheet ) { // import data tables related to this worksheet @@ -741,7 +741,7 @@ void OoxWorksheetFragment::importEmbeddedOleData( StreamDataSequence& orEmbedded // ============================================================================ -BiffWorksheetFragment::BiffWorksheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : +BiffWorksheetFragment::BiffWorksheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : BiffWorksheetFragmentBase( rParent, xProgressBar, eSheetType, nSheet ) { } diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index be8ac3d359db..ab2d5c1b1946 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -362,7 +362,7 @@ public: const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); /** Returns true, if this helper refers to an existing Calc sheet. */ inline bool isValidSheet() const { return mxSheet.is(); } @@ -522,8 +522,10 @@ private: /** Inserts all imported hyperlinks into their cell ranges. */ void finalizeHyperlinkRanges() const; + /** Generates the final URL for the passed hyperlink. */ + OUString getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const; /** Inserts a hyperlinks into the specified cell. */ - void finalizeHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const; + void insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const; /** Inserts all imported data validations into their cell ranges. */ void finalizeValidationRanges() const; @@ -593,7 +595,7 @@ private: // ---------------------------------------------------------------------------- -WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : +WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : WorkbookHelper( rHelper ), maTrueFormula( CREATE_OUSTRING( "=TRUE()" ) ), maFalseFormula( CREATE_OUSTRING( "=FALSE()" ) ), @@ -608,10 +610,9 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBar maSheetViewSett( *this ), mxProgressBar( xProgressBar ), meSheetType( eSheetType ), - mnSheet( static_cast< sal_Int16 >( nSheet ) ), + mnSheet( nSheet ), mbHasDefWidth( false ) { - OSL_ENSURE( nSheet <= SAL_MAX_INT16, "WorksheetData::WorksheetData - invalid sheet index" ); mxSheet = getSheetFromDoc( nSheet ); if( !mxSheet.is() ) mnSheet = -1; @@ -978,14 +979,11 @@ void WorksheetData::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, s void WorksheetData::initializeWorksheetImport() { -#if OOX_XLS_USE_DEFAULT_STYLE -#else // set default cell style for unused cells PropertySet aPropSet( mxSheet ); aPropSet.setProperty( PROP_CellStyle, getStyles().getDefaultStyleName() ); -#endif - /* remember current sheet index in global data, needed by some global + /* Remember current sheet index in global data, needed by some global objects, e.g. the chart converter. */ setCurrentSheetIndex( mnSheet ); } @@ -1006,9 +1004,9 @@ void WorksheetData::finalizeWorksheetImport() convertColumns(); convertRows(); lclUpdateProgressBar( mxFinalProgress, 0.75 ); - maComments.finalizeImport(); finalizeDrawing(); finalizeVmlDrawing(); + maComments.finalizeImport(); // after VML drawing lclUpdateProgressBar( mxFinalProgress, 1.0 ); // reset current sheet index in global data @@ -1169,42 +1167,44 @@ void WorksheetData::finalizeHyperlinkRanges() const { for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt ) { - OUStringBuffer aUrlBuffer; - if( aIt->maTarget.getLength() > 0 ) - aUrlBuffer.append( getBaseFilter().getAbsoluteUrl( aIt->maTarget ) ); - if( aIt->maLocation.getLength() > 0 ) - aUrlBuffer.append( sal_Unicode( '#' ) ).append( aIt->maLocation ); - OUString aUrl = aUrlBuffer.makeStringAndClear(); + OUString aUrl = getHyperlinkUrl( *aIt ); + // try to insert URL into each cell of the range if( aUrl.getLength() > 0 ) - { - // convert '#SheetName!A1' to '#SheetName.A1' - if( aUrl[ 0 ] == '#' ) - { - sal_Int32 nSepPos = aUrl.lastIndexOf( '!' ); - if( nSepPos > 0 ) - { - // replace the exclamation mark with a period - aUrl = aUrl.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) ); - // #i66592# convert sheet names that have been renamed on import - bool bQuotedName = (nSepPos > 3) && (aUrl[ 1 ] == '\'') && (aUrl[ nSepPos - 1 ] == '\''); - sal_Int32 nNamePos = bQuotedName ? 2 : 1; - sal_Int32 nNameLen = nSepPos - (bQuotedName ? 3 : 1); - OUString aSheetName = aUrl.copy( nNamePos, nNameLen ); - OUString aCalcName = getWorksheets().getCalcSheetName( aSheetName ); - if( aCalcName.getLength() > 0 ) - aUrl = aUrl.replaceAt( nNamePos, nNameLen, aCalcName ); - } - } - - // try to insert URL into each cell of the range for( CellAddress aAddress( mnSheet, aIt->maRange.StartColumn, aIt->maRange.StartRow ); aAddress.Row <= aIt->maRange.EndRow; ++aAddress.Row ) for( aAddress.Column = aIt->maRange.StartColumn; aAddress.Column <= aIt->maRange.EndColumn; ++aAddress.Column ) - finalizeHyperlink( aAddress, aUrl ); - } + insertHyperlink( aAddress, aUrl ); } } -void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const +OUString WorksheetData::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const +{ + OUStringBuffer aUrlBuffer; + if( rHyperlink.maTarget.getLength() > 0 ) + aUrlBuffer.append( getBaseFilter().getAbsoluteUrl( rHyperlink.maTarget ) ); + if( rHyperlink.maLocation.getLength() > 0 ) + aUrlBuffer.append( sal_Unicode( '#' ) ).append( rHyperlink.maLocation ); + OUString aUrl = aUrlBuffer.makeStringAndClear(); + + // convert '#SheetName!A1' to '#SheetName.A1' + if( (aUrl.getLength() > 0) && (aUrl[ 0 ] == '#') ) + { + sal_Int32 nSepPos = aUrl.lastIndexOf( '!' ); + if( nSepPos > 0 ) + { + // replace the exclamation mark with a period + aUrl = aUrl.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) ); + // #i66592# convert sheet names that have been renamed on import + OUString aSheetName = aUrl.copy( 1, nSepPos - 1 ); + OUString aCalcName = getWorksheets().getCalcSheetName( aSheetName ); + if( aCalcName.getLength() > 0 ) + aUrl = aUrl.replaceAt( 1, nSepPos - 1, aCalcName ); + } + } + + return aUrl; +} + +void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const { Reference< XCell > xCell = getCell( rAddress ); if( xCell.is() ) switch( xCell->getType() ) @@ -1217,7 +1217,7 @@ void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUStri { // create a URL field object and set its properties Reference< XTextContent > xUrlField( getDocumentFactory()->createInstance( maUrlTextField ), UNO_QUERY ); - OSL_ENSURE( xUrlField.is(), "WorksheetData::finalizeHyperlink - cannot create text field" ); + OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" ); if( xUrlField.is() ) { // properties of the URL field @@ -1233,7 +1233,7 @@ void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUStri } catch( const Exception& ) { - OSL_ENSURE( false, "WorksheetData::finalizeHyperlink - cannot insert text field" ); + OSL_ENSURE( false, "WorksheetData::insertHyperlink - cannot insert text field" ); } } } @@ -1246,7 +1246,7 @@ void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUStri case ::com::sun::star::table::CellContentType_VALUE: { Reference< XFormulaTokens > xTokens( xCell, UNO_QUERY ); - OSL_ENSURE( xTokens.is(), "WorksheetHelper::finalizeHyperlink - missing formula interface" ); + OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula interface" ); if( xTokens.is() ) { SimpleFormulaContext aContext( xTokens, false, false ); @@ -2072,7 +2072,7 @@ WorksheetDataOwner::~WorksheetDataOwner() // ---------------------------------------------------------------------------- -WorksheetHelperRoot::WorksheetHelperRoot( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : +WorksheetHelperRoot::WorksheetHelperRoot( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : prv::WorksheetDataOwner( prv::WorksheetDataRef( new WorksheetData( rHelper, xProgressBar, eSheetType, nSheet ) ) ), WorksheetHelper( *mxSheetData ) { diff --git a/oox/workben/pagesize/excel_pagesize.txt b/oox/workben/pagesize/excel_pagesize.txt deleted file mode 100644 index e6d8a05583cb..000000000000 --- a/oox/workben/pagesize/excel_pagesize.txt +++ /dev/null @@ -1,66 +0,0 @@ -1 = Letter paper (8.5 in. by 11 in.) -2 = Letter small paper (8.5 in. by 11 in.) -3 = Tabloid paper (11 in. by 17 in.) -4 = Ledger paper (17 in. by 11 in.) -5 = Legal paper (8.5 in. by 14 in.) -6 = Statement paper (5.5 in. by 8.5 in.) -7 = Executive paper (7.25 in. by 10.5 in.) -8 = A3 paper (297 mm by 420 mm) -9 = A4 paper (210 mm by 297 mm) -10 = A4 small paper (210 mm by 297 mm) -11 = A5 paper (148 mm by 210 mm) -12 = B4 paper (250 mm by 353 mm) -13 = B5 paper (176 mm by 250 mm) -14 = Folio paper (8.5 in. by 13 in.) -15 = Quarto paper (215 mm by 275 mm) -16 = Standard paper (10 in. by 14 in.) -17 = Standard paper (11 in. by 17 in.) -18 = Note paper (8.5 in. by 11 in.) -19 = #9 envelope (3.875 in. by 8.875 in.) -20 = #10 envelope (4.125 in. by 9.5 in.) -21 = #11 envelope (4.5 in. by 10.375 in.) -22 = #12 envelope (4.75 in. by 11 in.) -23 = #14 envelope (5 in. by 11.5 in.) -24 = C paper (17 in. by 22 in.) -25 = D paper (22 in. by 34 in.) -26 = E paper (34 in. by 44 in.) -27 = DL envelope (110 mm by 220 mm) -28 = C5 envelope (162 mm by 229 mm) -29 = C3 envelope (324 mm by 458 mm) -30 = C4 envelope (229 mm by 324 mm) -31 = C6 envelope (114 mm by 162 mm) -32 = C65 envelope (114 mm by 229 mm) -33 = B4 envelope (250 mm by 353 mm) -34 = B5 envelope (176 mm by 250 mm) -35 = B6 envelope (176 mm by 125 mm) -36 = Italy envelope (110 mm by 230 mm) -37 = Monarch envelope (3.875 in. by 7.5 in.). -38 = 6 3/4 envelope (3.625 in. by 6.5 in.) -39 = US standard fanfold (14.875 in. by 11 in.) -40 = German standard fanfold (8.5 in. by 12 in.) -41 = German legal fanfold (8.5 in. by 13 in.) -42 = ISO B4 (250 mm by 353 mm) -43 = Japanese double postcard (200 mm by 148 mm) -44 = Standard paper (9 in. by 11 in.) -45 = Standard paper (10 in. by 11 in.) -46 = Standard paper (15 in. by 11 in.) -47 = Invite envelope (220 mm by 220 mm) -50 = Letter extra paper (9.275 in. by 12 in.) -51 = Legal extra paper (9.275 in. by 15 in.) -52 = Tabloid extra paper (11.69 in. by 18 in.) -53 = A4 extra paper (236 mm by 322 mm) -54 = Letter transverse paper (8.275 in. by 11 in.) -55 = A4 transverse paper (210 mm by 297 mm) -56 = Letter extra transverse paper (9.275 in. by 12 in.) -57 = SuperA/SuperA/A4 paper (227 mm by 356 mm) -58 = SuperB/SuperB/A3 paper (305 mm by 487 mm) -59 = Letter plus paper (8.5 in. by 12.69 in.) -60 = A4 plus paper (210 mm by 330 mm) -61 = A5 transverse paper (148 mm by 210 mm) -62 = JIS B5 transverse paper (182 mm by 257 mm) -63 = A3 extra paper (322 mm by 445 mm) -64 = A5 extra paper (174 mm by 235 mm) -65 = ISO B5 extra paper (201 mm by 276 mm) -66 = A2 paper (420 mm by 594 mm) -67 = A3 transverse paper (297 mm by 420 mm) -68 = A3 extra transverse paper (322 mm by 445 mm) diff --git a/oox/workben/pagesize/parsePageSize.py b/oox/workben/pagesize/parsePageSize.py deleted file mode 100755 index 8b536baaeba4..000000000000 --- a/oox/workben/pagesize/parsePageSize.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python - -import sys - -class PageSize(object): - def __init__ (self): - self.index = 0 - self.list = [] - - def parseLine (self, line): - lhs, rhs = line.split("=") - name, size = rhs.split("(") - index = int(lhs) - name = name.strip() - size = size[:size.rfind(")")] - words = size.split() - width, height = float(words[0]), float(words[3]) - if words[1] != words[4]: - print "unit mismatch", words[1], words[4] - sys.exit(1) - unit = '' - if words[1] == 'mm': - unit = 'mm' - elif words[1] == 'in.': - unit = 'inches' - else: - print "unknown unit:", words[1] - sys.exit(1) - - item = {'index': index, 'name': name, 'width': width, 'height': height, 'unit': unit} - self.list.append(item) - - def output (self): - print "static const XmlPaperSize PaperSizeTable[] =" - print "{" - line = " { 0, 0 }," - while len(line) <= 60: - line += ' ' - line += "// 0 - (undefined)" - print line - n = len(self.list) - for i in xrange(0, n): - if self.list[i]['unit'] == 'mm': - macro = 'MM2MM100' - elif self.list[i]['unit'] == 'inches': - macro = 'IN2MM100' - else: - print "unknown unit:", self.list[i]['unit'] - sys.exit(1) - line = " " - line += '{ ' + macro + "( %g )"%self.list[i]['width'] + ',' - while len(line) <= 28: - line += ' ' - line += macro + "( %g )"%self.list[i]['height'] - while len(line) <= 48: - line += ' ' - line += '}' - if i != n - 1: - line += "," - while len(line) <= 60: - line += ' ' - if self.list[i]['index'] < 10: - line += "// %d - "%self.list[i]['index'] + self.list[i]['name'] - else: - line += "// %d - "%self.list[i]['index'] + self.list[i]['name'] - - print line - print "};" - return - - -if len(sys.argv) < 2: - sys.exit(1) - -obj = PageSize() -for line in open(sys.argv[1], 'r').readlines(): - obj.parseLine(line) -obj.output() From e83f65005a2732dcc3107533cb0cbda5616558b0 Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Thu, 17 Sep 2009 13:53:54 +0000 Subject: [PATCH 11/16] CWS-TOOLING: integrate CWS encsig09 2009-09-14 15:11:29 +0200 oc r276125 : #i105049# MacroSignatur needs Macro 2009-09-09 17:09:46 +0200 jl r276005 : #i103989# could not signe encrypted doc containing a formular object 2009-09-09 13:11:24 +0200 jl r275985 : #i103989# could not signe encrypted doc containing a formular object 2009-09-08 15:54:02 +0200 mav r275934 : #i103906# fix the automation test scenario ( tempfile should be writable for the user ) 2009-09-07 14:01:39 +0200 mav r275895 : #i103906# fix the problem with reload 2009-09-07 09:34:48 +0200 mav r275871 : #i104786# do the ODF version check only for ODF documents 2009-09-07 08:19:06 +0200 mav r275870 : #i104389# fix text 2009-09-06 22:24:21 +0200 mav r275867 : #i104786# check the consistency of ODF version 2009-09-06 22:23:24 +0200 mav r275866 : #i104786# check the consistency of ODF version 2009-09-06 22:23:00 +0200 mav r275865 : #i104786# check the consistency of ODF version 2009-09-06 22:22:36 +0200 mav r275864 : #i104786# check the consistency of ODF version 2009-09-06 22:22:03 +0200 mav r275863 : #i104786# check the consistency of ODF version 2009-09-02 17:09:30 +0200 mav r275722 : #i104715# let repairing mechanics use the streams correctly 2009-09-01 16:52:49 +0200 mav r275670 : #i104389# notify user not to trust the corrupted document 2009-09-01 16:31:37 +0200 mav r275668 : #i104389# use vnd.sun.star.zip: protocol to access zip files 2009-09-01 16:30:32 +0200 mav r275667 : #i104389# use vnd.sun.star.zip: protocol to access zip files 2009-09-01 16:22:13 +0200 jl r275666 : #i104339# small content change 2009-09-01 14:20:42 +0200 jl r275660 : #i103519# remove some debug output 2009-09-01 13:51:52 +0200 jl r275659 : #i103519# NSS uses '\' for escaping in distinguished names 2009-09-01 12:49:47 +0200 mav r275655 : #i104389# use zip-mode to read from jar files 2009-09-01 12:40:22 +0200 mav r275653 : #i104389# use zip-mode to read from jar files 2009-09-01 12:32:29 +0200 mav r275652 : #i104389# use constants 2009-08-31 21:58:00 +0200 mav r275637 : #i10000# fix warning 2009-08-31 21:11:17 +0200 mav r275636 : #i104227# adding of scripting signature removes the document signature 2009-08-31 20:55:05 +0200 mav r275635 : #i103905# ZipStorage supports Compressed property 2009-08-31 20:53:55 +0200 mav r275634 : #i103905# adjust macro signature transfer to usage of ZipStorage 2009-08-31 15:30:49 +0200 jl r275609 : #i103989# warning is shown as long the user does not click 'OK' 2009-08-31 14:36:10 +0200 jl r275608 : #i103989# changed warning text when signing macro and there is a document signature. This warning is only displayed once 2009-08-31 13:34:41 +0200 mav r275603 : #i104452# disable macros in repaired documents 2009-08-31 13:33:42 +0200 mav r275602 : #i104452# disable macros in repaired documents 2009-08-31 13:03:56 +0200 jl r275600 : #i45212# signature dialog could not be started when using read-only documents 2009-08-31 09:26:13 +0200 mav r275583 : #i104578# store the additional entry as the last one to workaround parsing problem in OOo3.1 and later 2009-08-30 20:54:25 +0200 mav r275562 : #i10000# adopt for unix 2009-08-30 10:56:00 +0200 mav r275561 : CWS-TOOLING: rebase CWS encsig09 to trunk@275331 (milestone: DEV300:m56) 2009-08-28 16:34:00 +0200 mav r275539 : #i104578# write necessary info in manifest.xml for ODF1.2 encrypted document 2009-08-28 14:04:22 +0200 mav r275533 : #104587# fix handling of readonly streams 2009-08-28 13:58:10 +0200 mav r275531 : #i104389# fix the broken document handling 2009-08-28 11:40:39 +0200 mav r275522 : #i104389# fix the signature streams check 2009-08-27 21:48:12 +0200 mav r275509 : #i103927# show the warning 2009-08-27 21:47:48 +0200 mav r275508 : #i103927# show the warning 2009-08-27 16:45:59 +0200 jl r275495 : #i45212# remove unused variable 2009-08-27 16:34:00 +0200 jl r275494 : #i103989# 2009-08-27 13:54:28 +0200 jl r275482 : #i103519# fixed replacement of 'S' by 'ST' 2009-08-27 12:32:21 +0200 mav r275472 : #i10000# fix warning 2009-08-27 11:58:11 +0200 mav r275467 : #i104389# handle the entry path correctly 2009-08-26 17:18:35 +0200 jl r275438 : #i103519# subject and issuer distinguished names were not properly displayed. The strings were obtained by system functions (Windows, NSS), which use quotes to escape the values, when they contain special characters 2009-08-26 11:00:20 +0200 mav r275403 : #i10000# fix warnings 2009-08-26 08:25:45 +0200 mav r275392 : #i10000# fix warning 2009-08-26 08:02:22 +0200 mav r275391 : #i10000# adopt for linux 2009-08-26 07:40:30 +0200 mav r275390 : #i10000# fix warning 2009-08-26 07:35:28 +0200 mav r275389 : #i10000# use correct include file name 2009-08-25 15:01:41 +0200 jl r275356 : #i103989# better check for mimetype of streams 2009-08-25 09:07:09 +0200 mav r275335 : CWS-TOOLING: rebase CWS encsig09 to trunk@274622 (milestone: DEV300:m54) 2009-08-24 18:17:02 +0200 mav r275329 : #i103927# check the nonencrypted streams 2009-08-24 18:14:14 +0200 mav r275328 : #i103927# check the nonencrypted streams 2009-08-24 17:59:34 +0200 mav r275327 : #i103927#,#i104389# check the package consistency and nonencrypted streams 2009-08-24 16:18:28 +0200 jl r275323 : #i103989# added comment 2009-08-24 13:08:47 +0200 jl r275305 : #i45212# #i66276# only write the X509Certificate element once and allow to add remove several certificates at a time 2009-08-21 12:57:28 +0200 ufi r275239 : 104339 2009-08-21 08:39:05 +0200 jl r275213 : #i10398# comparing URIs of signed files with the 'element list' 2009-08-20 13:39:47 +0200 jl r275178 : #i10398# displaying 'new partially signed' status in the status bar 2009-08-20 13:35:39 +0200 jl r275177 : #i10398# displaying 'new partially signed' status in the status bar 2009-08-20 13:29:06 +0200 jl r275176 : #i10398# displaying 'new partially signed' status in the status bar 2009-08-20 13:26:21 +0200 jl r275175 : #i10398# displaying 'new partially signed' status in the status bar 2009-08-20 12:05:09 +0200 ufi r275170 : i104339 2009-08-19 12:24:54 +0200 jl r275146 : #i10398# displaying 'old signature' icon and status in signature dialog 2009-08-18 15:18:48 +0200 jl r275111 : #i103989# document signatures containing manifest.xml are now validated according to the final ODF1.2 spec 2009-08-18 11:41:06 +0200 mav r275087 : #i103927# detect if encrypted ODF1.2 document contains nonencrypted streams 2009-08-18 11:35:13 +0200 mav r275085 : #i103927# detect if encrypted ODF1.2 document contains nonencrypted streams 2009-08-14 17:32:41 +0200 jl r274999 : #i103989# using c14n tranformation for XML streams 2009-08-14 15:27:43 +0200 jl r274987 : #i103989# remove special handling for encrypted document streams in UriBindingHelper::OpenInputStream, since we use zip storage this is not necessary anymore 2009-08-14 15:08:10 +0200 jl r274983 : #i103989# Showing a message when adding or removing a macro signature, that the document signature will be removed 2009-08-14 14:57:27 +0200 jl r274982 : #i103989# accesing Sequence at invalid index 2009-08-11 08:55:02 +0200 mav r274846 : #i103905# let signing service know if there is already a valid document signature 2009-08-10 11:33:37 +0200 jl r274799 : #i103905# do not truncate the stream 2009-08-10 10:43:47 +0200 mav r274797 : #i103905# provide the storage version 2009-08-07 16:58:46 +0200 jl r274780 : #i103989# 2009-08-07 16:56:19 +0200 jl r274779 : #i103989# using odf version string etc. 2009-08-07 15:20:53 +0200 mav r274771 : #i103905# provide the storage version 2009-08-07 15:19:12 +0200 mav r274770 : #i103905# provide the storage version 2009-08-07 12:41:45 +0200 mav r274758 : #103930# do not store thumbnail in case of encrypted document 2009-08-07 12:36:52 +0200 mav r274757 : #i103905# provide the storage version 2009-08-07 12:15:54 +0200 mav r274754 : #i103760# the signed state is not lost on saving 2009-08-07 12:06:19 +0200 mav r274753 : #i103760# avoid warning regarding signature removal on export 2009-08-07 12:06:01 +0200 mav r274752 : #i103760# avoid warning regarding signature removal on export 2009-08-06 08:47:34 +0200 mav r274703 : #i103905# allow to transport ODF version to the signing component 2009-08-05 21:34:42 +0200 mav r274701 : #i103905# allow to transport ODF version to the signing component 2009-08-05 15:48:17 +0200 mav r274683 : #i103905# allow to transport ODF version to the signing component 2009-08-05 14:58:12 +0200 jl r274673 : #i103989# documentsignature now signes all streams except documentsignatures.xml, all streams are processed as binary files 2009-08-05 12:00:32 +0200 mav r274648 : #i103905# allow to transport ODF version to the signing component 2009-08-04 10:57:04 +0200 jl r274612 : #i103989# added XInitialization 2009-07-31 10:32:27 +0200 mav r274516 : #i103905# use zip storage to sign documents 2009-07-30 14:01:33 +0200 mav r274489 : #i103906# optimize the usage of temporary medium 2009-07-30 14:00:28 +0200 mav r274488 : #i103906# optimize the usage of temporary medium 2009-07-30 13:59:09 +0200 mav r274487 : #i103906# optimize the usage of temporary medium 2009-07-30 13:50:44 +0200 mav r274485 : #i103906# optimize the usage of temporary medium 2009-07-30 13:49:53 +0200 mav r274484 : #i103906# optimize the usage of temporary medium 2009-07-30 13:49:13 +0200 mav r274483 : #i103906# optimize the usage of temporary medium 2009-07-30 13:47:09 +0200 mav r274482 : #i103905#,#i103906# let the signing process use zip-storage; optimize the usage of temporary medium 2009-07-21 09:10:31 +0200 mav r274159 : CWS-TOOLING: rebase CWS encsig09 to trunk@273468 (milestone: DEV300:m51) 2009-05-05 08:39:01 +0200 mav r271496 : #i100832# allow to sign macros only when there are any --- filter/source/xsltdialog/xmlfilterjar.cxx | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/filter/source/xsltdialog/xmlfilterjar.cxx b/filter/source/xsltdialog/xmlfilterjar.cxx index d62da836236c..9f21a840cc1c 100644 --- a/filter/source/xsltdialog/xmlfilterjar.cxx +++ b/filter/source/xsltdialog/xmlfilterjar.cxx @@ -35,15 +35,15 @@ #include #include #include -#ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_ #include -#endif +#include #include #include #include #include +#include #include #include #include @@ -62,6 +62,7 @@ using namespace rtl; using namespace osl; using namespace comphelper; +using namespace com::sun::star; using namespace com::sun::star::lang; using namespace com::sun::star::frame; using namespace com::sun::star::uno; @@ -173,9 +174,15 @@ bool XMLFilterJarHelper::savePackage( const OUString& rPackageURL, const XMLFilt // create the package jar file - Sequence< Any > aArguments( 1 ); + Sequence< Any > aArguments( 2 ); aArguments[ 0 ] <<= rPackageURL; + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + Reference< XHierarchicalNameAccess > xIfc( mxMSF->createInstanceWithArguments( rtl::OUString::createFromAscii( @@ -270,9 +277,15 @@ void XMLFilterJarHelper::openPackage( const OUString& rPackageURL, XMLFilterVect { // create the package jar file - Sequence< Any > aArguments( 1 ); + Sequence< Any > aArguments( 2 ); aArguments[ 0 ] <<= rPackageURL; + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + Reference< XHierarchicalNameAccess > xIfc( mxMSF->createInstanceWithArguments( rtl::OUString::createFromAscii( From 59791cfb87dc386f5cc0b479027e4f2f0d696bb0 Mon Sep 17 00:00:00 2001 From: Jens-Heiner Rechtien Date: Thu, 17 Sep 2009 16:34:35 +0000 Subject: [PATCH 12/16] CWS-TOOLING: integrate CWS vcl105 2009-09-07 Philipp Lohmann fix path issues 2009-09-07 hdu #i104525# Aqua: workaround OSX problem in RecentlyUsed list 2009-09-07 Philipp Lohmann add missing dollar sign 2009-09-07 Philipp Lohmann remove warnings 2009-09-07 hdu #i104011# need to use real-vals in cff-subsetter for some fonts 2009-09-05 Philipp Lohmann #i103674# less noise 2009-09-05 Philipp Lohmann #i103674# add garmin communicator to list of crashing plugins 2009-09-05 Philipp Lohmann #i103674# confiuration option to disable plugin support 2009-09-05 Philipp Lohmann merge #i102735# 2009-09-05 Philipp Lohmann #i88802# enable transparency resolution for PDF/A 2009-09-04 Philipp Lohmann rebase to DEV300m57 2009-09-03 Philipp Lohmann #i90083# fix a typo 2009-09-03 Philipp Lohmann merge 2009-09-03 Philipp Lohmann #i90083# workaround for application frame switching 2009-09-03 hdu #i104720# better description for --without-fonts configure option 2009-09-02 hdu #i104723# update third-party fonts 2009-09-02 hdu #i104723# update default-installed Liberation fonts from 1.04->1.05.1.20090721 2009-09-02 hdu #i104720# update default-installed DejaVu fonts from 2.21->2.30 2009-09-02 hdu #i89682# add Gentium fonts to default installation 2009-09-02 hdu #i89682# add Gentium fonts to default installation 2009-09-01 hdu #i104011# fix vertical offset in PDF-export of USP-layouted text 2009-08-27 Philipp Lohmann #i102033# ignore transients 2009-08-27 Philipp Lohmann merge 2009-08-27 Philipp Lohmann fix warning, remove crappy early exits 2009-08-26 Philipp Lohmann #i63494# user event time for generic plugin always regotten to work around metacity 2009-08-26 Philipp Lohmann merge 2009-08-26 Philipp Lohmann #i104526# fix string conversion 2009-08-25 Philipp Lohmann #b6855541# show newly added driver, repair remove driver 2009-08-25 Philipp Lohmann #i104469# maximizing issue (thanks haggai) --- filter/source/pdf/pdfexport.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index ceff18507db9..deb7429e743a 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -1059,7 +1059,6 @@ sal_Bool PDFExport::ImplWriteActions( PDFWriter& rWriter, PDFExtOutDevData* pPDF GDIMetaFile aMtf; bool bTransparenciesRemoved = false; - #if 0 if( mbRemoveTransparencies ) { bTransparenciesRemoved = rWriter.GetReferenceDevice()-> @@ -1067,7 +1066,6 @@ sal_Bool PDFExport::ImplWriteActions( PDFWriter& rWriter, PDFExtOutDevData* pPDF false, true, mbReduceImageResolution ); } else - #endif { aMtf = rInMtf; } From 776265384b8807df3e0853e9990cfb85ee8b615e Mon Sep 17 00:00:00 2001 From: Jens-Heiner Rechtien Date: Fri, 18 Sep 2009 10:15:03 +0000 Subject: [PATCH 13/16] CWS-TOOLING: integrate CWS mba32issues02 2009-09-17 mb93783 merge commit 2009-09-03 tb121644 #i104748 - slot unification to .uno:PasteSpecial 2009-09-01 mba #101455#: code simplification 2009-08-31 mb93783 iso locales for norwegian builds are nb and nn, not no 2009-08-25 mba merge to m55 2009-07-29 mba cleanup after rebase 2009-07-29 mba #i103200#: wrong order of first and last name in CJK UI 2009-07-27 mba adding dictionary changes from broken svn CWS 2009-07-27 mba adding dictionary changes from broken svn CWS 2009-07-27 mba apply patch from broken svn CWS --- .../fragments/types/writer_AportisDoc_PalmDB_File.xcu | 6 +++--- .../config/fragments/types/writer_PocketWord_File.xcu | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/filter/source/config/fragments/types/writer_AportisDoc_PalmDB_File.xcu b/filter/source/config/fragments/types/writer_AportisDoc_PalmDB_File.xcu index aa1f68e2d302..516d9da0eeaf 100644 --- a/filter/source/config/fragments/types/writer_AportisDoc_PalmDB_File.xcu +++ b/filter/source/config/fragments/types/writer_AportisDoc_PalmDB_File.xcu @@ -1,12 +1,12 @@ - + com.sun.star.comp.filters.XMLFilterDetect pdb - + application/x-aportisdoc false AportisDoc Palm DB AportisDoc (Palm) - + doctype:TEXt diff --git a/filter/source/config/fragments/types/writer_PocketWord_File.xcu b/filter/source/config/fragments/types/writer_PocketWord_File.xcu index 3e2e4d28583a..61c50a935dbc 100644 --- a/filter/source/config/fragments/types/writer_PocketWord_File.xcu +++ b/filter/source/config/fragments/types/writer_PocketWord_File.xcu @@ -1,12 +1,12 @@ - + com.sun.star.comp.filters.XMLFilterDetect psw - + application/x-pocket-word false PocketWord File Pocket Word - + doctype:pwi From c5390d6e4af3eabf8b825a231ab1ae152bd7db1c Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Fri, 18 Sep 2009 12:31:43 +0000 Subject: [PATCH 15/16] CWS-TOOLING: integrate CWS calc32stopper1 2009-09-15 15:43:23 +0200 dr r276180 : newpic 2009-09-15 15:41:13 +0200 dr r276179 : newpic 2009-09-15 14:58:14 +0200 dr r276178 : #i104905# fixed note handling while importing from external data 2009-09-15 13:47:43 +0200 dr r276173 : #i104905# fixed note handling while importing from database 2009-09-15 11:56:00 +0200 dr r276164 : #i104155# prevent crash loading docx 2009-09-15 10:40:43 +0200 dr r276154 : #i104990# 2009-09-15 10:27:31 +0200 dr r276152 : #i104990# enable saving BIFF8 with password/encryption 2009-09-15 10:26:40 +0200 dr r276151 : #i104990# enable saving BIFF8 with password/encryption 2009-09-14 19:13:11 +0200 dr r276145 : #i105007# missing cleanup for deleted headers 2009-09-14 19:06:57 +0200 dr r276144 : #i105007# missing cleanup for deleted headers 2009-09-14 18:53:39 +0200 dr r276143 : #i104915# prevent crashes and misbehaviour when dealing with note cells: enter matrix, enter mult.op 2009-09-14 13:57:00 +0200 dr r276109 : #160184# make drilldown working in exported pivottables, ported to DEV300 2009-09-11 15:16:08 +0200 nn r276068 : #i104987# MoveBlock: pass bCut parameter 2009-09-11 15:15:22 +0200 nn r276067 : #i104986# CopyToClip: correct order of parameters 2009-09-11 09:45:59 +0200 dr r276053 : correct milestone --- oox/source/core/filterbase.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index d289255bac98..c5b423380e82 100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -89,7 +89,7 @@ public: explicit DocumentOpenedGuard( const OUString& rUrl ); ~DocumentOpenedGuard(); - inline bool isValid() const { return maUrl.getLength() > 0; } + inline bool isValid() const { return mbValid; } private: DocumentOpenedGuard( const DocumentOpenedGuard& ); @@ -100,15 +100,15 @@ private: UrlSet& mrUrls; OUString maUrl; + bool mbValid; }; DocumentOpenedGuard::DocumentOpenedGuard( const OUString& rUrl ) : mrUrls( UrlPool::get() ) { ::osl::MutexGuard aGuard( *this ); - OSL_ENSURE( (rUrl.getLength() == 0) || (mrUrls.count( rUrl ) == 0), - "DocumentOpenedGuard::DocumentOpenedGuard - filter called recursively for this document" ); - if( (rUrl.getLength() > 0) && (mrUrls.count( rUrl ) == 0) ) + mbValid = (rUrl.getLength() == 0) || (mrUrls.count( rUrl ) == 0); + if( mbValid && (rUrl.getLength() > 0) ) { mrUrls.insert( rUrl ); maUrl = rUrl; @@ -118,7 +118,7 @@ DocumentOpenedGuard::DocumentOpenedGuard( const OUString& rUrl ) : DocumentOpenedGuard::~DocumentOpenedGuard() { ::osl::MutexGuard aGuard( *this ); - if( isValid() ) + if( maUrl.getLength() > 0 ) mrUrls.erase( maUrl ); }