1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xiname.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "rangenam.hxx"
35 #include "xistream.hxx"
37 // for formula compiler
38 #include "excform.hxx"
40 #include "excimp8.hxx"
42 // ============================================================================
43 // *** Implementation ***
44 // ============================================================================
46 XclImpName::XclImpName( XclImpStream
& rStrm
, sal_uInt16 nXclNameIdx
) :
47 XclImpRoot( rStrm
.GetRoot() ),
49 mcBuiltIn( EXC_BUILTIN_UNKNOWN
),
53 ExcelToSc
& rFmlaConv
= GetOldFmlaConverter();
54 ScRangeName
& rRangeNames
= GetNamedRanges();
56 // 1) *** read data from stream *** ---------------------------------------
58 sal_uInt16 nFlags
= 0, nFmlaSize
= 0, nExtSheet
= EXC_NAME_GLOBAL
, nXclTab
= EXC_NAME_GLOBAL
;
59 sal_uInt8 nNameLen
= 0, nShortCut
;
65 sal_uInt8 nFlagsBiff2
;
68 rStrm
>> nShortCut
>> nNameLen
;
69 nFmlaSize
= rStrm
.ReaduInt8();
70 ::set_flag( nFlags
, EXC_NAME_FUNC
, ::get_flag( nFlagsBiff2
, EXC_NAME2_FUNC
) );
77 rStrm
>> nFlags
>> nShortCut
>> nNameLen
>> nFmlaSize
;
84 rStrm
>> nFlags
>> nShortCut
>> nNameLen
>> nFmlaSize
>> nExtSheet
>> nXclTab
;
89 default: DBG_ERROR_BIFF();
92 if( GetBiff() <= EXC_BIFF5
)
93 maXclName
= rStrm
.ReadRawByteString( nNameLen
);
95 maXclName
= rStrm
.ReadUniString( nNameLen
);
97 // 2) *** convert sheet index and name *** --------------------------------
99 // Visual Basic procedure
100 mbVBName
= ::get_flag( nFlags
, EXC_NAME_VB
);
102 // get built-in name, or convert characters invalid in Calc
103 bool bBuiltIn
= ::get_flag( nFlags
, EXC_NAME_BUILTIN
);
105 // special case for BIFF5 filter range - name appears as plain text without built-in flag
106 if( (GetBiff() == EXC_BIFF5
) && (maXclName
== XclTools::GetXclBuiltInDefName( EXC_BUILTIN_FILTERDATABASE
)) )
109 maXclName
.Assign( EXC_BUILTIN_FILTERDATABASE
);
112 // convert Excel name to Calc name
116 maScName
= maXclName
;
121 if( maXclName
.Len() )
122 mcBuiltIn
= maXclName
.GetChar( 0 );
123 if( mcBuiltIn
== '?' ) // NUL character is imported as '?'
125 maScName
= XclTools::GetBuiltInDefName( mcBuiltIn
);
130 maScName
= maXclName
;
131 ScfTools::ConvertToScDefinedName( maScName
);
134 // add index for local names
135 if( nXclTab
!= EXC_NAME_GLOBAL
)
137 sal_uInt16 nUsedTab
= (GetBiff() == EXC_BIFF8
) ? nXclTab
: nExtSheet
;
138 maScName
.Append( '_' ).Append( String::CreateFromInt32( nUsedTab
) );
139 // TODO: may not work for BIFF5, handle skipped sheets (all BIFF)
140 mnScTab
= static_cast< SCTAB
>( nUsedTab
- 1 );
143 // find an unused name
144 String
aOrigName( maScName
);
145 sal_Int32 nCounter
= 0;
147 while( rRangeNames
.SearchName( maScName
, nDummy
) )
148 maScName
.Assign( aOrigName
).Append( ' ' ).Append( String::CreateFromInt32( ++nCounter
) );
150 // 3) *** convert the name definition formula *** -------------------------
153 const ScTokenArray
* pTokArr
= 0; // pointer to token array, owned by rFmlaConv
154 RangeType nNameType
= RT_NAME
;
156 if( ::get_flag( nFlags
, EXC_NAME_BIG
) )
158 // special, unsupported name
159 rFmlaConv
.GetDummy( pTokArr
);
163 SCsTAB
const nLocalTab
= (nXclTab
== EXC_NAME_GLOBAL
) ? SCTAB_MAX
: (nXclTab
- 1);
165 // --- print ranges or title ranges ---
166 rStrm
.PushPosition();
169 case EXC_BUILTIN_PRINTAREA
:
170 if( rFmlaConv
.Convert( GetPrintAreaBuffer(), rStrm
, nFmlaSize
, nLocalTab
, FT_RangeName
) == ConvOK
)
171 nNameType
|= RT_PRINTAREA
;
173 case EXC_BUILTIN_PRINTTITLES
:
174 if( rFmlaConv
.Convert( GetTitleAreaBuffer(), rStrm
, nFmlaSize
, nLocalTab
, FT_RangeName
) == ConvOK
)
175 nNameType
|= RT_COLHEADER
| RT_ROWHEADER
;
180 // --- name formula ---
181 // JEG : double check this. It is clearly false for normal names
182 // but some of the builtins (sheettitle?) might be able to handle arrays
183 ExcelConverterBase::ConvertParam aParam
;
184 aParam
.mbAllowArrays
= false;
185 rFmlaConv
.Convert( pTokArr
, rStrm
, nFmlaSize
, aParam
, FT_RangeName
);
187 // --- auto or advanced filter ---
188 if( (GetBiff() == EXC_BIFF8
) && pTokArr
&& bBuiltIn
)
191 if( pTokArr
->IsReference( aRange
) )
195 case EXC_BUILTIN_FILTERDATABASE
:
196 GetFilterManager().Insert( &GetOldRoot(), aRange
, maScName
);
198 case EXC_BUILTIN_CRITERIA
:
199 GetFilterManager().AddAdvancedRange( aRange
);
200 nNameType
|= RT_CRITERIA
;
202 case EXC_BUILTIN_EXTRACT
:
203 if( pTokArr
->IsValidReference( aRange
) )
204 GetFilterManager().AddExtractPos( aRange
);
210 else if( nFmlaSize
> 0 )
212 // regular defined name
213 ExcelConverterBase::ConvertParam aParam
;
214 aParam
.mbAllowArrays
= true;
215 rFmlaConv
.Convert( pTokArr
, rStrm
, nFmlaSize
, aParam
, FT_RangeName
);
218 // 4) *** create a defined name in the Calc document *** ------------------
220 if( pTokArr
&& (bBuiltIn
|| !::get_flag( nFlags
, EXC_NAME_HIDDEN
)) && !mbVBName
)
222 // create the Calc name data
223 ScRangeData
* pData
= new ScRangeData( GetDocPtr(), maScName
, *pTokArr
, ScAddress(), nNameType
);
224 pData
->GuessPosition(); // calculate base position for relative refs
225 pData
->SetIndex( nXclNameIdx
); // used as unique identifier in formulas
226 rRangeNames
.Insert( pData
); // takes ownership of pData
227 mpScData
= pData
; // cache for later use
231 // ----------------------------------------------------------------------------
233 XclImpNameManager::XclImpNameManager( const XclImpRoot
& rRoot
) :
238 void XclImpNameManager::ReadName( XclImpStream
& rStrm
)
240 ULONG nCount
= maNameList
.Count();
241 if( nCount
< 0xFFFF )
242 maNameList
.Append( new XclImpName( rStrm
, static_cast< sal_uInt16
>( nCount
+ 1 ) ) );
245 const XclImpName
* XclImpNameManager::FindName( const String
& rXclName
, SCTAB nScTab
) const
247 const XclImpName
* pGlobalName
= 0; // a found global name
248 const XclImpName
* pLocalName
= 0; // a found local name
249 for( const XclImpName
* pName
= maNameList
.First(); pName
&& !pLocalName
; pName
= maNameList
.Next() )
251 if( pName
->GetXclName() == rXclName
)
253 if( pName
->GetScTab() == nScTab
)
255 else if( pName
->IsGlobal() )
259 return pLocalName
? pLocalName
: pGlobalName
;
262 const XclImpName
* XclImpNameManager::GetName( sal_uInt16 nXclNameIdx
) const
264 DBG_ASSERT( nXclNameIdx
> 0, "XclImpNameManager::GetName - index must be >0" );
265 return maNameList
.GetObject( nXclNameIdx
- 1 );
268 // ============================================================================