summaryrefslogtreecommitdiff
path: root/oox/inc/oox/xls/defnamesbuffer.hxx
blob: 5374c47f6a079e0db9ea784928bdcf98b9b0025f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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_XLS_DEFINEDNAMESBUFFER_HXX
#define OOX_XLS_DEFINEDNAMESBUFFER_HXX

#include "oox/xls/formulabase.hxx"

namespace com { namespace sun { namespace star {
    namespace sheet { class XNamedRange; }
} } }

namespace oox {
namespace xls {

class FormulaContext;
class BiffInputStreamPos;

// ============================================================================

// codes for built-in names
const sal_Unicode BIFF_DEFNAME_CONSOLIDATEAREA  = '\x00';
const sal_Unicode BIFF_DEFNAME_AUTOOPEN         = '\x01';   // Sheet macro executed when workbook is opened.
const sal_Unicode BIFF_DEFNAME_AUTOCLOSE        = '\x02';   // Sheet macro executed when workbook is closed.
const sal_Unicode BIFF_DEFNAME_EXTRACT          = '\x03';   // Filter output destination for advanced filter.
const sal_Unicode BIFF_DEFNAME_DATABASE         = '\x04';
const sal_Unicode BIFF_DEFNAME_CRITERIA         = '\x05';   // Filter criteria source range for advanced filter.
const sal_Unicode BIFF_DEFNAME_PRINTAREA        = '\x06';   // Print ranges.
const sal_Unicode BIFF_DEFNAME_PRINTTITLES      = '\x07';   // Rows/columns repeated on each page when printing.
const sal_Unicode BIFF_DEFNAME_RECORDER         = '\x08';
const sal_Unicode BIFF_DEFNAME_DATAFORM         = '\x09';
const sal_Unicode BIFF_DEFNAME_AUTOACTIVATE     = '\x0A';   // Sheet macro executed when workbook is activated.
const sal_Unicode BIFF_DEFNAME_AUTODEACTIVATE   = '\x0B';   // Sheet macro executed when workbook is deactivated.
const sal_Unicode BIFF_DEFNAME_SHEETTITLE       = '\x0C';
const sal_Unicode BIFF_DEFNAME_FILTERDATABASE   = '\x0D';   // Sheet range autofilter or advanced filter works on.
const sal_Unicode BIFF_DEFNAME_UNKNOWN          = '\x0E';

// ============================================================================

struct DefinedNameModel
{
    ::rtl::OUString     maName;         /// The original name.
    ::rtl::OUString     maFormula;      /// The formula string.
    sal_Int32           mnSheet;        /// Sheet index for local names.
    sal_Int32           mnFuncGroupId;  /// Function group identifier.
    bool                mbMacro;        /// True = Macro name (VBA or sheet macro).
    bool                mbFunction;     /// True = function, false = command.
    bool                mbVBName;       /// True = VBA macro, false = sheet macro.
    bool                mbHidden;       /// True = name hidden in UI.

    explicit            DefinedNameModel();
};

// ============================================================================

/** Base class for defined names and external names. */
class DefinedNameBase : public WorkbookHelper
{
public:
    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 original name as imported from or exported to the file. */
    const ::rtl::OUString& getUpcaseModelName() const;
    /** Returns an Any with a SingleReference or ComplexReference, or an empty Any. */
    ::com::sun::star::uno::Any getReference( const ::com::sun::star::table::CellAddress& rBaseAddress ) const;

protected:
    /** Imports the OOXML formula string, using the passed formula context. */
    void                importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet );
    /** Imports the BIFF12 formula, using the passed formula context. */
    void                importBiff12Formula( FormulaContext& rContext, sal_Int16 nBaseSheet, SequenceInputStream& rStrm );
    /** Imports the BIFF formula, using the passed formula context. */
    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                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.
    ::com::sun::star::uno::Any maRefAny;    /// Single cell/range reference.
};

// ============================================================================

class DefinedName : public DefinedNameBase
{
public:
    explicit            DefinedName( const WorkbookHelper& rHelper );

    /** Sets the attributes for this defined name from the passed attribute set. */
    void                importDefinedName( const AttributeList& rAttribs );
    /** Sets the formula string from the body of the definedName element. */
    void                setFormula( const ::rtl::OUString& rFormula );
    /** Imports the defined name from a DEFINEDNAME record in the passed stream. */
    void                importDefinedName( SequenceInputStream& rStrm );
    /** Imports the defined name from a DEFINEDNAME record in the passed BIFF stream. */
    void                importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet );

    /** Creates a defined name in the Calc document. */
    void                createNameObject();
    /** Converts the formula string or BIFF token array for this defined name. */
    void                convertFormula();

    /** Returns true, if this defined name is global in the document. */
    inline bool         isGlobalName() const { return mnCalcSheet < 0; }
    /** Returns true, if this defined name is a special builtin name. */
    inline bool         isBuiltinName() const { return mcBuiltinId != BIFF_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 a reference to a VBA macro. */
    inline bool         isVBName() const { return maModel.mbMacro && maModel.mbVBName; }

    /** Returns the 0-based sheet index for local names, or -1 for global names. */
    inline sal_Int16    getLocalCalcSheet() const { return mnCalcSheet; }
    /** Returns the built-in identifier of the defined name. */
    inline sal_Unicode  getBuiltinId() const { return mcBuiltinId; }
    /** Returns the token index used in API token arrays (com.sun.star.sheet.FormulaToken). */
    inline sal_Int32    getTokenIndex() const { return mnTokenIndex; }
    /** Tries to resolve the defined name to an absolute cell range. */
    bool                getAbsoluteRange( ::com::sun::star::table::CellRangeAddress& orRange ) const;

private:
    /** Imports the OOXML or BIFF12 formula, using the passed formula context. */
    void                implImportOoxFormula( FormulaContext& rContext );
    /** Imports the BIFF formula, using the passed formula context. */
    void                implImportBiffFormula( FormulaContext& rContext );

private:
    typedef ::std::auto_ptr< StreamDataSequence >   StreamDataSeqPtr;
    typedef ::std::auto_ptr< BiffInputStreamPos >   BiffStreamPosPtr;

    ::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 BIFF12 import.
    BiffStreamPosPtr    mxBiffStrm;         /// Cached BIFF stream for formula import.
    sal_uInt16          mnFmlaSize;         /// Cached BIFF formula size for formula import.
};

typedef ::boost::shared_ptr< DefinedName > DefinedNameRef;

// ============================================================================

class DefinedNamesBuffer : public WorkbookHelper
{
public:
    explicit            DefinedNamesBuffer( const WorkbookHelper& rHelper );

    /** 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. */
    void                importDefinedName( SequenceInputStream& rStrm );
    /** Imports a defined name from a DEFINEDNAME record in the passed BIFF stream. */
    void                importDefinedName( BiffInputStream& rStrm );

    /** Creates all defined names in the document. */
    void                finalizeImport();

    /** Returns a defined name by zero-based index (order of appearence). */
    DefinedNameRef      getByIndex( sal_Int32 nIndex ) const;
    /** Returns a defined name by token index (index in XDefinedNames container). */
    DefinedNameRef      getByTokenIndex( sal_Int32 nIndex ) const;
    /** Returns a defined name by its model name.
        @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_Int16 nCalcSheet = -1 ) const;
    /** Returns a built-in defined name by its built-in identifier.
        @param nSheet  The sheet index of the built-in name.
        @return  Reference to the defined name or empty reference. */
    DefinedNameRef      getByBuiltinId( sal_Unicode cBuiltinId, sal_Int16 nCalcSheet ) const;

private:
    DefinedNameRef      createDefinedName();

private:
    typedef ::std::pair< sal_Int16, ::rtl::OUString >   SheetNameKey;
    typedef ::std::pair< sal_Int16, sal_Unicode >       BuiltinKey;

    typedef RefVector< DefinedName >            DefNameVector;
    typedef RefMap< SheetNameKey, DefinedName > DefNameNameMap;
    typedef RefMap< BuiltinKey, DefinedName >   DefNameBuiltinMap;
    typedef RefMap< sal_Int32, DefinedName >    DefNameTokenIdMap;

    DefNameVector       maDefNames;         /// List of all defined names in insertion order.
    DefNameNameMap      maModelNameMap;     /// Maps all defined names by sheet index and model name.
    DefNameBuiltinMap   maBuiltinMap;       /// Maps all defined names by sheet index and built-in identifier.
    DefNameTokenIdMap   maTokenIdMap;       /// Maps all defined names by API token index.
    sal_Int16           mnCalcSheet;        /// Current sheet index for BIFF2-BIFF4 names (always sheet-local).
};

// ============================================================================

} // namespace xls
} // namespace oox

#endif