1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef OOX_XLS_DEFINEDNAMESBUFFER_HXX 25 #define OOX_XLS_DEFINEDNAMESBUFFER_HXX 26 27 #include "oox/xls/formulabase.hxx" 28 29 namespace com { namespace sun { namespace star { 30 namespace sheet { class XNamedRange; } 31 } } } 32 33 namespace oox { 34 namespace xls { 35 36 class BiffInputStreamPos; 37 38 // ============================================================================ 39 40 // codes for built-in names 41 const sal_Unicode BIFF_DEFNAME_CONSOLIDATEAREA = '\x00'; 42 const sal_Unicode BIFF_DEFNAME_AUTOOPEN = '\x01'; // Sheet macro executed when workbook is opened. 43 const sal_Unicode BIFF_DEFNAME_AUTOCLOSE = '\x02'; // Sheet macro executed when workbook is closed. 44 const sal_Unicode BIFF_DEFNAME_EXTRACT = '\x03'; // Filter output destination for advanced filter. 45 const sal_Unicode BIFF_DEFNAME_DATABASE = '\x04'; 46 const sal_Unicode BIFF_DEFNAME_CRITERIA = '\x05'; // Filter criteria source range for advanced filter. 47 const sal_Unicode BIFF_DEFNAME_PRINTAREA = '\x06'; // Print ranges. 48 const sal_Unicode BIFF_DEFNAME_PRINTTITLES = '\x07'; // Rows/columns repeated on each page when printing. 49 const sal_Unicode BIFF_DEFNAME_RECORDER = '\x08'; 50 const sal_Unicode BIFF_DEFNAME_DATAFORM = '\x09'; 51 const sal_Unicode BIFF_DEFNAME_AUTOACTIVATE = '\x0A'; // Sheet macro executed when workbook is activated. 52 const sal_Unicode BIFF_DEFNAME_AUTODEACTIVATE = '\x0B'; // Sheet macro executed when workbook is deactivated. 53 const sal_Unicode BIFF_DEFNAME_SHEETTITLE = '\x0C'; 54 const sal_Unicode BIFF_DEFNAME_FILTERDATABASE = '\x0D'; // Sheet range autofilter or advanced filter works on. 55 const sal_Unicode BIFF_DEFNAME_UNKNOWN = '\x0E'; 56 57 // ============================================================================ 58 59 struct DefinedNameModel 60 { 61 ::rtl::OUString maName; /// The original name. 62 ::rtl::OUString maFormula; /// The formula string. 63 sal_Int32 mnSheet; /// Sheet index for local names. 64 sal_Int32 mnFuncGroupId; /// Function group identifier. 65 bool mbMacro; /// True = Macro name (VBA or sheet macro). 66 bool mbFunction; /// True = function, false = command. 67 bool mbVBName; /// True = VBA macro, false = sheet macro. 68 bool mbHidden; /// True = name hidden in UI. 69 70 explicit DefinedNameModel(); 71 }; 72 73 // ============================================================================ 74 75 /** Base class for defined names and external names. */ 76 class DefinedNameBase : public WorkbookHelper 77 { 78 public: 79 explicit DefinedNameBase( const WorkbookHelper& rHelper ); 80 81 /** Returns the original name as imported from or exported to the file. */ getModelName() const82 inline const ::rtl::OUString& getModelName() const { return maModel.maName; } 83 /** Returns the name as used in the Calc document. */ getCalcName() const84 inline const ::rtl::OUString& getCalcName() const { return maCalcName; } 85 86 /** Returns the original name as imported from or exported to the file. */ 87 const ::rtl::OUString& getUpcaseModelName() const; 88 /** Returns an Any with a SingleReference or ComplexReference, or an empty Any. */ 89 ::com::sun::star::uno::Any getReference( const ::com::sun::star::table::CellAddress& rBaseAddr ) const; 90 91 protected: 92 /** Converts the OOXML formula string stored in the own model. */ 93 ApiTokenSequence importOoxFormula( sal_Int16 nBaseSheet ); 94 /** Imports the BIFF12 formula from the passed stream. */ 95 ApiTokenSequence importBiff12Formula( sal_Int16 nBaseSheet, SequenceInputStream& rStrm ); 96 /** Imports the BIFF formula from the passed stream. */ 97 ApiTokenSequence importBiffFormula( sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ); 98 99 /** Tries to convert the passed token sequence to a SingleReference or ComplexReference. */ 100 void extractReference( const ApiTokenSequence& rTokens ); 101 102 protected: 103 DefinedNameModel maModel; /// Model data for this defined name. 104 mutable ::rtl::OUString maUpModelName; /// Model name converted to uppercase ASCII. 105 ::rtl::OUString maCalcName; /// Final name used in the Calc document. 106 ::com::sun::star::uno::Any maRefAny; /// Single cell/range reference. 107 }; 108 109 // ============================================================================ 110 111 class DefinedName : public DefinedNameBase 112 { 113 public: 114 explicit DefinedName( const WorkbookHelper& rHelper ); 115 116 /** Sets the attributes for this defined name from the passed attribute set. */ 117 void importDefinedName( const AttributeList& rAttribs ); 118 /** Sets the formula string from the body of the definedName element. */ 119 void setFormula( const ::rtl::OUString& rFormula ); 120 /** Imports the defined name from a DEFINEDNAME record in the passed stream. */ 121 void importDefinedName( SequenceInputStream& rStrm ); 122 /** Imports the defined name from a DEFINEDNAME record in the passed BIFF stream. */ 123 void importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet ); 124 125 /** Creates a defined name in the Calc document. */ 126 void createNameObject(); 127 /** Converts the formula string or BIFF token array for this defined name. */ 128 void convertFormula(); 129 130 /** Returns true, if this defined name is global in the document. */ isGlobalName() const131 inline bool isGlobalName() const { return mnCalcSheet < 0; } 132 /** Returns true, if this defined name is a special builtin name. */ isBuiltinName() const133 inline bool isBuiltinName() const { return mcBuiltinId != BIFF_DEFNAME_UNKNOWN; } 134 /** Returns true, if this defined name is a macro function call. */ isMacroFunction() const135 inline bool isMacroFunction() const { return maModel.mbMacro && maModel.mbFunction; } 136 /** Returns true, if this defined name is a reference to a VBA macro. */ isVBName() const137 inline bool isVBName() const { return maModel.mbMacro && maModel.mbVBName; } 138 139 /** Returns the 0-based sheet index for local names, or -1 for global names. */ getLocalCalcSheet() const140 inline sal_Int16 getLocalCalcSheet() const { return mnCalcSheet; } 141 /** Returns the built-in identifier of the defined name. */ getBuiltinId() const142 inline sal_Unicode getBuiltinId() const { return mcBuiltinId; } 143 /** Returns the token index used in API token arrays (com.sun.star.sheet.FormulaToken). */ getTokenIndex() const144 inline sal_Int32 getTokenIndex() const { return mnTokenIndex; } 145 /** Tries to resolve the defined name to an absolute cell range. */ 146 bool getAbsoluteRange( ::com::sun::star::table::CellRangeAddress& orRange ) const; 147 148 private: 149 /** Imports the OOXML or BIFF12 definition of the name. */ 150 void implImportOoxFormula(); 151 /** Imports the BIFF definition of the name. */ 152 void implImportBiffFormula(); 153 154 private: 155 typedef ::std::auto_ptr< StreamDataSequence > StreamDataSeqPtr; 156 typedef ::std::auto_ptr< BiffInputStreamPos > BiffStreamPosPtr; 157 158 ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange2 > 159 mxNamedRange; /// XNamedRange interface of the defined name. 160 sal_Int32 mnTokenIndex; /// Name index used in API token array. 161 sal_Int16 mnCalcSheet; /// Calc sheet index for sheet-local names. 162 sal_Unicode mcBuiltinId; /// Identifier for built-in defined names. 163 StreamDataSeqPtr mxFormula; /// Formula data for BIFF12 import. 164 BiffStreamPosPtr mxBiffStrm; /// Cached BIFF stream for formula import. 165 sal_uInt16 mnFmlaSize; /// Cached BIFF formula size for formula import. 166 }; 167 168 typedef ::boost::shared_ptr< DefinedName > DefinedNameRef; 169 170 // ============================================================================ 171 172 class DefinedNamesBuffer : public WorkbookHelper 173 { 174 public: 175 explicit DefinedNamesBuffer( const WorkbookHelper& rHelper ); 176 177 /** Sets the sheet index for local names (BIFF2-BIFF4 only). */ 178 void setLocalCalcSheet( sal_Int16 nCalcSheet ); 179 180 /** Imports a defined name from the passed attribute set. */ 181 DefinedNameRef importDefinedName( const AttributeList& rAttribs ); 182 /** Imports a defined name from a DEFINEDNAME record in the passed stream. */ 183 void importDefinedName( SequenceInputStream& rStrm ); 184 /** Imports a defined name from a DEFINEDNAME record in the passed BIFF stream. */ 185 void importDefinedName( BiffInputStream& rStrm ); 186 187 /** Creates all defined names in the document. */ 188 void finalizeImport(); 189 190 /** Returns a defined name by zero-based index (order of appearence). */ 191 DefinedNameRef getByIndex( sal_Int32 nIndex ) const; 192 /** Returns a defined name by token index (index in XDefinedNames container). */ 193 DefinedNameRef getByTokenIndex( sal_Int32 nIndex ) const; 194 /** Returns a defined name by its model name. 195 @param nSheet The sheet index for local names or -1 for global names. 196 If no local name is found, tries to find a matching global name. 197 @return Reference to the defined name or empty reference. */ 198 DefinedNameRef getByModelName( const ::rtl::OUString& rModelName, sal_Int16 nCalcSheet = -1 ) const; 199 /** Returns a built-in defined name by its built-in identifier. 200 @param nSheet The sheet index of the built-in name. 201 @return Reference to the defined name or empty reference. */ 202 DefinedNameRef getByBuiltinId( sal_Unicode cBuiltinId, sal_Int16 nCalcSheet ) const; 203 204 private: 205 DefinedNameRef createDefinedName(); 206 207 private: 208 typedef ::std::pair< sal_Int16, ::rtl::OUString > SheetNameKey; 209 typedef ::std::pair< sal_Int16, sal_Unicode > BuiltinKey; 210 211 typedef RefVector< DefinedName > DefNameVector; 212 typedef RefMap< SheetNameKey, DefinedName > DefNameNameMap; 213 typedef RefMap< BuiltinKey, DefinedName > DefNameBuiltinMap; 214 typedef RefMap< sal_Int32, DefinedName > DefNameTokenIdMap; 215 216 DefNameVector maDefNames; /// List of all defined names in insertion order. 217 DefNameNameMap maModelNameMap; /// Maps all defined names by sheet index and model name. 218 DefNameBuiltinMap maBuiltinMap; /// Maps all defined names by sheet index and built-in identifier. 219 DefNameTokenIdMap maTokenIdMap; /// Maps all defined names by API token index. 220 sal_Int16 mnCalcSheet; /// Current sheet index for BIFF2-BIFF4 names (always sheet-local). 221 }; 222 223 // ============================================================================ 224 225 } // namespace xls 226 } // namespace oox 227 228 #endif 229