xref: /aoo4110/main/oox/inc/oox/xls/defnamesbuffer.hxx (revision b1cdbd2c)
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