diff options
149 files changed, 4898 insertions, 8207 deletions
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/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 @@ <node oor:name="writer_AportisDoc_PalmDB_File" oor:op="replace" > - <prop oor:name="DetectService"/> + <prop oor:name="DetectService"><value>com.sun.star.comp.filters.XMLFilterDetect</value></prop> <prop oor:name="URLPattern"/> <prop oor:name="Extensions"><value>pdb</value></prop> - <prop oor:name="MediaType"/> + <prop oor:name="MediaType"><value>application/x-aportisdoc</value></prop> <prop oor:name="Preferred"><value>false</value></prop> <prop oor:name="PreferredFilter"><value>AportisDoc Palm DB</value></prop> <prop oor:name="UIName"> <value>AportisDoc (Palm)</value> </prop> - <prop oor:name="ClipboardFormat"/> + <prop oor:name="ClipboardFormat"><value>doctype:TEXt</value></prop> </node> 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 @@ <node oor:name="writer_MS_Word_2007" oor:op="replace" > - <prop oor:name="DetectService"><value>com.sun.star.comp.Writer.WriterFilterDetector</value></prop> + <prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop> <prop oor:name="URLPattern"/> <prop oor:name="Extensions"><value>docx docm</value></prop> <prop oor:name="MediaType"><value>application/msword</value></prop> 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 @@ <node oor:name="writer_MS_Word_2007_Template" oor:op="replace" > - <prop oor:name="DetectService"><value>com.sun.star.comp.Writer.WriterFilterDetector</value></prop> + <prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop> <prop oor:name="URLPattern"/> <prop oor:name="Extensions"><value>dotx dotm</value></prop> <prop oor:name="MediaType"><value>application/msword</value></prop> 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 @@ <node oor:name="writer_PocketWord_File" oor:op="replace" > - <prop oor:name="DetectService"/> + <prop oor:name="DetectService"><value>com.sun.star.comp.filters.XMLFilterDetect</value></prop> <prop oor:name="URLPattern"/> <prop oor:name="Extensions"><value>psw</value></prop> - <prop oor:name="MediaType"/> + <prop oor:name="MediaType"><value>application/x-pocket-word</value></prop> <prop oor:name="Preferred"><value>false</value></prop> <prop oor:name="PreferredFilter"><value>PocketWord File</value></prop> <prop oor:name="UIName"> <value>Pocket Word</value> </prop> - <prop oor:name="ClipboardFormat"/> + <prop oor:name="ClipboardFormat"><value>doctype:pwi</value></prop> </node> 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 -# <http://www.openoffice.org/license.html> -# 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 - * <http://www.openoffice.org/license.html> - * 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=<file name>\n" ); - sOut.append("parameters:\n" ); - sOut.append("\tcfg=<file name>\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 - * <http://www.openoffice.org/license.html> - * 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<nPrettyTabs; ++tabs) - sBuffer.append("\t"); - sBuffer.append("<node oor:name=\""+sSetName+"\">\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<nPrettyTabs; ++tabs) - sBuffer.append("\t"); - sBuffer.append("</node>\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 -# <http://www.openoffice.org/license.html> -# 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 - * <http://www.openoffice.org/license.html> - * 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=<dir> datafile=<file>"); - 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 - * <http://www.openoffice.org/license.html> - * 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: - * <ul> - * <li>(') => (')</li> - * <li>(") => (")</li> - * <li>(>) => (>)</li> - * <li>(<) => (<)</li> - * <li>(>) => (>)</li> - * <li>(&) => (&)</li> - * <li>...</li> - * </ul> - */ - - 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("<html><header><title>Relation View</title></header><body>"); - sRelationView.append("<table border=1>"); - sRelationView.append("<tr><td><b>type</b></td><td><b>detect service</b></td><td><b>preferred filter</b></td><td><b>frame loader</b></td><td><b>content handler</b></td></tr>"); - - 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("<tr>"); - sRelationView.append("<td>"+sType+"</td>"); - - java.lang.String sVal = (java.lang.String)aType.get(PROPNAME_DETECTSERVICE); - if (sVal == null || sVal.length()<1) - sRelationView.append("<td> - </td>"); - else - sRelationView.append("<td>"+sVal+"</td>"); - - sVal = (java.lang.String)aType.get(PROPNAME_PREFERREDFILTER); - if (sVal == null || sVal.length()<1) - sRelationView.append("<td> - </td>"); - else - sRelationView.append("<td>"+sVal+"</td>"); - - sVal = (java.lang.String)aType.get(PROPNAME_FRAMELOADER); - if (sVal == null || sVal.length()<1) - sRelationView.append("<td> - </td>"); - else - sRelationView.append("<td>"+sVal+"</td>"); - - sVal = (java.lang.String)aType.get(PROPNAME_CONTENTHANDLER); - if (sVal == null || sVal.length()<1) - sRelationView.append("<td> - </td>"); - else - sRelationView.append("<td>"+sVal+"</td>"); - - sRelationView.append("</tr>"); - } - - sRelationView.append("</table>"); - sRelationView.append("</body>"); - - 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("<html><header><title>Type2Filters View</title></header><body>"); - sType2FiltersView.append("<table border=1>"); - sType2FiltersView.append("<tr><td><b>type</b></td><td><b>filters</b></td></tr>"); - - 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("<tr><td>"+sType+"</td><td>"); - java.util.Enumeration aEn = lFilters.elements(); - while(aEn.hasMoreElements()) - sType2FiltersView.append(aEn.nextElement()+"<br>"); - sType2FiltersView.append("</td></tr>"); - } - - sType2FiltersView.append("</table>"); - sType2FiltersView.append("</body>"); - - 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("<node oor:name=\""+sSetName+"\" oor:op=\"replace\">\n"); - java.util.Iterator it = rMap.keySet().iterator(); - while(it.hasNext()) - { - java.lang.String sItem = (java.lang.String)it.next(); - sXML.append("<node oor:name=\""+sItem+"\" oor:op=\"replace\">\n"); - sXML.append(getItemAsXML(eType, sItem, nFormat)); - sXML.append("</node>\n"); - } - sXML.append("</node>\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<c; ++i) - { - sData.append(lList.elementAt(i)); - if (i<(c-1)) - sData.append(";"); - } - - lList = (java.util.Vector)aMap.get(PROPNAME_EXTENSIONS); - c = lList.size(); - for (i=0; i<c; ++i) - { - sData.append(lList.elementAt(i)); - if (i<(c-1)) - sData.append(";"); - } - - sData.append(","); - sData.append(aMap.get(PROPNAME_DOCUMENTICONID)); - sData.append(","); - - aResultMap.put(PROPNAME_DATA, sData.toString()); - } - 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_URLPATTERN , aMap.get(PROPNAME_URLPATTERN )); - aResultMap.put(PROPNAME_EXTENSIONS , aMap.get(PROPNAME_EXTENSIONS )); - aResultMap.put(PROPNAME_UINAME , aMap.get(PROPNAME_UINAME )); - aResultMap.put(PROPNAME_PREFERREDFILTER, aMap.get(PROPNAME_PREFERREDFILTER)); - aResultMap.put(PROPNAME_DETECTSERVICE , aMap.get(PROPNAME_DETECTSERVICE )); - aResultMap.put(PROPNAME_CLIPBOARDFORMAT, aMap.get(PROPNAME_CLIPBOARDFORMAT)); - aResultMap.put(PROPNAME_UIORDER , aMap.get(PROPNAME_UIORDER )); - /* REMOVED! - aResultMap.put(PROPNAME_DOCUMENTICONID , aMap.get(PROPNAME_DOCUMENTICONID )); - */ - } - break; - - //----------------------------------- - default : - throw new java.lang.Exception("unknown format"); - } - - return aResultMap; - } - - //___________________________________________ - - /** converts a filter 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 convertFilterPropsToExternal(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)); - - // but pack all other properties - java.lang.StringBuffer sData = new java.lang.StringBuffer(256); - - sData.append(aMap.get(PROPNAME_ORDER)); - sData.append(","); - sData.append(aMap.get(PROPNAME_TYPE)); - sData.append(","); - sData.append(aMap.get(PROPNAME_DOCUMENTSERVICE)); - sData.append(","); - sData.append(aMap.get(PROPNAME_FILTERSERVICE)); - sData.append(","); - sData.append(aMap.get(PROPNAME_FLAGS)); - sData.append(","); - java.util.Vector lList = (java.util.Vector)aMap.get(PROPNAME_USERDATA); - int c = lList.size(); - int i = 0; - for (i=0; i<c; ++i) - { - sData.append(lList.elementAt(i)); - if (i<(c-1)) - sData.append(";"); - } - sData.append(","); - sData.append(aMap.get(PROPNAME_FILEFORMATVERSION)); - sData.append(","); - sData.append(aMap.get(PROPNAME_TEMPLATENAME)); - sData.append(","); - sData.append(aMap.get(PROPNAME_UICOMPONENT)); - sData.append(","); - - aResultMap.put(PROPNAME_DATA, sData.toString()); - } - break; - - //----------------------------------- - case FORMAT_6Y : - { - // supress "Order" property. - // Will be moved to type entries in 6.y version! - - // supress "UIName" property. - // Only type entries will be localized in 6.y version! - /* TODO make it configurable :-) */ - aResultMap.put(PROPNAME_UINAME , aMap.get(PROPNAME_UINAME )); - - // copy all supported properties directly - aResultMap.put(PROPNAME_TYPE , aMap.get(PROPNAME_TYPE )); - aResultMap.put(PROPNAME_DOCUMENTSERVICE , aMap.get(PROPNAME_DOCUMENTSERVICE )); - aResultMap.put(PROPNAME_FILTERSERVICE , aMap.get(PROPNAME_FILTERSERVICE )); - 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 )); - - // "Flags" will be converted from internal format [int] to - // the 6.y format [string-list]! - java.lang.Integer nFlags = (java.lang.Integer)aMap.get(PROPNAME_FLAGS); - java.util.Vector lFlags = Cache.convertFilterFlagValues2Names(nFlags); - aResultMap.put(PROPNAME_FLAGS, lFlags); - } - break; - - //----------------------------------- - default : - throw new java.lang.Exception("unknown format"); - } - - return aResultMap; - } - - //___________________________________________ - - /** converts a detect service 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 convertDetectServicePropsToExternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - java.util.HashMap aResultMap = null; - - switch(nFormat) - { - //----------------------------------- - case FORMAT_60 : - { - // no changes! - aResultMap = aMap; - } - break; - - //----------------------------------- - case FORMAT_6Y : - { - // remove localized name - aResultMap = aMap; - aResultMap.remove(PROPNAME_UINAME); - } - break; - - //----------------------------------- - default : - throw new java.lang.Exception("unknown format"); - } - - return aResultMap; - } - - private static java.util.HashMap convertFrameLoaderPropsToExternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - java.util.HashMap aResultMap = null; - - switch(nFormat) - { - //----------------------------------- - case FORMAT_60 : - { - // no changes! - aResultMap = aMap; - } - break; - - //----------------------------------- - case FORMAT_6Y : - { - // remove localized name - aResultMap = aMap; - aResultMap.remove(PROPNAME_UINAME); - } - break; - - //----------------------------------- - default : - throw new java.lang.Exception("unknown format"); - } - - return aResultMap; - } - - private static java.util.HashMap convertContentHandlerPropsToExternal(java.util.HashMap aMap , - int nFormat) - throws java.lang.Exception - { - java.util.HashMap aResultMap = null; - - switch(nFormat) - { - //----------------------------------- - case FORMAT_60 : - { - // no changes! - aResultMap = aMap; - } - break; - - //----------------------------------- - case FORMAT_6Y : - { - // remove localized name - aResultMap = aMap; - aResultMap.remove(PROPNAME_UINAME); - } - break; - - //----------------------------------- - default : - throw new java.lang.Exception("unknown format"); - } - - return aResultMap; - } - - //___________________________________________ - - /** converts a type 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["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<nPrettyTabs; ++t) - sXML.append("\t"); - sXML.append("<"+XMLHelper.XMLTAG_NODE+" "+XMLHelper.XMLATTRIB_OOR_NAME+"=\""+XMLHelper.encodeHTMLSigns(sItemName)+"\" "+XMLHelper.XMLATTRIB_OOR_OP+"=\""+XMLHelper.XMLATTRIB_OP_REPLACE+"\">\n"); - sXML.append(XMLHelper.convertPropSetToXML(rFormatedItem, nPrettyTabs+1)); - for (int t=0; t<nPrettyTabs; ++t) - sXML.append("\t"); - sXML.append("</"+XMLHelper.XMLTAG_NODE+">\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<c; ++i1) - { - java.lang.String sT1 = lT1[i1]; - java.util.HashMap aT1 = (java.util.HashMap)m_lTypes.get(sT1); - - for (int i2=i1; i2<c; ++i2) - { - java.lang.String sT2 = lT1[i2]; - java.util.HashMap aT2 = (java.util.HashMap)m_lTypes.get(sT2); - - if (!sT1.equals(sT2)) - { - if ( - aT1.get(PROPNAME_MEDIATYPE).equals(aT2.get(PROPNAME_MEDIATYPE)) && - aT1.get(PROPNAME_CLIPBOARDFORMAT).equals(aT2.get(PROPNAME_CLIPBOARDFORMAT)) && - aT1.get(PROPNAME_URLPATTERN).equals(aT2.get(PROPNAME_URLPATTERN)) && - aT1.get(PROPNAME_EXTENSIONS).equals(aT2.get(PROPNAME_EXTENSIONS)) - ) - { - System.err.println("UUPPSS----------------------------------------------------------------------------"); - System.err.println("[1]\""+sT1+"\" equals [2]\""+sT2+"\""); - System.err.println("\tprops 1: "+aT1); - System.err.println("\tprops 2: "+aT2); - System.err.println("----------------------------------------------------------------------------------\n"); - ++nUPS; -// throw new java.lang.Exception("UUPPS :-)"); - } - } - } - } - System.err.println("count of UPS = "+nUPS); -*/ - } -} diff --git a/filter/source/config/tools/utils/ConfigHelper.java b/filter/source/config/tools/utils/ConfigHelper.java deleted file mode 100644 index 18518dc6df39..000000000000 --- a/filter/source/config/tools/utils/ConfigHelper.java +++ /dev/null @@ -1,297 +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: ConfigHelper.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 - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - **********************************************************************_*/ - -package com.sun.star.filter.config.tools.utils; - - -//_______________________________________________ -// definition - -/** can be used to analyze command line parameters - * and merge it together with might existing config - * files. That provides the possibility to overwrite - * config values via command line parameter. - * - * - */ -public class ConfigHelper extends java.util.Properties -{ - //___________________________________________ - // member - - /** indicates an empty command line. */ - private boolean m_bEmpty = true; - - //___________________________________________ - // ctor - - //------------------------------------------- - /** initialize a new helper with the list of - * command line parameters and bind this new instance - * to a property file on disk. - * - * @param sPropFile - * name of the property file. - * If its set to null or an empty value - * it will be ignored. - * - * @param lCommandLineArgs - * the list of original command line arguments. - * - * @throws [Exception] - * in case the command line contains an unknown - * schema for specifiying parameters or the - * specified property file does not exists - * or seem to be corrupted. - */ - public ConfigHelper(java.lang.String sPropFile , - java.lang.String[] lCommandLineArgs) - throws java.lang.Exception - { - // first load prop file, so its values can be overwritten - // by command line args later - // Do it only, if a valid file name was given. - // But in case this file name is wrong, throw an exception. - // So the outside code can react! - if ( - (sPropFile != null) && - (sPropFile.length() > 0 ) - ) - { - java.lang.ClassLoader aLoader = getClass().getClassLoader(); - java.io.InputStream aStream = aLoader.getResourceAsStream(sPropFile); - if (aStream == null) - aStream = new java.io.FileInputStream(sPropFile); - load(aStream); - } - - int count = 0; - if (lCommandLineArgs != null) - count = lCommandLineArgs.length; - m_bEmpty = (count < 1); - - for (int arg=0; arg<count; ++arg) - { - // is it a named-value argument? - // Note: We ignores double "=" signs! => 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 "<xxx>" and converted to <xxx>! - * - * @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 - * <http://www.openoffice.org/license.html> - * 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<c; ++i) - { - // simple files! - if (lAllFiles[i].isFile()) - lFilteredFiles.add(lAllFiles[i]); - else - // recursion? - if (bRecursive && lAllFiles[i].isDirectory()) - { - java.util.Vector lSubFiles = FileHelper.getSystemFilesFromDir(lAllFiles[i],bRecursive); - if (lSubFiles != null) - { - java.util.Enumeration aSnapshot = lSubFiles.elements(); - while (aSnapshot.hasMoreElements()) - lFilteredFiles.add(aSnapshot.nextElement()); - } - } - } - - return lFilteredFiles; - } - - //_________________________________ - /** it converts the given name (e.g. an internal type name) to - * an usable system file name. - * - * Do so some special characters (e.g. "/") must be replaced with other ones. - * - * @param sName - * the name, which should be analyzed and converted. - * - * @return A valid system file name, which should be similar to the - * given name, but does not contain special characters any longer. - */ - public static java.lang.String convertName2FileName(String sName) - { - int i = 0; - int nLength = sName.length(); - char[] lBuffer = sName.toCharArray(); - - java.lang.StringBuffer sNewName = new java.lang.StringBuffer(nLength); - for (i=0; i<nLength; ++i) - { - char c = lBuffer[i]; - if ( - c>=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; f<lChilds.length; ++f) - { - if (lChilds[f].isDirectory()) - { - FileHelper.makeDirectoryEmpty(lChilds[f], bFilesOnly); - if (!bFilesOnly) - { - if (!lChilds[f].delete()) - throw new java.io.IOException("\""+lChilds[f].toString()+"\" could not be deleted."); - } - } - else - { - if (!lChilds[f].delete()) - throw new java.io.IOException("\""+lChilds[f].toString()+"\" could not be deleted."); - } - } - } - - //___________________________________________ - - /** it try to generate a new file with a unique ID - * inside given directory. - * - * Call this method with a directory and a base name for - * a file. It will be used to generate a new files inside - * the directory. Existing files will be checked and new file - * name will be tested till a non existing file name would be found. - * - * @param aBaseDir - * must be a system path - * e.g.: "c:\temp" - * - * @param sBaseName - * must be a system file name without extensions. - * e.g.: "myfile_" - * - * @param sExtension - * the whished extension. - * e.g.: "dat" - * - * @return A valid file object, if an unique file could be created - - * Null otherwhise. - * e.g.: "c:\temp\myfile_1.dat" - */ - public static java.io.File createUniqueFile(java.io.File aBaseDir , - java.lang.String sBaseName , - java.lang.String sExtension) - { - java.io.File aBaseFile = new java.io.File(aBaseDir, sBaseName); - java.io.File aFile = null; - long nr = 0; - while (aFile == null && nr < java.lang.Long.MAX_VALUE) - { - java.lang.String sFileName = aBaseFile.getPath() + java.lang.String.valueOf(nr) + "." + sExtension; - aFile = new java.io.File(sFileName); - if (aFile.exists()) - aFile=null; - ++nr; - } - return aFile; - } - - //___________________________________________ - - /** reads the complete file, using the right encoding, - * into the given string buffer. - * - * @param aFile - * must point to a system file, which must 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 sBuffer - * used to return the file content. - * - * @throw [IOException] - * - if the file couldnt be opened - * - if the file does not use the right encoding - */ - public static void readEncodedBufferFromFile(java.io.File aFile , - java.lang.String sEncoding, - java.lang.StringBuffer sBuffer ) - throws java.io.IOException - { - if (sEncoding.equals("UTF-8Special")) - { - FileHelper.readAndCheckUTF8File(aFile,sBuffer); - return; - } - - java.io.FileInputStream aByteStream = new java.io.FileInputStream(aFile.getAbsolutePath()); - java.io.InputStreamReader aEncodedReader = new java.io.InputStreamReader(aByteStream, sEncoding); - char[] aEncodedBuffer = new char[4096]; - int nReadCount = 0; - - while((nReadCount=aEncodedReader.read(aEncodedBuffer))>0) - 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<nReadCount) - { - nByteOrg_1 = 0; - nByteOrg_2 = 0; - nByteOrg_3 = 0; - nByteOrg_4 = 0; - nByte_1 = 0; - nByte_2 = 0; - nByte_3 = 0; - nByte_4 = 0; - nUTF8 = 0; - nEncodingType = 0; - - nByteOrg_1 = aBuffer[i++] & 0xFF; - nByte_1 = nByteOrg_1; - /* - Table 3-6. Well-Formed UTF-8 Byte Sequences - - ============================================================================ - Nr. Code Points 1st Byte 2nd Byte 3rd Byte 4th Byte - ============================================================================ - 01 U+ 0..U+ 7F 00..7F - 02 U+ 80..U+ 7FF C2..DF 80..BF - 03 U+ 800..U+ FFF E0 A0..BF 80..BF - 04 U+ 1000..U+ CFFF E1..EC 80..BF 80..BF - 05 U+ D000..U+ D7FF ED 80..9F 80..BF - 06 U+ E000..U+ FFFF EE..EF 80..BF 80..BF - 07 U+ 10000..U+ 3FFFF F0 90..BF 80..BF 80..BF - 08 U+ 40000..U+ FFFFF F1..F3 80..BF 80..BF 80..BF - 09 U+100000..U+10FFFF F4 80..8F 80..BF 80..BF - */ - // ------------------------------------------------------------ - // 01 - // 1 byte: 0xxxxxxx - // ------------------------------------------------------------ - if ( - (nByteOrg_1 >= 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 - * <http://www.openoffice.org/license.html> - * 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/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 - * <http://www.openoffice.org/license.html> - * 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 <value ...> entry. */ - public static final java.lang.String XMLTAG_VALUE = "value"; - - /** its the tag name of a <prop ...> entry. */ - public static final java.lang.String XMLTAG_PROP = "prop"; - - /** its the tag name of a <node ...> 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 <name,value> 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<sSource.length(); ++i) - { - char c = sSource.charAt(i); - if (c == '&') - sDestination.append("&"); - else - sDestination.append(c); - } - - java.lang.String sReturn = sDestination.toString(); - if (!sReturn.equals(sValue)) - System.out.println("encode \""+sValue+"\" => \""+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<nPrettyTabs; ++t) - sXML.append("\t"); - - if (aValue instanceof java.lang.Integer) - { - sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">"); - sXML.append("<value>"+aValue.toString()+"</value>"); - sXML.append("</prop>\n"); - } - else - if (aValue instanceof java.lang.Boolean) - { - sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">"); - sXML.append("<value>"+aValue.toString()+"</value>"); - sXML.append("</prop>\n"); - } - else - if (aValue instanceof java.lang.String) - { - sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\""); - java.lang.String sValue = (java.lang.String)aValue; - - sValue = encodeHTMLSigns(sValue); - - if (sValue.length() < 1) - sXML.append("/>\n"); - else - { - sXML.append("><value>"+sValue+"</value>"); - sXML.append("</prop>\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<nPrettyTabs; ++t) - sXML.append("\t"); - - int c = aValue.size(); - if (c < 1) - { - sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\"/>\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<c; ++i) - { - // get the next list item - java.lang.Object aItem = aValue.get(i); - if (!(aItem instanceof java.lang.String)) - throw new java.lang.Exception("Current implementation supports string-list only!"); - - java.lang.String sValue = (java.lang.String)aItem; - - sValue = encodeHTMLSigns(sValue); - - // append item with default separator, which isn a valid separator at all - // But supress adding of the separator if last element is reached. - sValBuff.append(sValue); - if (i<(c-1)) - sValBuff.append("\n"); - - // check for delim clash - // Attention: An empty (means default) element forbid using - // of a whitespace character as separator! - while(true) - { - if (d >= 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("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">"); - if (d == DEFAULT_SEPARATOR) - sXML.append("<value>"); - else - sXML.append("<value "+XMLATTRIB_OOR_SEPARATOR+"=\""+DELIMS[d]+"\">"); - sXML.append(sListVal); - sXML.append("</value>"); - sXML.append("</prop>\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<nPrettyTabs; ++t) - sXML.append("\t"); - // !Our localized values must be formated at a deeper coloum - // then its property name! - ++nPrettyTabs; - - sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">\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<nPrettyTabs; ++t) - sXML.append("\t"); - sXML.append("<value "+XMLATTRIB_XML_LANG+"=\""+sLocale+"\">"+sValue+"</value>\n"); - } - --nPrettyTabs; - for (int t=0; t<nPrettyTabs; ++t) - sXML.append("\t"); - sXML.append("</prop>\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<lAttribs.getLength(); ++i) - { - org.w3c.dom.Attr aAttrib = (org.w3c.dom.Attr)lAttribs.item(i); - if (aAttrib.getName().equals(sAttrib)) - { - java.lang.String sValue = aAttrib.getValue(); - return sValue; - } - } - - // the searched attribute was not found! -// System.err.println("required attribute \""+sAttrib+"\" does not exist for node ["+aNode.toString()+"]"); - return null; - } - - //___________________________________________ - - /** returns a list of childs, which are ELEMENT_NODES and have the right tag name. - * - * It analyze the list of all possible child nodes. Only ELEMENT_NODES are candidates. - * All other ones will be ignored. Further these element nodes are compared by it's tag - * names. If it match with the specified value it's added to the return list. - * So the return list includes references to the DOM tree nodes only, which are child - * element nodes with the right tag name. - * - * @param aNode - * provides access to the child nodes, which should be analyzed - * - * @param sTag - * the searched tag name. - * - * @return A list of child nodes, which are element nodes and have the right tag name. - */ - public static java.util.Vector extractChildNodesByTagName(org.w3c.dom.Node aNode, - java.lang.String sTag ) - { - // extract first all ELEMENT_NODES of he given parent - // Such nodes only provide tag names. - java.util.Vector lChilds = XMLHelper.extractChildNodesByType(aNode,org.w3c.dom.Node.ELEMENT_NODE); - java.util.Vector lExtractedChilds = new java.util.Vector(lChilds.size()); - - // step over the list and search for the right tags using the specified name - java.util.Enumeration en = lChilds.elements(); - while (en.hasMoreElements()) - { - org.w3c.dom.Node aChild = (org.w3c.dom.Node)en.nextElement(); - if (aChild.getNodeName().equals(sTag)) - lExtractedChilds.add(aChild); - } - - // pack(!) and return the list - lExtractedChilds.trimToSize(); - return lExtractedChilds; - } - - //___________________________________________ - - /** returns a list of childs, which supports the right node type. - * - * It analyze the list of all possible child nodes. If a node represent the right node type - * it is added to the return list. Otherwhise it will be ignored. - * - * @param aNode - * provides access to the list of possible children nodes. - * - * @param nType - * represent the searched node type. - * Possible values are constant fields of a org.w3c.dom.Node - e.g. org.w3c.dom.Node.ELEMENT_NODE. - * - * @return A list of child nodes, which provides the right node type. - */ - public static java.util.Vector extractChildNodesByType(org.w3c.dom.Node aNode, - short nType) - { - // get list of all possibe childs and reserve enough space for our return list - // Attention: A null pointer is not allowed for return! (means lExtractedChilds) - org.w3c.dom.NodeList lChilds = aNode.getChildNodes(); - int c = lChilds.getLength(); - java.util.Vector lExtractedChilds = new java.util.Vector(c); - - // step of these childs and select only needed ones - for (int i=0; i<c; ++i) - { - org.w3c.dom.Node aChild = lChilds.item(i); - if (aChild.getNodeType() == nType) - lExtractedChilds.add(aChild); - } - - // pack(!) and return the list - lExtractedChilds.trimToSize(); - return lExtractedChilds; - } - - //___________________________________________ - - /** generates an xml header, using parameters. - * - * @param sVersion - * number of the xml version. - * - * @param sEncoding - * used file encoding. - * - * @param sPath - * name of the configuration root. - * - * @param sPackage - * name of the configuration package. - * - * @param bLanguagepack - * force creation of a special header, - * which is needed for language packs only. - * - * @return [java.lang.String] - * the generated xml header. - -*/ - public static java.lang.String generateHeader(java.lang.String sVersion , - java.lang.String sEncoding , - java.lang.String sPath , - java.lang.String sPackage , - boolean bLanguagePack) - { - java.lang.StringBuffer sHeader = new java.lang.StringBuffer(256); - - if (bLanguagePack) - { - sHeader.append("<?xml version=\""); - sHeader.append(sVersion); - sHeader.append("\" encoding=\""); - sHeader.append(sEncoding); - sHeader.append("\"?>\n"); - sHeader.append("<oor:component-data oor:package=\""); - sHeader.append(sPath); - sHeader.append("\" oor:name=\""); - sHeader.append(sPackage); - sHeader.append("\" xmlns:install=\"http://openoffice.org/2004/installation\""); - sHeader.append(" xmlns:oor=\"http://openoffice.org/2001/registry\""); - sHeader.append(" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""); - sHeader.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"); - } - else - { - sHeader.append("<?xml version=\""); - sHeader.append(sVersion); - sHeader.append("\" encoding=\""); - sHeader.append(sEncoding); - sHeader.append("\"?>\n<!DOCTYPE oor:component-data SYSTEM \"../../../../component-update.dtd\">\n"); - sHeader.append("<oor:component-data xmlns:oor=\"http://openoffice.org/2001/registry\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" oor:package=\""); - sHeader.append(sPath); - sHeader.append("\" oor:name=\""); - sHeader.append(sPackage); - sHeader.append("\">\n"); - } - - return sHeader.toString(); - } - - public static java.lang.String generateFooter() - { - return "</oor:component-data>\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 -# <http://www.openoffice.org/license.html> -# 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/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<vcl::PDFWriter::ErrorCode>::const_iterator it = rErrors.begin(); it != rErrors.end(); ++it ) diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src index e8e79f0c162d..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 { @@ -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..."; }; 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 <svtools/genericunodialog.hxx> +#include <cppuhelper/implbase2.hxx>
+ // ------------- // - 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/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; } 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 <com/sun/star/frame/XConfigManager.hpp> #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XActiveDataSink.hpp> -#ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_ #include <com/sun/star/beans/PropertyValue.hpp> -#endif +#include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/container/XNamed.hpp> #include <com/sun/star/container/XChild.hpp> #include <com/sun/star/util/XChangesBatch.hpp> #include <comphelper/oslfile2streamwrap.hxx> +#include <comphelper/storagehelper.hxx> #include <unotools/streamwrap.hxx> #include <tools/stream.hxx> #include <tools/urlobj.hxx> @@ -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( 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 <rtl/cipher.h> #include <rtl/digest.h> +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/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 <com/sun/star/xml/sax/XFastTokenHandler.hpp> #include <cppuhelper/implbase1.hxx> +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 001b537444c1..adfb8d6d0941 100644 --- a/oox/inc/oox/core/filterbase.hxx +++ b/oox/inc/oox/core/filterbase.hxx @@ -44,7 +44,7 @@ #include <cppuhelper/implbase5.hxx> #include "oox/helper/binarystreambase.hxx" #include "oox/helper/storagebase.hxx" -#include <oox/dllapi.h> +#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; @@ -190,8 +198,17 @@ 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. */ + ::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. */ @@ -251,19 +268,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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_CORE_FILTERDETECT_HXX +#define OOX_CORE_FILTERDETECT_HXX + +#include <vector> +#include <com/sun/star/document/XExtendedFilterDetection.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#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..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; @@ -204,10 +201,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/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 <vector> #include <boost/shared_ptr.hpp> #include <sal/types.h> +#include <rtl/instance.hxx> +#include <rtl/ustring.hxx> +#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 ); + /** 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; } - /** Removes transparence from the color. */ - void clearTransparence(); /** 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/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 <rtl/ustrbuf.hxx> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/util/DateTime.hpp> +#include <comphelper/mediadescriptor.hxx> #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/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 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 Functor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} - inline void operator()( const value_type& rValue ) const { mrFunctor( *rValue ); } + 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 const ::oox::drawingml::Theme* getCurrentTheme() const; - - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; + virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) 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(); diff --git a/filter/source/config/tools/utils/MalformedCommandLineException.java b/oox/inc/oox/token/propertylist.hxx index f6f33246a1f3..abc776c348f6 100644 --- a/filter/source/config/tools/utils/MalformedCommandLineException.java +++ b/oox/inc/oox/token/propertylist.hxx @@ -1,4 +1,4 @@ -/*_*********************************************************************** +/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -6,8 +6,8 @@ * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: MalformedCommandLineException.java,v $ - * $Revision: 1.4 $ + * $RCSfile: propertylist.hxx,v $ + * $Revision: 1.1 $ * * This file is part of OpenOffice.org. * @@ -26,21 +26,28 @@ * <http://www.openoffice.org/license.html> * for a copy of the LGPLv3 License. * - **********************************************************************_*/ + ************************************************************************/ -package com.sun.star.filter.config.tools.utils; +#ifndef OOX_TOKEN_PROPERTYLIST_HXX +#define OOX_TOKEN_PROPERTYLIST_HXX +#include <vector> +#include <rtl/ustring.hxx> -//___________________________________________ -// types +namespace oox { -/** 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 +// ============================================================================ + +/** A vector that contains all predefined property names used in the filters. */ +struct PropertyList : public ::std::vector< ::rtl::OUString > { - public MalformedCommandLineException() {} - public MalformedCommandLineException(java.lang.String sMsg) { super(sMsg); } -} + 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_TOKEN_TOKENMAP_HXX +#define OOX_TOKEN_TOKENMAP_HXX + +#include <vector> +#include <rtl/instance.hxx> +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +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 + * <http://www.openoffice.org/license.html> + * 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 <memory> #include <vector> #include <com/sun/star/awt/Point.hpp> -#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/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 <vector> +#include <comphelper/docpasswordhelper.hxx> #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..d5be59019315 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; @@ -467,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/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 ); - - FuncInfoParamClassIterator& operator++(); + explicit FunctionParamInfoIterator( const FunctionInfo& rFuncInfo ); - 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/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 <com/sun/star/table/CellVertJustify.hpp> #include <com/sun/star/table/TableBorder.hpp> #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; } - - /** Creates the style sheet described by the style XF with the passed identifier. */ - const ::rtl::OUString& createCellStyle( sal_Int32 nXfId, bool bSkipDefaultBuiltin = false ); + /** 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 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/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/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 <vector> -#include <map> #include <utility> +#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: - typedef ::std::pair< sal_Int16, ::rtl::OUString > IndexNamePair; + 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 ); + }; - const SheetInfoModel* getSheetInfo( sal_Int32 nSheet ) const; + typedef ::std::pair< sal_Int16, ::rtl::OUString > IndexNamePair; - 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/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 <algorithm> #include <string.h> -#include <osl/diagnose.h> +#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 +{ + return StorageRef( new OleStorage( getGlobalFactory(), rxInStream, true ) ); +} + +StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) 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(), rxOutStream, true ) ); } // ============================================================================ 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/core/fasttokenhandler.hxx" +#include <osl/mutex.hxx> +#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 23363db46ed5..c5b423380e82 100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -38,6 +38,7 @@ #include <osl/mutex.hxx> #include <rtl/instance.hxx> #include <rtl/uri.hxx> +#include <comphelper/docpasswordhelper.hxx> #include <comphelper/mediadescriptor.hxx> #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 { @@ -88,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& ); @@ -99,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; @@ -117,7 +118,7 @@ DocumentOpenedGuard::DocumentOpenedGuard( const OUString& rUrl ) : DocumentOpenedGuard::~DocumentOpenedGuard() { ::osl::MutexGuard aGuard( *this ); - if( isValid() ) + if( maUrl.getLength() > 0 ) mrUrls.erase( maUrl ); } @@ -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,23 +236,39 @@ void FilterBaseImpl::setDocumentModel( const Reference< XComponent >& rxComponen mxModelFactory.set( rxComponent, UNO_QUERY ); } -void FilterBaseImpl::setMediaDescriptor( const Sequence< PropertyValue >& rDescriptor ) +bool FilterBaseImpl::hasDocumentModel() const { - 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 ); + return mxGlobalFactory.is() && mxModel.is() && mxModelFactory.is(); +} - if( mxInStream.is() ) - maDescriptor.addInputStream(); +void FilterBaseImpl::initializeFilter() +{ + try + { + // lock the model controllers + mxModel->lockControllers(); + } + catch( Exception& ) + { + } } -bool FilterBaseImpl::hasDocumentModel() const +void FilterBaseImpl::finalizeFilter() { - return mxGlobalFactory.is() && mxModel.is() && mxModelFactory.is(); + 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& ) + { + } } // ============================================================================ @@ -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; @@ -437,7 +471,27 @@ 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 +{ + ::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 ) @@ -508,17 +562,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 +578,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 +588,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 +632,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 <com/sun/star/document/XExtendedFilterDetection.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> - -#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> -#include <com/sun/star/xml/sax/XFastContextHandler.hpp> +#include "oox/core/filterdetect.hxx" +#include <com/sun/star/io/XStream.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> - +#include <rtl/digest.h> +#include <openssl/evp.h> +#include <comphelper/docpasswordhelper.hxx> #include <comphelper/mediadescriptor.hxx> -#include <cppuhelper/implbase1.hxx> -#include <cppuhelper/implbase2.hxx> - #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 <vector> 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<XLocat { } -// =========================================================================== - void SAL_CALL FilterDetectDocHandler::startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& 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. */ +/* =========================================================================== */ + +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 ) +{ + ZipStorage aZipStorage( rxFactory, rxInStrm ); + return aZipStorage.isStorage(); +} + +// ---------------------------------------------------------------------------- + +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 ) + { + memcpy( pnKeyDerived + RTL_DIGEST_LENGTH_SHA1, pnX2, nRequiredKeyLen - RTL_DIGEST_LENGTH_SHA1 ); + nRequiredKeyLen = RTL_DIGEST_LENGTH_SHA1; + } + memcpy( pnKeyDerived, pnX1, nRequiredKeyLen ); +} + +// ---------------------------------------------------------------------------- -OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException ) +bool lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen ) { - OUString aFilter; + 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; - if( mxFactory.is() ) try + 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 ) { - 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 ); + 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 ); } - catch ( const Exception& ) + + 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 aFilter; + 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..84d12776eadd 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 = \ @@ -50,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 6fb94434cc59..07652c5c447b 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -28,29 +28,32 @@ * ************************************************************************/ -#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 <cstdio> +#include <rtl/strbuf.hxx> #include <rtl/ustrbuf.hxx> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/embed/XRelationshipAccess.hpp> #include <com/sun/star/xml/sax/InputSource.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> +#include <comphelper/mediadescriptor.hxx> #include <sax/fshelper.hxx> - +#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::OStringBuffer; using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::com::sun::star::beans::StringPair; @@ -76,6 +79,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; @@ -207,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& ) { @@ -479,16 +492,27 @@ XmlFilterBase& XmlFilterBase::exportDocumentProperties( Reference< XDocumentProp return *this; } -StorageRef XmlFilterBase::implCreateStorage( - Reference< XInputStream >& rxInStream, Reference< XStream >& rxOutStream ) const +// protected ------------------------------------------------------------------ + +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 { - StorageRef xStorage; - if( rxInStream.is() ) - xStorage.reset( new ZipStorage( getGlobalFactory(), rxInStream ) ); - else if( rxOutStream.is() ) - xStorage.reset( new ZipStorage( getGlobalFactory(), rxOutStream ) ); + return StorageRef( new ZipStorage( getGlobalFactory(), rxInStream ) ); +} - return xStorage; +StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const +{ + return StorageRef( new ZipStorage( getGlobalFactory(), rxOutStream ) ); } // ============================================================================ 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 <algorithm> #include <math.h> +#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,164 +46,127 @@ 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. -const double DEC_GAMMA = 2.3; -const double INC_GAMMA = 1.0 / DEC_GAMMA; + explicit PresetColorsPool(); +}; -sal_Int32 lclGetPresetColor( sal_Int32 nToken ) +// ---------------------------------------------------------------------------- + +PresetColorsPool::PresetColorsPool() : + maDmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ), + maVmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ) { - switch( nToken ) + // predefined colors in DrawingML (map XML token identifiers to RGB values) + static const sal_Int32 spnDmlColors[] = { - 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; + 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; + +// ---------------------------------------------------------------------------- + inline void lclRgbToRgbComponents( sal_Int32& ornR, sal_Int32& ornG, sal_Int32& ornB, sal_Int32 nRgb ) { ornR = (nRgb >> 16) & 0xFF; @@ -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; - - 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_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 ); + 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_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) + 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; - } - 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; + 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/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; } 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; - - 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; + // convert preset dash or custom dash + if( moPresetDash.has() ) + lclConvertPresetDash( aLineDash, moPresetDash.get() ); + else + lclConvertCustomDash( aLineDash, maCustomDash ); - 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 <com/sun/star/awt/FontWeight.hpp> #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 95b7da811a74..da21926e04bf 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; } @@ -677,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 ); } @@ -1329,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; @@ -2183,6 +2192,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 +2657,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; @@ -2638,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 ) { @@ -3682,7 +3751,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..e9766865dd8b 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 @@ -346,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 @@ -1093,6 +1095,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 @@ -1648,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/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 <com/sun/star/io/XTextOutputStream.hpp> #include <rtl/math.hxx> #include <osl/file.hxx> +#include <comphelper/docpasswordhelper.hxx> #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/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 <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertySetInfo.hpp> #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 <oox/core/fasttokenhandler.hxx> +#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 <sal/config.h> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#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 ( <TOKENS> ) @@ -17,15 +17,15 @@ while ( <TOKENS> ) } 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 <sal/types.h>\n" ); +print ( HXX "#include <com/sun/star/xml/sax/FastToken.hpp>\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 <rtl/ustring.hxx> +#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 <string.h> -#include <osl/mutex.hxx> +#include "oox/token/tokenmap.hxx" #include <rtl/strbuf.hxx> -#include <com/sun/star/xml/sax/FastToken.hpp> -#include "oox/core/fasttokenhandler.hxx" +#include <rtl/string.hxx> #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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/vml/vmlformatting.hxx" +#include <rtl/strbuf.hxx> +#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 <modifier>(<amount>)' + 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 e583248adcfa..fe07172599a9 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -33,7 +33,6 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/beans/PropertyValues.hpp> #include <com/sun/star/awt/XControlModel.hpp> -#include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/drawing/PointSequenceSequence.hpp> #include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp> @@ -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; + + maTypeModel.maStrokeModel.pushToPropMap( aPropMap, mrDrawing.getFilter() ); + maTypeModel.maFillModel.pushToPropMap( aPropMap, mrDrawing.getFilter() ); - // 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 ); + 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 ) +{ + OptValue< OUString > oValue = rAttribs.getString( nElement ); + if( oValue.has() ) return OptValue< bool >( ConversionHelper::decodeBool( oValue.get() ) ); + return OptValue< bool >(); +} + +/** 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 ) { - 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 ); + 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 (supported: f, t, False, True). +/** 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/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,95 +31,89 @@ #include "oox/xls/biffcodec.hxx" #include <osl/thread.h> #include <string.h> +#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() : + mbValid( false ) { } -BiffDecoderBase::BiffDecoderBase( const BiffDecoderBase& rDecoder ) : - WorkbookHelper( rDecoder ), - mnError( rDecoder.mnError ) +BiffDecoderBase::~BiffDecoderBase() { } -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 ); + if( isValid() ) + maCodec.initKey( &maPassword.front() ); } -void BiffDecoder_XOR::init( const OString& rPass ) +BiffDecoder_XOR* BiffDecoder_XOR::implClone() { - maPass = rPass; - sal_Int32 nLen = maPass.getLength(); - bool bValid = (0 < nLen) && (nLen < 16); + return new BiffDecoder_XOR( *this ); +} - if( bValid ) +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 - sal_uInt8 pnPassw[ 16 ]; - memset( pnPassw, 0, sizeof( pnPassw ) ); - memcpy( pnPassw, maPass.getStr(), static_cast< size_t >( nLen ) ); + maPassword.clear(); + maPassword.resize( 16, 0 ); + memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) ); // init codec - maCodec.initKey( pnPassw ); - bValid = maCodec.verifyKey( mnKey, mnHash ); + maCodec.initKey( &maPassword.front() ); + return maCodec.verifyKey( mnKey, mnHash ); } - - setHasValidPassword( bValid ); -} - -BiffDecoder_XOR* BiffDecoder_XOR::implClone() -{ - return new BiffDecoder_XOR( *this ); + return false; } void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) @@ -149,55 +143,49 @@ 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 ); + if( isValid() ) + maCodec.initKey( &maPassword.front(), &maSalt.front() ); } -void BiffDecoder_RCF::init( const OUString& rPass ) +BiffDecoder_RCF* BiffDecoder_RCF::implClone() { - maPass = rPass; - sal_Int32 nLen = maPass.getLength(); - bool bValid = (0 < nLen) && (nLen < 16); + return new BiffDecoder_RCF( *this ); +} - if( bValid ) +bool BiffDecoder_RCF::implVerify( const OUString& rPassword ) +{ + sal_Int32 nLen = rPassword.getLength(); + if( (0 < nLen) && (nLen < 16) ) { // copy string to sal_uInt16 array - sal_uInt16 pnPassw[ 16 ]; - memset( pnPassw, 0, sizeof( pnPassw ) ); - const sal_Unicode* pcChar = maPass.getStr(); + maPassword.clear(); + maPassword.resize( 16, 0 ); + const sal_Unicode* pcChar = rPassword.getStr(); const sal_Unicode* pcCharEnd = pcChar + nLen; - sal_uInt16* pnCurrPass = pnPassw; - for( ; pcChar < pcCharEnd; ++pcChar, ++pnCurrPass ) - *pnCurrPass = static_cast< sal_uInt16 >( *pcChar ); + ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin(); + for( ; pcChar < pcCharEnd; ++pcChar, ++aIt ) + *aIt = static_cast< sal_uInt16 >( *pcChar ); // init codec - maCodec.initKey( pnPassw, &maDocId.front() ); - bValid = maCodec.verifyKey( &maSaltData.front(), &maSaltHash.front() ); + maCodec.initKey( &maPassword.front(), &maSalt.front() ); + return maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ); } - - setHasValidPassword( bValid ); -} - -BiffDecoder_RCF* BiffDecoder_RCF::implClone() -{ - return new BiffDecoder_RCF( *this ); + return false; } void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) @@ -229,130 +217,117 @@ 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; -} // namespace +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; // ---------------------------------------------------------------------------- -BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ), - mbHasPassword( false ) -{ -} - -const OString& BiffCodecHelper::getBiff5WbProtPassword() -{ - static const OString saPass( "VelvetSweatshop" ); - return saPass; -} - -const OUString& BiffCodecHelper::getBiff8WbProtPassword() +BiffDecoderRef lclReadFilePass_XOR( BiffInputStream& rStrm ) { - 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; -} - -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; - - return mxDecoder.get() && mxDecoder->isValid(); -} - -void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm ) -{ - if( mxDecoder.get() ) - rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) ); -} - -// private -------------------------------------------------------------------- - -void BiffCodecHelper::importFilePass_XOR( BiffInputStream& rStrm ) -{ - OSL_ENSURE( rStrm.getRemaining() == 4, "BiffCodecHelper::importFilePass_XOR - wrong record size" ); + BiffDecoderRef xDecoder; + OSL_ENSURE( rStrm.getRemaining() == 4, "lclReadFilePass_XOR - wrong record size" ); if( rStrm.getRemaining() == 4 ) { sal_uInt16 nBaseKey, nHash; rStrm >> nBaseKey >> nHash; - mxDecoder.reset( new BiffDecoder_XOR( *this, nBaseKey, nHash ) ); + xDecoder.reset( new BiffDecoder_XOR( nBaseKey, nHash ) ); } + return xDecoder; } -void BiffCodecHelper::importFilePass_RCF( BiffInputStream& rStrm ) +BiffDecoderRef lclReadFilePass_RCF( BiffInputStream& rStrm ) { - OSL_ENSURE( rStrm.getRemaining() == 48, "BiffCodecHelper::importFilePass_RCF - wrong record size" ); + BiffDecoderRef xDecoder; + OSL_ENSURE( rStrm.getRemaining() == 48, "lclReadFilePass_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 ) ); + 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; } -void BiffCodecHelper::importFilePass_Strong( BiffInputStream& /*rStrm*/ ) +BiffDecoderRef lclReadFilePass_CryptoApi( BiffInputStream& /*rStrm*/ ) { // not supported + return BiffDecoderRef(); } -void BiffCodecHelper::importFilePass2( BiffInputStream& rStrm ) -{ - importFilePass_XOR( rStrm ); -} - -void BiffCodecHelper::importFilePass8( BiffInputStream& rStrm ) +BiffDecoderRef lclReadFilePassBiff8( BiffInputStream& rStrm ) { + BiffDecoderRef xDecoder; switch( rStrm.readuInt16() ) { - case BIFF_FILEPASS_BIFF2: - importFilePass_XOR( rStrm ); + case BIFF_FILEPASS_XOR: + xDecoder = lclReadFilePass_XOR( rStrm ); break; - case BIFF_FILEPASS_BIFF8: + case BIFF_FILEPASS_RCF: + { + sal_uInt16 nMajor = rStrm.readuInt16(); rStrm.skip( 2 ); - switch( rStrm.readuInt16() ) + switch( nMajor ) { case BIFF_FILEPASS_BIFF8_RCF: - importFilePass_RCF( rStrm ); + xDecoder = lclReadFilePass_RCF( rStrm ); break; - case BIFF_FILEPASS_BIFF8_STRONG: - importFilePass_Strong( rStrm ); + case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003: + case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007: + xDecoder = lclReadFilePass_CryptoApi( rStrm ); break; default: - OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown BIFF8 encryption sub mode" ); + OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown BIFF8 encryption sub mode" ); } + } break; default: - OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown encryption mode" ); + OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown encryption mode" ); } + return xDecoder; +} + +} // namespace + +// ---------------------------------------------------------------------------- + +BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) : + WorkbookHelper( rHelper ) +{ +} + +/*static*/ BiffDecoderRef BiffCodecHelper::implReadFilePass( BiffInputStream& rStrm, BiffType eBiff ) +{ + 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" ); + 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(); +} + +void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm ) +{ + if( mxDecoder.get() ) + rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) ); } // ============================================================================ 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 <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp> #include <com/sun/star/sheet/XSheetAnnotations.hpp> #include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp> -#include <com/sun/star/text/XText.hpp> #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 <rtl/ustrbuf.hxx> #include <com/sun/star/sheet/ComplexReference.hpp> +#include <com/sun/star/sheet/ExternalReference.hpp> #include <com/sun/star/sheet/NamedRangeFlag.hpp> #include <com/sun/star/sheet/ReferenceFlags.hpp> #include <com/sun/star/sheet/SingleReference.hpp> @@ -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 <rtl/strbuf.hxx> +#include <com/sun/star/sheet/ComplexReference.hpp> #include <com/sun/star/sheet/DDELinkInfo.hpp> #include <com/sun/star/sheet/ExternalLinkType.hpp> +#include <com/sun/star/sheet/ExternalReference.hpp> +#include <com/sun/star/sheet/ReferenceFlags.hpp> +#include <com/sun/star/sheet/SingleReference.hpp> #include <com/sun/star/sheet/XDDELinks.hpp> #include <com/sun/star/sheet/XDDELink.hpp> #include <com/sun/star/sheet/XDDELinkResults.hpp> @@ -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: + // cell references to other internal sheets are stored in hidden external names + if( bHiddenRef && (getBiff() == BIFF4) && isWorkbookFile() ) + { + TokensFormulaContext aContext( true, true ); + importBiffFormula( aContext, mrParentLink.getCalcSheetIndex(), rStrm ); + extractReference( aContext.getTokens() ); + } + break; + 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 documents are stored in hidden external names + if( bHiddenRef ) { TokensFormulaContext aContext( true, true ); - importBiffFormula( aContext, rStrm ); - setReference( aContext.getTokens() ); + 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/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" ); +} + +const FunctionParamInfo& FunctionParamInfoIterator::getParamInfo() const +{ + 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); } -FuncInfoParamClassIterator& FuncInfoParamClassIterator::operator++() +bool FunctionParamInfoIterator::isExcelOnlyParam() const { - if( (mpnParamClass + 1 < mpnParamClassEnd) && (mpnParamClass[ 1 ] != 0) ) - ++mpnParamClass; + 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: 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 <rtl/ustrbuf.hxx> #include <com/sun/star/text/XText.hpp> #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 <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/awt/FontDescriptor.hpp> #include <com/sun/star/awt/FontFamily.hpp> #include <com/sun/star/awt/FontPitch.hpp> @@ -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(); } -bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar ) +OUString lclGetBuiltInStyleName( const OUString& rName ) { -#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 + OUStringBuffer aStyleName; + aStyleName.appendAscii( spcStyleNamePrefix ).append( rName ); + return aStyleName.makeStringAndClear(); +} - // try the other builtin styles +bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar ) +{ + // 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() ); + // #i103281# check if this is a new built-in style introduced in XL2007 + if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_STYLEEXT) && rStrm.startNextRecord() ) + { + 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 ) + { + maModel.mnBuiltinId = rStrm.readInt8(); + maModel.mnLevel = rStrm.readInt8(); + } + } } } -const OUString& CellStyle::createCellStyle( sal_Int32 nXfId, bool bSkipDefaultBuiltin ) +OUString CellStyle::calcInitialStyleName() const { - if( maCalcName.getLength() == 0 ) + 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 { - bool bBuiltin = maModel.isBuiltin(); - if( !bSkipDefaultBuiltin || !bBuiltin || maModel.mbCustom ) - { - // name of the style (generate unique name for builtin styles) - maCalcName = maModel.createStyleName(); - // #i1624# #i1768# ignore unnamed user styles - if( maCalcName.getLength() > 0 ) - { - 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 - } - } + 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() ); } - return maCalcName; + 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 d5904877b7ee..6a78c838838e 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; @@ -231,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 ); @@ -245,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() ); } } } @@ -281,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 @@ -366,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; @@ -402,7 +403,8 @@ bool BiffWorkbookFragment::importFragment() } // final conversions, e.g. calculation settings and view settings - finalizeWorkbookImport(); + if( bRet ) + finalizeWorkbookImport(); return bRet; } @@ -432,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 ); @@ -509,33 +511,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 +550,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 +572,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 +597,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 @@ -620,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 ) @@ -636,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() ) @@ -646,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 @@ -685,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/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 <com/sun/star/util/Date.hpp> #include <com/sun/star/util/XNumberFormatsSupplier.hpp> #include <com/sun/star/sheet/XCalculatable.hpp> +#include <comphelper/mediadescriptor.hxx> #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/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 <com/sun/star/sheet/XSheetLinkable.hpp> #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; - return OUString(); + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->maCalcName : OUString(); } -sal_Int32 WorksheetBuffer::getCalcSheetIndex( const OUString& rModelName ) const +sal_Int16 WorksheetBuffer::getCalcSheetIndex( const OUString& rWorksheetName ) 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; + 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(); } // 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 ); + } +} + +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::finalizeHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const +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/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..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 @@ -74,11 +74,26 @@ 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) DEFLIB1NAME =$(TARGET) # --- Targets ---------------------------------------------------------- +.ENDIF # L10N_framework .INCLUDE : target.mk 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() 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( 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/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 <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/io/XInputStream.hpp> +#include <comphelper/mediadescriptor.hxx> +#include <oox/core/filterdetect.hxx> #include <dmapper/DomainMapper.hxx> #include <WriterFilter.hxx> #include <doctok/WW8Document.hxx> @@ -44,6 +46,7 @@ #include <resourcemodel/TagLogger.hxx> 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()) { - - 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; - } + MediaDescriptor aMediaDesc( aDescriptor ); + OUString sFilterName = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_FILTERNAME(), OUString() ); + + 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= 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 |