xref: /aoo42x/main/oox/source/xls/defnamesbuffer.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "oox/xls/defnamesbuffer.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <com/sun/star/sheet/ComplexReference.hpp>
31*cdf0e10cSrcweir #include <com/sun/star/sheet/ExternalReference.hpp>
32*cdf0e10cSrcweir #include <com/sun/star/sheet/NamedRangeFlag.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/sheet/ReferenceFlags.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/sheet/SingleReference.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/sheet/XFormulaTokens.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/sheet/XPrintAreas.hpp>
37*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
38*cdf0e10cSrcweir #include "oox/helper/attributelist.hxx"
39*cdf0e10cSrcweir #include "oox/helper/containerhelper.hxx"
40*cdf0e10cSrcweir #include "oox/helper/propertyset.hxx"
41*cdf0e10cSrcweir #include "oox/xls/addressconverter.hxx"
42*cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx"
43*cdf0e10cSrcweir #include "oox/xls/externallinkbuffer.hxx"
44*cdf0e10cSrcweir #include "oox/xls/formulaparser.hxx"
45*cdf0e10cSrcweir #include "oox/xls/worksheetbuffer.hxx"
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir namespace oox {
48*cdf0e10cSrcweir namespace xls {
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir // ============================================================================
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
53*cdf0e10cSrcweir using namespace ::com::sun::star::table;
54*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir using ::rtl::OUString;
57*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir // ============================================================================
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir namespace {
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_HIDDEN      = 0x00000001;
64*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_FUNC        = 0x00000002;
65*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_VBNAME      = 0x00000004;
66*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_MACRO       = 0x00000008;
67*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_CALCEXP     = 0x00000010;
68*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_BUILTIN     = 0x00000020;
69*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_PUBLISHED   = 0x00008000;
70*cdf0e10cSrcweir const sal_uInt32 BIFF12_DEFNAME_WBPARAM     = 0x00010000;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_HIDDEN        = 0x0001;
73*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_FUNC          = 0x0002;
74*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_VBNAME        = 0x0004;
75*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_MACRO         = 0x0008;
76*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_CALCEXP       = 0x0010;
77*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_BUILTIN       = 0x0020;
78*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_BIG           = 0x1000;
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir const sal_uInt8 BIFF2_DEFNAME_FUNC          = 0x02;     /// BIFF2 function/command flag.
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir const sal_uInt16 BIFF_DEFNAME_GLOBAL        = 0;        /// 0 = Globally defined name.
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir const sal_uInt16 BIFF_REFFLAG_COL1REL       = 0x0001;
85*cdf0e10cSrcweir const sal_uInt16 BIFF_REFFLAG_ROW1REL       = 0x0002;
86*cdf0e10cSrcweir const sal_uInt16 BIFF_REFFLAG_COL2REL       = 0x0004;
87*cdf0e10cSrcweir const sal_uInt16 BIFF_REFFLAG_ROW2REL       = 0x0008;
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir // ----------------------------------------------------------------------------
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir const sal_Char* const spcLegacyPrefix = "Excel_BuiltIn_";
92*cdf0e10cSrcweir const sal_Char* const spcOoxPrefix = "_xlnm.";
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir const sal_Char* const sppcBaseNames[] =
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir     "Consolidate_Area",
97*cdf0e10cSrcweir     "Auto_Open",
98*cdf0e10cSrcweir     "Auto_Close",
99*cdf0e10cSrcweir     "Extract",
100*cdf0e10cSrcweir     "Database",
101*cdf0e10cSrcweir     "Criteria",
102*cdf0e10cSrcweir     "Print_Area",
103*cdf0e10cSrcweir     "Print_Titles",
104*cdf0e10cSrcweir     "Recorder",
105*cdf0e10cSrcweir     "Data_Form",
106*cdf0e10cSrcweir     "Auto_Activate",
107*cdf0e10cSrcweir     "Auto_Deactivate",
108*cdf0e10cSrcweir     "Sheet_Title",
109*cdf0e10cSrcweir     "_FilterDatabase"
110*cdf0e10cSrcweir };
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir /** Localized names for _xlnm._FilterDatabase as used in BIFF5. */
113*cdf0e10cSrcweir const sal_Char* const sppcFilterDbNames[] =
114*cdf0e10cSrcweir {
115*cdf0e10cSrcweir     "_FilterDatabase",      // English
116*cdf0e10cSrcweir     "_FilterDatenbank"      // German
117*cdf0e10cSrcweir };
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir OUString lclGetBaseName( sal_Unicode cBuiltinId )
120*cdf0e10cSrcweir {
121*cdf0e10cSrcweir     OSL_ENSURE( cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ), "lclGetBaseName - unsupported built-in identifier" );
122*cdf0e10cSrcweir     OUStringBuffer aBuffer;
123*cdf0e10cSrcweir     if( cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ) )
124*cdf0e10cSrcweir         aBuffer.appendAscii( sppcBaseNames[ cBuiltinId ] );
125*cdf0e10cSrcweir     else
126*cdf0e10cSrcweir         aBuffer.append( static_cast< sal_Int32 >( cBuiltinId ) );
127*cdf0e10cSrcweir     return aBuffer.makeStringAndClear();
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir OUString lclGetPrefixedName( sal_Unicode cBuiltinId )
131*cdf0e10cSrcweir {
132*cdf0e10cSrcweir     return OUStringBuffer().appendAscii( spcOoxPrefix ).append( lclGetBaseName( cBuiltinId ) ).makeStringAndClear();
133*cdf0e10cSrcweir }
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir /** returns the built-in name identifier from a perfixed built-in name, e.g. '_xlnm.Print_Area'. */
136*cdf0e10cSrcweir sal_Unicode lclGetBuiltinIdFromPrefixedName( const OUString& rModelName )
137*cdf0e10cSrcweir {
138*cdf0e10cSrcweir     OUString aPrefix = OUString::createFromAscii( spcOoxPrefix );
139*cdf0e10cSrcweir     sal_Int32 nPrefixLen = aPrefix.getLength();
140*cdf0e10cSrcweir     if( rModelName.matchIgnoreAsciiCase( aPrefix ) )
141*cdf0e10cSrcweir     {
142*cdf0e10cSrcweir         for( sal_Unicode cBuiltinId = 0; cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ); ++cBuiltinId )
143*cdf0e10cSrcweir         {
144*cdf0e10cSrcweir             OUString aBaseName = lclGetBaseName( cBuiltinId );
145*cdf0e10cSrcweir             sal_Int32 nBaseNameLen = aBaseName.getLength();
146*cdf0e10cSrcweir             if( (rModelName.getLength() == nPrefixLen + nBaseNameLen) && rModelName.matchIgnoreAsciiCase( aBaseName, nPrefixLen ) )
147*cdf0e10cSrcweir                 return cBuiltinId;
148*cdf0e10cSrcweir         }
149*cdf0e10cSrcweir     }
150*cdf0e10cSrcweir     return BIFF_DEFNAME_UNKNOWN;
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir /** returns the built-in name identifier from a built-in base name, e.g. 'Print_Area'. */
154*cdf0e10cSrcweir sal_Unicode lclGetBuiltinIdFromBaseName( const OUString& rModelName )
155*cdf0e10cSrcweir {
156*cdf0e10cSrcweir     for( sal_Unicode cBuiltinId = 0; cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ); ++cBuiltinId )
157*cdf0e10cSrcweir         if( rModelName.equalsIgnoreAsciiCaseAscii( sppcBaseNames[ cBuiltinId ] ) )
158*cdf0e10cSrcweir             return cBuiltinId;
159*cdf0e10cSrcweir     return BIFF_DEFNAME_UNKNOWN;
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir bool lclIsFilterDatabaseName( const OUString& rModelName )
163*cdf0e10cSrcweir {
164*cdf0e10cSrcweir     for( const sal_Char* const* ppcName = sppcFilterDbNames; ppcName < STATIC_ARRAY_END( sppcFilterDbNames ); ++ppcName )
165*cdf0e10cSrcweir         if( rModelName.equalsIgnoreAsciiCaseAscii( *ppcName ) )
166*cdf0e10cSrcweir             return true;
167*cdf0e10cSrcweir     return false;
168*cdf0e10cSrcweir }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir OUString lclGetUpcaseModelName( const OUString& rModelName )
171*cdf0e10cSrcweir {
172*cdf0e10cSrcweir     // TODO: i18n?
173*cdf0e10cSrcweir     return rModelName.toAsciiUpperCase();
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir void lclConvertRefFlags( sal_Int32& ornFlags, sal_Int32& ornAbsPos, sal_Int32& ornRelPos, sal_Int32 nBasePos, sal_Int32 nApiRelFlag, bool bRel )
177*cdf0e10cSrcweir {
178*cdf0e10cSrcweir     if( getFlag( ornFlags, nApiRelFlag ) && !bRel )
179*cdf0e10cSrcweir     {
180*cdf0e10cSrcweir         // convert relative to absolute
181*cdf0e10cSrcweir         setFlag( ornFlags, nApiRelFlag, false );
182*cdf0e10cSrcweir         ornAbsPos = nBasePos + ornRelPos;
183*cdf0e10cSrcweir     }
184*cdf0e10cSrcweir     else if( !getFlag( ornFlags, nApiRelFlag ) && bRel )
185*cdf0e10cSrcweir     {
186*cdf0e10cSrcweir         // convert absolute to relative
187*cdf0e10cSrcweir         setFlag( ornFlags, nApiRelFlag, true );
188*cdf0e10cSrcweir         ornRelPos = ornAbsPos - nBasePos;
189*cdf0e10cSrcweir     }
190*cdf0e10cSrcweir }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBaseAddr, bool bColRel, bool bRowRel )
193*cdf0e10cSrcweir {
194*cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::ReferenceFlags;
195*cdf0e10cSrcweir     lclConvertRefFlags(
196*cdf0e10cSrcweir         orApiRef.Flags, orApiRef.Column, orApiRef.RelativeColumn,
197*cdf0e10cSrcweir         rBaseAddr.Column, COLUMN_RELATIVE, bColRel );
198*cdf0e10cSrcweir     lclConvertRefFlags(
199*cdf0e10cSrcweir         orApiRef.Flags, orApiRef.Row, orApiRef.RelativeRow,
200*cdf0e10cSrcweir         rBaseAddr.Row, ROW_RELATIVE, bRowRel );
201*cdf0e10cSrcweir }
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir Any lclConvertReference( const Any& rRefAny, const CellAddress& rBaseAddr, sal_uInt16 nRelFlags )
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir     if( rRefAny.has< SingleReference >() && !getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ) && !getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) )
206*cdf0e10cSrcweir     {
207*cdf0e10cSrcweir         SingleReference aApiRef;
208*cdf0e10cSrcweir         rRefAny >>= aApiRef;
209*cdf0e10cSrcweir         lclConvertSingleRefFlags( aApiRef, rBaseAddr, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) );
210*cdf0e10cSrcweir         return Any( aApiRef );
211*cdf0e10cSrcweir     }
212*cdf0e10cSrcweir     if( rRefAny.has< ComplexReference >() )
213*cdf0e10cSrcweir     {
214*cdf0e10cSrcweir         ComplexReference aApiRef;
215*cdf0e10cSrcweir         rRefAny >>= aApiRef;
216*cdf0e10cSrcweir         lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddr, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) );
217*cdf0e10cSrcweir         lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddr, getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) );
218*cdf0e10cSrcweir         return Any( aApiRef );
219*cdf0e10cSrcweir     }
220*cdf0e10cSrcweir     return Any();
221*cdf0e10cSrcweir }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir } // namespace
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir // ============================================================================
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir DefinedNameModel::DefinedNameModel() :
228*cdf0e10cSrcweir     mnSheet( -1 ),
229*cdf0e10cSrcweir     mnFuncGroupId( -1 ),
230*cdf0e10cSrcweir     mbMacro( false ),
231*cdf0e10cSrcweir     mbFunction( false ),
232*cdf0e10cSrcweir     mbVBName( false ),
233*cdf0e10cSrcweir     mbHidden( false )
234*cdf0e10cSrcweir {
235*cdf0e10cSrcweir }
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir // ============================================================================
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir DefinedNameBase::DefinedNameBase( const WorkbookHelper& rHelper ) :
240*cdf0e10cSrcweir     WorkbookHelper( rHelper )
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir const OUString& DefinedNameBase::getUpcaseModelName() const
245*cdf0e10cSrcweir {
246*cdf0e10cSrcweir     if( maUpModelName.getLength() == 0 )
247*cdf0e10cSrcweir         maUpModelName = lclGetUpcaseModelName( maModel.maName );
248*cdf0e10cSrcweir     return maUpModelName;
249*cdf0e10cSrcweir }
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir Any DefinedNameBase::getReference( const CellAddress& rBaseAddr ) const
252*cdf0e10cSrcweir {
253*cdf0e10cSrcweir     if( maRefAny.hasValue() && (maModel.maName.getLength() >= 2) && (maModel.maName[ 0 ] == '\x01') )
254*cdf0e10cSrcweir     {
255*cdf0e10cSrcweir         sal_Unicode cFlagsChar = getUpcaseModelName()[ 1 ];
256*cdf0e10cSrcweir         if( ('A' <= cFlagsChar) && (cFlagsChar <= 'P') )
257*cdf0e10cSrcweir         {
258*cdf0e10cSrcweir             sal_uInt16 nRelFlags = static_cast< sal_uInt16 >( cFlagsChar - 'A' );
259*cdf0e10cSrcweir             if( maRefAny.has< ExternalReference >() )
260*cdf0e10cSrcweir             {
261*cdf0e10cSrcweir                 ExternalReference aApiExtRef;
262*cdf0e10cSrcweir                 maRefAny >>= aApiExtRef;
263*cdf0e10cSrcweir                 Any aRefAny = lclConvertReference( aApiExtRef.Reference, rBaseAddr, nRelFlags );
264*cdf0e10cSrcweir                 if( aRefAny.hasValue() )
265*cdf0e10cSrcweir                 {
266*cdf0e10cSrcweir                     aApiExtRef.Reference <<= aRefAny;
267*cdf0e10cSrcweir                     return Any( aApiExtRef );
268*cdf0e10cSrcweir                 }
269*cdf0e10cSrcweir             }
270*cdf0e10cSrcweir             else
271*cdf0e10cSrcweir             {
272*cdf0e10cSrcweir                 return lclConvertReference( maRefAny, rBaseAddr, nRelFlags );
273*cdf0e10cSrcweir             }
274*cdf0e10cSrcweir         }
275*cdf0e10cSrcweir     }
276*cdf0e10cSrcweir     return Any();
277*cdf0e10cSrcweir }
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir ApiTokenSequence DefinedNameBase::importOoxFormula( sal_Int16 nBaseSheet )
280*cdf0e10cSrcweir {
281*cdf0e10cSrcweir     return (maModel.maFormula.getLength() > 0) ?
282*cdf0e10cSrcweir         getFormulaParser().importFormula( CellAddress( nBaseSheet, 0, 0 ), maModel.maFormula ) :
283*cdf0e10cSrcweir         getFormulaParser().convertErrorToFormula( BIFF_ERR_NAME );
284*cdf0e10cSrcweir }
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir ApiTokenSequence DefinedNameBase::importBiff12Formula( sal_Int16 nBaseSheet, SequenceInputStream& rStrm )
287*cdf0e10cSrcweir {
288*cdf0e10cSrcweir     return getFormulaParser().importFormula( CellAddress( nBaseSheet, 0, 0 ), FORMULATYPE_DEFINEDNAME, rStrm );
289*cdf0e10cSrcweir }
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir ApiTokenSequence DefinedNameBase::importBiffFormula( sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize )
292*cdf0e10cSrcweir {
293*cdf0e10cSrcweir     return (!pnFmlaSize || (*pnFmlaSize > 0)) ?
294*cdf0e10cSrcweir         getFormulaParser().importFormula( CellAddress( nBaseSheet, 0, 0 ), FORMULATYPE_DEFINEDNAME, rStrm, pnFmlaSize ) :
295*cdf0e10cSrcweir         getFormulaParser().convertErrorToFormula( BIFF_ERR_NAME );
296*cdf0e10cSrcweir }
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir void DefinedNameBase::extractReference( const ApiTokenSequence& rTokens )
299*cdf0e10cSrcweir {
300*cdf0e10cSrcweir     OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "DefinedNameBase::extractReference - unexpected call" );
301*cdf0e10cSrcweir     maRefAny = getFormulaParser().extractReference( rTokens );
302*cdf0e10cSrcweir }
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir // ============================================================================
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir DefinedName::DefinedName( const WorkbookHelper& rHelper ) :
307*cdf0e10cSrcweir     DefinedNameBase( rHelper ),
308*cdf0e10cSrcweir     mnTokenIndex( -1 ),
309*cdf0e10cSrcweir     mcBuiltinId( BIFF_DEFNAME_UNKNOWN ),
310*cdf0e10cSrcweir     mnFmlaSize( 0 )
311*cdf0e10cSrcweir {
312*cdf0e10cSrcweir }
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir void DefinedName::importDefinedName( const AttributeList& rAttribs )
315*cdf0e10cSrcweir {
316*cdf0e10cSrcweir     maModel.maName        = rAttribs.getXString( XML_name, OUString() );
317*cdf0e10cSrcweir     maModel.mnSheet       = rAttribs.getInteger( XML_localSheetId, -1 );
318*cdf0e10cSrcweir     maModel.mnFuncGroupId = rAttribs.getInteger( XML_functionGroupId, -1 );
319*cdf0e10cSrcweir     maModel.mbMacro       = rAttribs.getBool( XML_xlm, false );
320*cdf0e10cSrcweir     maModel.mbFunction    = rAttribs.getBool( XML_function, false );
321*cdf0e10cSrcweir     maModel.mbVBName      = rAttribs.getBool( XML_vbProcedure, false );
322*cdf0e10cSrcweir     maModel.mbHidden      = rAttribs.getBool( XML_hidden, false );
323*cdf0e10cSrcweir     mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1;
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     /*  Detect built-in state from name itself, there is no built-in flag.
326*cdf0e10cSrcweir         Built-in names are prexixed with '_xlnm.' instead. */
327*cdf0e10cSrcweir     mcBuiltinId = lclGetBuiltinIdFromPrefixedName( maModel.maName );
328*cdf0e10cSrcweir }
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir void DefinedName::setFormula( const OUString& rFormula )
331*cdf0e10cSrcweir {
332*cdf0e10cSrcweir     maModel.maFormula = rFormula;
333*cdf0e10cSrcweir }
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir void DefinedName::importDefinedName( SequenceInputStream& rStrm )
336*cdf0e10cSrcweir {
337*cdf0e10cSrcweir     sal_uInt32 nFlags;
338*cdf0e10cSrcweir     rStrm >> nFlags;
339*cdf0e10cSrcweir     rStrm.skip( 1 );    // keyboard shortcut
340*cdf0e10cSrcweir     rStrm >> maModel.mnSheet >> maModel.maName;
341*cdf0e10cSrcweir     mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1;
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir     // macro function/command, hidden flag
344*cdf0e10cSrcweir     maModel.mnFuncGroupId = extractValue< sal_Int32 >( nFlags, 6, 9 );
345*cdf0e10cSrcweir     maModel.mbMacro       = getFlag( nFlags, BIFF12_DEFNAME_MACRO );
346*cdf0e10cSrcweir     maModel.mbFunction    = getFlag( nFlags, BIFF12_DEFNAME_FUNC );
347*cdf0e10cSrcweir     maModel.mbVBName      = getFlag( nFlags, BIFF12_DEFNAME_VBNAME );
348*cdf0e10cSrcweir     maModel.mbHidden      = getFlag( nFlags, BIFF12_DEFNAME_HIDDEN );
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir     // get built-in name index from name
351*cdf0e10cSrcweir     if( getFlag( nFlags, BIFF12_DEFNAME_BUILTIN ) )
352*cdf0e10cSrcweir         mcBuiltinId = lclGetBuiltinIdFromBaseName( maModel.maName );
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir     // store token array data
355*cdf0e10cSrcweir     sal_Int64 nRecPos = rStrm.tell();
356*cdf0e10cSrcweir     sal_Int32 nFmlaSize = rStrm.readInt32();
357*cdf0e10cSrcweir     rStrm.skip( nFmlaSize );
358*cdf0e10cSrcweir     sal_Int32 nAddDataSize = rStrm.readInt32();
359*cdf0e10cSrcweir     if( !rStrm.isEof() && (nFmlaSize > 0) && (nAddDataSize >= 0) && (rStrm.getRemaining() >= nAddDataSize) )
360*cdf0e10cSrcweir     {
361*cdf0e10cSrcweir         sal_Int32 nTotalSize = 8 + nFmlaSize + nAddDataSize;
362*cdf0e10cSrcweir         mxFormula.reset( new StreamDataSequence );
363*cdf0e10cSrcweir         rStrm.seek( nRecPos );
364*cdf0e10cSrcweir         rStrm.readData( *mxFormula, nTotalSize );
365*cdf0e10cSrcweir     }
366*cdf0e10cSrcweir }
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir void DefinedName::importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet )
369*cdf0e10cSrcweir {
370*cdf0e10cSrcweir     BiffType eBiff = getBiff();
371*cdf0e10cSrcweir     sal_uInt16 nFlags = 0;
372*cdf0e10cSrcweir     sal_Int16 nRefId = BIFF_DEFNAME_GLOBAL;
373*cdf0e10cSrcweir     sal_Int16 nTabId = BIFF_DEFNAME_GLOBAL;
374*cdf0e10cSrcweir     sal_uInt8 nNameLen = 0, nShortCut = 0;
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir     switch( eBiff )
377*cdf0e10cSrcweir     {
378*cdf0e10cSrcweir         case BIFF2:
379*cdf0e10cSrcweir         {
380*cdf0e10cSrcweir             sal_uInt8 nFlagsBiff2;
381*cdf0e10cSrcweir             rStrm >> nFlagsBiff2;
382*cdf0e10cSrcweir             rStrm.skip( 1 );
383*cdf0e10cSrcweir             rStrm >> nShortCut >> nNameLen;
384*cdf0e10cSrcweir             mnFmlaSize = rStrm.readuInt8();
385*cdf0e10cSrcweir             setFlag( nFlags, BIFF_DEFNAME_FUNC, getFlag( nFlagsBiff2, BIFF2_DEFNAME_FUNC ) );
386*cdf0e10cSrcweir             maModel.maName = rStrm.readCharArrayUC( nNameLen, getTextEncoding(), true );
387*cdf0e10cSrcweir         }
388*cdf0e10cSrcweir         break;
389*cdf0e10cSrcweir         case BIFF3:
390*cdf0e10cSrcweir         case BIFF4:
391*cdf0e10cSrcweir             rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize;
392*cdf0e10cSrcweir             maModel.maName = rStrm.readCharArrayUC( nNameLen, getTextEncoding(), true );
393*cdf0e10cSrcweir         break;
394*cdf0e10cSrcweir         case BIFF5:
395*cdf0e10cSrcweir             rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize >> nRefId >> nTabId;
396*cdf0e10cSrcweir             rStrm.skip( 4 );
397*cdf0e10cSrcweir             maModel.maName = rStrm.readCharArrayUC( nNameLen, getTextEncoding(), true );
398*cdf0e10cSrcweir         break;
399*cdf0e10cSrcweir         case BIFF8:
400*cdf0e10cSrcweir             rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize >> nRefId >> nTabId;
401*cdf0e10cSrcweir             rStrm.skip( 4 );
402*cdf0e10cSrcweir             maModel.maName = rStrm.readUniStringBody( nNameLen, true );
403*cdf0e10cSrcweir         break;
404*cdf0e10cSrcweir         case BIFF_UNKNOWN: break;
405*cdf0e10cSrcweir     }
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir     // macro function/command, hidden flag
408*cdf0e10cSrcweir     maModel.mnFuncGroupId = extractValue< sal_Int32 >( nFlags, 6, 6 );
409*cdf0e10cSrcweir     maModel.mbMacro       = getFlag( nFlags, BIFF_DEFNAME_MACRO );
410*cdf0e10cSrcweir     maModel.mbFunction    = getFlag( nFlags, BIFF_DEFNAME_FUNC );
411*cdf0e10cSrcweir     maModel.mbVBName      = getFlag( nFlags, BIFF_DEFNAME_VBNAME );
412*cdf0e10cSrcweir     maModel.mbHidden      = getFlag( nFlags, BIFF_DEFNAME_HIDDEN );
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir     // get built-in name index from name
415*cdf0e10cSrcweir     if( getFlag( nFlags, BIFF_DEFNAME_BUILTIN ) )
416*cdf0e10cSrcweir     {
417*cdf0e10cSrcweir         // name may be the built-in identifier or the built-in base name
418*cdf0e10cSrcweir         if( maModel.maName.getLength() == 1 )
419*cdf0e10cSrcweir             mcBuiltinId = maModel.maName[ 0 ];
420*cdf0e10cSrcweir         else
421*cdf0e10cSrcweir             mcBuiltinId = lclGetBuiltinIdFromBaseName( maModel.maName );
422*cdf0e10cSrcweir     }
423*cdf0e10cSrcweir     /*  In BIFF5, '_FilterDatabase' appears as hidden user name without
424*cdf0e10cSrcweir         built-in flag, and even worse, localized. */
425*cdf0e10cSrcweir     else if( (eBiff == BIFF5) && lclIsFilterDatabaseName( maModel.maName ) )
426*cdf0e10cSrcweir     {
427*cdf0e10cSrcweir         mcBuiltinId = BIFF_DEFNAME_FILTERDATABASE;
428*cdf0e10cSrcweir     }
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir     // get sheet index for sheet-local names in BIFF5-BIFF8
431*cdf0e10cSrcweir     switch( getBiff() )
432*cdf0e10cSrcweir     {
433*cdf0e10cSrcweir         case BIFF2:
434*cdf0e10cSrcweir         case BIFF3:
435*cdf0e10cSrcweir         case BIFF4:
436*cdf0e10cSrcweir             // BIFF2-BIFF4: all defined names are sheet-local
437*cdf0e10cSrcweir             mnCalcSheet = nCalcSheet;
438*cdf0e10cSrcweir         break;
439*cdf0e10cSrcweir         case BIFF5:
440*cdf0e10cSrcweir             // #i44019# nTabId may be invalid, resolve nRefId to sheet index
441*cdf0e10cSrcweir             if( nRefId != BIFF_DEFNAME_GLOBAL )
442*cdf0e10cSrcweir                 if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
443*cdf0e10cSrcweir                     if( pExtLink->getLinkType() == LINKTYPE_INTERNAL )
444*cdf0e10cSrcweir                         mnCalcSheet = pExtLink->getCalcSheetIndex();
445*cdf0e10cSrcweir         break;
446*cdf0e10cSrcweir         case BIFF8:
447*cdf0e10cSrcweir             // convert one-based worksheet index to zero-based Calc sheet index
448*cdf0e10cSrcweir             OSL_ENSURE( nTabId >= 0, "DefinedName::importDefinedName - invalid local sheet index" );
449*cdf0e10cSrcweir             if( nTabId != BIFF_DEFNAME_GLOBAL )
450*cdf0e10cSrcweir                 mnCalcSheet = getWorksheets().getCalcSheetIndex( nTabId - 1 );
451*cdf0e10cSrcweir         break;
452*cdf0e10cSrcweir         case BIFF_UNKNOWN:
453*cdf0e10cSrcweir         break;
454*cdf0e10cSrcweir     }
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir     if( (getBiff() <= BIFF4) && maModel.mbHidden && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') )
457*cdf0e10cSrcweir     {
458*cdf0e10cSrcweir         /*  Read the token array of special internal names containing addresses
459*cdf0e10cSrcweir             for BIFF3-BIFF4 3D references immediately. It is expected that
460*cdf0e10cSrcweir             these names contain a simple cell reference or range reference.
461*cdf0e10cSrcweir             Other regular defined names and external names rely on existence of
462*cdf0e10cSrcweir             this reference. */
463*cdf0e10cSrcweir         ApiTokenSequence aTokens = importBiffFormula( mnCalcSheet, rStrm, &mnFmlaSize );
464*cdf0e10cSrcweir         extractReference( aTokens );
465*cdf0e10cSrcweir     }
466*cdf0e10cSrcweir     else
467*cdf0e10cSrcweir     {
468*cdf0e10cSrcweir         /*  Store record position of other defined names to be able to import
469*cdf0e10cSrcweir             token array later. This is needed to correctly resolve references
470*cdf0e10cSrcweir             to names that are stored later in the defined names list following
471*cdf0e10cSrcweir             this name. */
472*cdf0e10cSrcweir         mxBiffStrm.reset( new BiffInputStreamPos( rStrm ) );
473*cdf0e10cSrcweir     }
474*cdf0e10cSrcweir }
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir void DefinedName::createNameObject()
477*cdf0e10cSrcweir {
478*cdf0e10cSrcweir     // do not create names for (macro) functions or VBA procedures
479*cdf0e10cSrcweir     // #163146# do not ignore hidden names (may be regular names created by VBA scripts)
480*cdf0e10cSrcweir     if( /*maModel.mbHidden ||*/ maModel.mbFunction || maModel.mbVBName )
481*cdf0e10cSrcweir         return;
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir     // skip BIFF names without stream position (e.g. BIFF3-BIFF4 internal 3D references)
484*cdf0e10cSrcweir     if( (getFilterType() == FILTER_BIFF) && !mxBiffStrm.get() )
485*cdf0e10cSrcweir         return;
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir     // convert original name to final Calc name (TODO: filter invalid characters from model name)
488*cdf0e10cSrcweir     maCalcName = isBuiltinName() ? lclGetPrefixedName( mcBuiltinId ) : maModel.maName;
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir     // #163146# do not rename sheet-local names by default, this breaks VBA scripts
491*cdf0e10cSrcweir #if 0
492*cdf0e10cSrcweir     // append sheet index for local names in multi-sheet documents
493*cdf0e10cSrcweir     if( isWorkbookFile() && !isGlobalName() )
494*cdf0e10cSrcweir         maCalcName = OUStringBuffer( maCalcName ).append( sal_Unicode( '_' ) ).
495*cdf0e10cSrcweir             append( static_cast< sal_Int32 >( mnCalcSheet + 1 ) ).makeStringAndClear();
496*cdf0e10cSrcweir #endif
497*cdf0e10cSrcweir 
498*cdf0e10cSrcweir     // special flags for this name
499*cdf0e10cSrcweir     sal_Int32 nNameFlags = 0;
500*cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::NamedRangeFlag;
501*cdf0e10cSrcweir     if( !isGlobalName() ) switch( mcBuiltinId )
502*cdf0e10cSrcweir     {
503*cdf0e10cSrcweir         case BIFF_DEFNAME_CRITERIA:     nNameFlags = FILTER_CRITERIA;               break;
504*cdf0e10cSrcweir         case BIFF_DEFNAME_PRINTAREA:    nNameFlags = PRINT_AREA;                    break;
505*cdf0e10cSrcweir         case BIFF_DEFNAME_PRINTTITLES:  nNameFlags = COLUMN_HEADER | ROW_HEADER;    break;
506*cdf0e10cSrcweir     }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir     // create the name and insert it into the document, maCalcName will be changed to the resulting name
509*cdf0e10cSrcweir     mxNamedRange = createNamedRangeObject( maCalcName, nNameFlags );
510*cdf0e10cSrcweir     // index of this defined name used in formula token arrays
511*cdf0e10cSrcweir     PropertySet aPropSet( mxNamedRange );
512*cdf0e10cSrcweir     aPropSet.getProperty( mnTokenIndex, PROP_TokenIndex );
513*cdf0e10cSrcweir }
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir void DefinedName::convertFormula()
516*cdf0e10cSrcweir {
517*cdf0e10cSrcweir     Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY );
518*cdf0e10cSrcweir     if( !xTokens.is() )
519*cdf0e10cSrcweir         return;
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir     // convert and set formula of the defined name
522*cdf0e10cSrcweir     ApiTokenSequence aTokens;
523*cdf0e10cSrcweir     switch( getFilterType() )
524*cdf0e10cSrcweir     {
525*cdf0e10cSrcweir         case FILTER_OOXML:
526*cdf0e10cSrcweir         {
527*cdf0e10cSrcweir             if( mxFormula.get() )
528*cdf0e10cSrcweir             {
529*cdf0e10cSrcweir                 SequenceInputStream aStrm( *mxFormula );
530*cdf0e10cSrcweir                 aTokens = importBiff12Formula( mnCalcSheet, aStrm );
531*cdf0e10cSrcweir             }
532*cdf0e10cSrcweir             else
533*cdf0e10cSrcweir                 aTokens = importOoxFormula( mnCalcSheet );
534*cdf0e10cSrcweir         }
535*cdf0e10cSrcweir         break;
536*cdf0e10cSrcweir         case FILTER_BIFF:
537*cdf0e10cSrcweir         {
538*cdf0e10cSrcweir             OSL_ENSURE( mxBiffStrm.get(), "DefinedName::convertFormula - missing BIFF stream" );
539*cdf0e10cSrcweir             if( mxBiffStrm.get() )
540*cdf0e10cSrcweir             {
541*cdf0e10cSrcweir                 BiffInputStream& rStrm = mxBiffStrm->getStream();
542*cdf0e10cSrcweir                 BiffInputStreamPosGuard aStrmGuard( rStrm );
543*cdf0e10cSrcweir                 if( mxBiffStrm->restorePosition() )
544*cdf0e10cSrcweir                     aTokens = importBiffFormula( mnCalcSheet, rStrm, &mnFmlaSize );
545*cdf0e10cSrcweir             }
546*cdf0e10cSrcweir         }
547*cdf0e10cSrcweir         break;
548*cdf0e10cSrcweir         case FILTER_UNKNOWN:
549*cdf0e10cSrcweir         break;
550*cdf0e10cSrcweir     }
551*cdf0e10cSrcweir     xTokens->setTokens( aTokens );
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir     // set built-in names (print ranges, repeated titles, filter ranges)
554*cdf0e10cSrcweir     if( !isGlobalName() ) switch( mcBuiltinId )
555*cdf0e10cSrcweir     {
556*cdf0e10cSrcweir         case BIFF_DEFNAME_PRINTAREA:
557*cdf0e10cSrcweir         {
558*cdf0e10cSrcweir             Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY );
559*cdf0e10cSrcweir             ApiCellRangeList aPrintRanges;
560*cdf0e10cSrcweir             getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, mnCalcSheet );
561*cdf0e10cSrcweir             if( xPrintAreas.is() && !aPrintRanges.empty() )
562*cdf0e10cSrcweir                 xPrintAreas->setPrintAreas( ContainerHelper::vectorToSequence( aPrintRanges ) );
563*cdf0e10cSrcweir         }
564*cdf0e10cSrcweir         break;
565*cdf0e10cSrcweir         case BIFF_DEFNAME_PRINTTITLES:
566*cdf0e10cSrcweir         {
567*cdf0e10cSrcweir             Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY );
568*cdf0e10cSrcweir             ApiCellRangeList aTitleRanges;
569*cdf0e10cSrcweir             getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, mnCalcSheet );
570*cdf0e10cSrcweir             if( xPrintAreas.is() && !aTitleRanges.empty() )
571*cdf0e10cSrcweir             {
572*cdf0e10cSrcweir                 bool bHasRowTitles = false;
573*cdf0e10cSrcweir                 bool bHasColTitles = false;
574*cdf0e10cSrcweir                 const CellAddress& rMaxPos = getAddressConverter().getMaxAddress();
575*cdf0e10cSrcweir                 for( ApiCellRangeList::const_iterator aIt = aTitleRanges.begin(), aEnd = aTitleRanges.end(); (aIt != aEnd) && (!bHasRowTitles || !bHasColTitles); ++aIt )
576*cdf0e10cSrcweir                 {
577*cdf0e10cSrcweir                     bool bFullRow = (aIt->StartColumn == 0) && (aIt->EndColumn >= rMaxPos.Column);
578*cdf0e10cSrcweir                     bool bFullCol = (aIt->StartRow == 0) && (aIt->EndRow >= rMaxPos.Row);
579*cdf0e10cSrcweir                     if( !bHasRowTitles && bFullRow && !bFullCol )
580*cdf0e10cSrcweir                     {
581*cdf0e10cSrcweir                         xPrintAreas->setTitleRows( *aIt );
582*cdf0e10cSrcweir                         xPrintAreas->setPrintTitleRows( sal_True );
583*cdf0e10cSrcweir                         bHasRowTitles = true;
584*cdf0e10cSrcweir                     }
585*cdf0e10cSrcweir                     else if( !bHasColTitles && bFullCol && !bFullRow )
586*cdf0e10cSrcweir                     {
587*cdf0e10cSrcweir                         xPrintAreas->setTitleColumns( *aIt );
588*cdf0e10cSrcweir                         xPrintAreas->setPrintTitleColumns( sal_True );
589*cdf0e10cSrcweir                         bHasColTitles = true;
590*cdf0e10cSrcweir                     }
591*cdf0e10cSrcweir                 }
592*cdf0e10cSrcweir             }
593*cdf0e10cSrcweir         }
594*cdf0e10cSrcweir         break;
595*cdf0e10cSrcweir     }
596*cdf0e10cSrcweir }
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir bool DefinedName::getAbsoluteRange( CellRangeAddress& orRange ) const
599*cdf0e10cSrcweir {
600*cdf0e10cSrcweir     /*  ScNamedRangeObj::XCellRangeReferrer::getReferredCells is buggy with
601*cdf0e10cSrcweir         relative references, so we extract an absolute reference by hand. */
602*cdf0e10cSrcweir     Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY );
603*cdf0e10cSrcweir     return xTokens.is() && getFormulaParser().extractCellRange( orRange, xTokens->getTokens(), false );
604*cdf0e10cSrcweir }
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir // ============================================================================
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir DefinedNamesBuffer::DefinedNamesBuffer( const WorkbookHelper& rHelper ) :
609*cdf0e10cSrcweir     WorkbookHelper( rHelper ),
610*cdf0e10cSrcweir     mnCalcSheet( -1 )
611*cdf0e10cSrcweir {
612*cdf0e10cSrcweir }
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir void DefinedNamesBuffer::setLocalCalcSheet( sal_Int16 nCalcSheet )
615*cdf0e10cSrcweir {
616*cdf0e10cSrcweir     OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4),
617*cdf0e10cSrcweir         "DefinedNamesBuffer::setLocalCalcSheet - invalid call" );
618*cdf0e10cSrcweir     mnCalcSheet = nCalcSheet;
619*cdf0e10cSrcweir }
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir DefinedNameRef DefinedNamesBuffer::importDefinedName( const AttributeList& rAttribs )
622*cdf0e10cSrcweir {
623*cdf0e10cSrcweir     DefinedNameRef xDefName = createDefinedName();
624*cdf0e10cSrcweir     xDefName->importDefinedName( rAttribs );
625*cdf0e10cSrcweir     return xDefName;
626*cdf0e10cSrcweir }
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir void DefinedNamesBuffer::importDefinedName( SequenceInputStream& rStrm )
629*cdf0e10cSrcweir {
630*cdf0e10cSrcweir     createDefinedName()->importDefinedName( rStrm );
631*cdf0e10cSrcweir }
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir void DefinedNamesBuffer::importDefinedName( BiffInputStream& rStrm )
634*cdf0e10cSrcweir {
635*cdf0e10cSrcweir     createDefinedName()->importDefinedName( rStrm, mnCalcSheet );
636*cdf0e10cSrcweir }
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir void DefinedNamesBuffer::finalizeImport()
639*cdf0e10cSrcweir {
640*cdf0e10cSrcweir     // first insert all names without formula definition into the document, and insert them into the maps
641*cdf0e10cSrcweir     for( DefNameVector::iterator aIt = maDefNames.begin(), aEnd = maDefNames.end(); aIt != aEnd; ++aIt )
642*cdf0e10cSrcweir     {
643*cdf0e10cSrcweir         DefinedNameRef xDefName = *aIt;
644*cdf0e10cSrcweir         xDefName->createNameObject();
645*cdf0e10cSrcweir         // map by sheet index and original model name
646*cdf0e10cSrcweir         maModelNameMap[ SheetNameKey( xDefName->getLocalCalcSheet(), xDefName->getUpcaseModelName() ) ] = xDefName;
647*cdf0e10cSrcweir         // map by sheet index and built-in identifier
648*cdf0e10cSrcweir         if( !xDefName->isGlobalName() && xDefName->isBuiltinName() )
649*cdf0e10cSrcweir             maBuiltinMap[ BuiltinKey( xDefName->getLocalCalcSheet(), xDefName->getBuiltinId() ) ] = xDefName;
650*cdf0e10cSrcweir         // map by API formula token identifier
651*cdf0e10cSrcweir         sal_Int32 nTokenIndex = xDefName->getTokenIndex();
652*cdf0e10cSrcweir         if( nTokenIndex >= 0 )
653*cdf0e10cSrcweir             maTokenIdMap[ nTokenIndex ] = xDefName;
654*cdf0e10cSrcweir     }
655*cdf0e10cSrcweir 
656*cdf0e10cSrcweir     /*  Now convert all name formulas, so that the formula parser can find all
657*cdf0e10cSrcweir         names in case of circular dependencies. */
658*cdf0e10cSrcweir     maDefNames.forEachMem( &DefinedName::convertFormula );
659*cdf0e10cSrcweir }
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir DefinedNameRef DefinedNamesBuffer::getByIndex( sal_Int32 nIndex ) const
662*cdf0e10cSrcweir {
663*cdf0e10cSrcweir     return maDefNames.get( nIndex );
664*cdf0e10cSrcweir }
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir DefinedNameRef DefinedNamesBuffer::getByTokenIndex( sal_Int32 nIndex ) const
667*cdf0e10cSrcweir {
668*cdf0e10cSrcweir     return maTokenIdMap.get( nIndex );
669*cdf0e10cSrcweir }
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, sal_Int16 nCalcSheet ) const
672*cdf0e10cSrcweir {
673*cdf0e10cSrcweir     OUString aUpcaseName = lclGetUpcaseModelName( rModelName );
674*cdf0e10cSrcweir     DefinedNameRef xDefName = maModelNameMap.get( SheetNameKey( nCalcSheet, aUpcaseName ) );
675*cdf0e10cSrcweir     // lookup global name, if no local name exists
676*cdf0e10cSrcweir     if( !xDefName && (nCalcSheet >= 0) )
677*cdf0e10cSrcweir         xDefName = maModelNameMap.get( SheetNameKey( -1, aUpcaseName ) );
678*cdf0e10cSrcweir     return xDefName;
679*cdf0e10cSrcweir }
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir DefinedNameRef DefinedNamesBuffer::getByBuiltinId( sal_Unicode cBuiltinId, sal_Int16 nCalcSheet ) const
682*cdf0e10cSrcweir {
683*cdf0e10cSrcweir     return maBuiltinMap.get( BuiltinKey( nCalcSheet, cBuiltinId ) );
684*cdf0e10cSrcweir }
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir DefinedNameRef DefinedNamesBuffer::createDefinedName()
687*cdf0e10cSrcweir {
688*cdf0e10cSrcweir     DefinedNameRef xDefName( new DefinedName( *this ) );
689*cdf0e10cSrcweir     maDefNames.push_back( xDefName );
690*cdf0e10cSrcweir     return xDefName;
691*cdf0e10cSrcweir }
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir // ============================================================================
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir } // namespace xls
696*cdf0e10cSrcweir } // namespace oox
697