merge the formfield patch from ooo-build
[ooovba.git] / sc / source / filter / excel / xiname.cxx
blob0ad70d538048000fb2bd73598dcba8aa219167dd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xiname.cxx,v $
10 * $Revision: 1.10 $
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"
33 #include "xiname.hxx"
34 #include "rangenam.hxx"
35 #include "xistream.hxx"
37 // for formula compiler
38 #include "excform.hxx"
39 // for filter manager
40 #include "excimp8.hxx"
42 // ============================================================================
43 // *** Implementation ***
44 // ============================================================================
46 XclImpName::XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx ) :
47 XclImpRoot( rStrm.GetRoot() ),
48 mpScData( 0 ),
49 mcBuiltIn( EXC_BUILTIN_UNKNOWN ),
50 mnScTab( SCTAB_MAX ),
51 mbVBName( false )
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;
61 switch( GetBiff() )
63 case EXC_BIFF2:
65 sal_uInt8 nFlagsBiff2;
66 rStrm >> nFlagsBiff2;
67 rStrm.Ignore( 1 );
68 rStrm >> nShortCut >> nNameLen;
69 nFmlaSize = rStrm.ReaduInt8();
70 ::set_flag( nFlags, EXC_NAME_FUNC, ::get_flag( nFlagsBiff2, EXC_NAME2_FUNC ) );
72 break;
74 case EXC_BIFF3:
75 case EXC_BIFF4:
77 rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize;
79 break;
81 case EXC_BIFF5:
82 case EXC_BIFF8:
84 rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize >> nExtSheet >> nXclTab;
85 rStrm.Ignore( 4 );
87 break;
89 default: DBG_ERROR_BIFF();
92 if( GetBiff() <= EXC_BIFF5 )
93 maXclName = rStrm.ReadRawByteString( nNameLen );
94 else
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 )) )
108 bBuiltIn = true;
109 maXclName.Assign( EXC_BUILTIN_FILTERDATABASE );
112 // convert Excel name to Calc name
113 if( mbVBName )
115 // VB macro name
116 maScName = maXclName;
118 else if( bBuiltIn )
120 // built-in name
121 if( maXclName.Len() )
122 mcBuiltIn = maXclName.GetChar( 0 );
123 if( mcBuiltIn == '?' ) // NUL character is imported as '?'
124 mcBuiltIn = '\0';
125 maScName = XclTools::GetBuiltInDefName( mcBuiltIn );
127 else
129 // any other name
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;
146 USHORT nDummy;
147 while( rRangeNames.SearchName( maScName, nDummy ) )
148 maScName.Assign( aOrigName ).Append( ' ' ).Append( String::CreateFromInt32( ++nCounter ) );
150 // 3) *** convert the name definition formula *** -------------------------
152 rFmlaConv.Reset();
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 );
161 else if( bBuiltIn )
163 SCsTAB const nLocalTab = (nXclTab == EXC_NAME_GLOBAL) ? SCTAB_MAX : (nXclTab - 1);
165 // --- print ranges or title ranges ---
166 rStrm.PushPosition();
167 switch( mcBuiltIn )
169 case EXC_BUILTIN_PRINTAREA:
170 if( rFmlaConv.Convert( GetPrintAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvOK )
171 nNameType |= RT_PRINTAREA;
172 break;
173 case EXC_BUILTIN_PRINTTITLES:
174 if( rFmlaConv.Convert( GetTitleAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvOK )
175 nNameType |= RT_COLHEADER | RT_ROWHEADER;
176 break;
178 rStrm.PopPosition();
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 )
190 ScRange aRange;
191 if( pTokArr->IsReference( aRange ) )
193 switch( mcBuiltIn )
195 case EXC_BUILTIN_FILTERDATABASE:
196 GetFilterManager().Insert( &GetOldRoot(), aRange, maScName );
197 break;
198 case EXC_BUILTIN_CRITERIA:
199 GetFilterManager().AddAdvancedRange( aRange );
200 nNameType |= RT_CRITERIA;
201 break;
202 case EXC_BUILTIN_EXTRACT:
203 if( pTokArr->IsValidReference( aRange ) )
204 GetFilterManager().AddExtractPos( aRange );
205 break;
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 ) :
234 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 )
254 pLocalName = pName;
255 else if( pName->IsGlobal() )
256 pGlobalName = pName;
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 // ============================================================================