Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "xiname.hxx"
30 : : #include "rangenam.hxx"
31 : : #include "xistream.hxx"
32 : :
33 : : // for formula compiler
34 : : #include "excform.hxx"
35 : : // for filter manager
36 : : #include "excimp8.hxx"
37 : : #include "scextopt.hxx"
38 : : #include "document.hxx"
39 : : // ============================================================================
40 : : // *** Implementation ***
41 : : // ============================================================================
42 : :
43 : 48 : XclImpName::TokenStrmData::TokenStrmData( XclImpStream& rStrm ) :
44 : 48 : mrStrm(rStrm), mnStrmPos(0), mnStrmSize(0) {}
45 : :
46 : 66 : XclImpName::XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx ) :
47 : 66 : XclImpRoot( rStrm.GetRoot() ),
48 : : mpScData( 0 ),
49 : : mcBuiltIn( EXC_BUILTIN_UNKNOWN ),
50 : : mnScTab( SCTAB_MAX ),
51 : : meNameType( RT_NAME ),
52 : : mnXclTab( EXC_NAME_GLOBAL ),
53 : : mnNameIndex( nXclNameIdx ),
54 : : mbVBName( false ),
55 : : mbMacro( false ),
56 [ + - ][ + - ]: 66 : mpTokensData( NULL )
57 : : {
58 [ + - ]: 66 : ExcelToSc& rFmlaConv = GetOldFmlaConverter();
59 : :
60 : : // 1) *** read data from stream *** ---------------------------------------
61 : :
62 : 66 : sal_uInt16 nFlags = 0, nFmlaSize = 0, nExtSheet = EXC_NAME_GLOBAL;
63 : 66 : sal_uInt8 nNameLen = 0, nShortCut;
64 : :
65 [ - - + - ]: 66 : switch( GetBiff() )
66 : : {
67 : : case EXC_BIFF2:
68 : : {
69 : : sal_uInt8 nFlagsBiff2;
70 [ # # ]: 0 : rStrm >> nFlagsBiff2;
71 [ # # ]: 0 : rStrm.Ignore( 1 );
72 [ # # ][ # # ]: 0 : rStrm >> nShortCut >> nNameLen;
73 [ # # ]: 0 : nFmlaSize = rStrm.ReaduInt8();
74 : 0 : ::set_flag( nFlags, EXC_NAME_FUNC, ::get_flag( nFlagsBiff2, EXC_NAME2_FUNC ) );
75 : : }
76 : 0 : break;
77 : :
78 : : case EXC_BIFF3:
79 : : case EXC_BIFF4:
80 : : {
81 [ # # ][ # # ]: 0 : rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize;
[ # # ][ # # ]
82 : : }
83 : 0 : break;
84 : :
85 : : case EXC_BIFF5:
86 : : case EXC_BIFF8:
87 : : {
88 [ + - ][ + - ]: 66 : rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize >> nExtSheet >> mnXclTab;
[ + - ][ + - ]
[ + - ][ + - ]
89 [ + - ]: 66 : rStrm.Ignore( 4 );
90 : : }
91 : 66 : break;
92 : :
93 : : default: DBG_ERROR_BIFF();
94 : : }
95 : :
96 [ - + ]: 66 : if( GetBiff() <= EXC_BIFF5 )
97 [ # # ][ # # ]: 0 : maXclName = rStrm.ReadRawByteString( nNameLen );
[ # # ]
98 : : else
99 [ + - ][ + - ]: 66 : maXclName = rStrm.ReadUniString( nNameLen );
[ + - ]
100 : :
101 : : // 2) *** convert sheet index and name *** --------------------------------
102 : :
103 : : // functions and VBA
104 : 66 : bool bFunction = ::get_flag( nFlags, EXC_NAME_FUNC );
105 : 66 : mbVBName = ::get_flag( nFlags, EXC_NAME_VB );
106 : 66 : mbMacro = ::get_flag( nFlags, EXC_NAME_PROC );
107 : :
108 : : // get built-in name, or convert characters invalid in Calc
109 : 66 : bool bBuiltIn = ::get_flag( nFlags, EXC_NAME_BUILTIN );
110 : :
111 : : // special case for BIFF5 filter range - name appears as plain text without built-in flag
112 [ # # ][ # # ]: 66 : if( (GetBiff() == EXC_BIFF5) && (maXclName.Equals(XclTools::GetXclBuiltInDefName(EXC_BUILTIN_FILTERDATABASE))) )
[ # # ][ # # ]
[ - + ][ # # ]
[ - + ][ - +
# # # # ]
[ - + ]
113 : : {
114 : 0 : bBuiltIn = true;
115 [ # # ]: 0 : maXclName.Assign( EXC_BUILTIN_FILTERDATABASE );
116 : : }
117 : :
118 : : // convert Excel name to Calc name
119 [ - + ]: 66 : if( mbVBName )
120 : : {
121 : : // VB macro name
122 [ # # ]: 0 : maScName = maXclName;
123 : : }
124 [ + + ]: 66 : else if( bBuiltIn )
125 : : {
126 : : // built-in name
127 [ + - ]: 18 : if( maXclName.Len() )
128 : 18 : mcBuiltIn = maXclName.GetChar( 0 );
129 [ - + ]: 18 : if( mcBuiltIn == '?' ) // NUL character is imported as '?'
130 : 0 : mcBuiltIn = '\0';
131 [ + - ][ + - ]: 18 : maScName = XclTools::GetBuiltInDefName( mcBuiltIn );
132 : : }
133 : : else
134 : : {
135 : : // any other name
136 [ + - ]: 48 : maScName = maXclName;
137 [ + - ]: 48 : ScfTools::ConvertToScDefinedName( maScName );
138 : : }
139 : :
140 : : // add index for local names
141 [ + + ]: 66 : if( mnXclTab != EXC_NAME_GLOBAL )
142 : : {
143 [ + - ]: 30 : sal_uInt16 nUsedTab = (GetBiff() == EXC_BIFF8) ? mnXclTab : nExtSheet;
144 : : // TODO: may not work for BIFF5, handle skipped sheets (all BIFF)
145 : 30 : mnScTab = static_cast< SCTAB >( nUsedTab - 1 );
146 : : }
147 : :
148 : : // 3) *** convert the name definition formula *** -------------------------
149 : :
150 [ + - ]: 66 : rFmlaConv.Reset();
151 : 66 : const ScTokenArray* pTokArr = 0; // pointer to token array, owned by rFmlaConv
152 : :
153 [ - + ]: 66 : if( ::get_flag( nFlags, EXC_NAME_BIG ) )
154 : : {
155 : : // special, unsupported name
156 [ # # ]: 0 : rFmlaConv.GetDummy( pTokArr );
157 : : }
158 [ + + ]: 66 : else if( bBuiltIn )
159 : : {
160 [ + - ]: 18 : SCsTAB const nLocalTab = (mnXclTab == EXC_NAME_GLOBAL) ? SCTAB_MAX : (mnXclTab - 1);
161 : :
162 : : // --- print ranges or title ranges ---
163 [ + - ]: 18 : rStrm.PushPosition();
164 [ - - + ]: 18 : switch( mcBuiltIn )
165 : : {
166 : : case EXC_BUILTIN_PRINTAREA:
167 [ # # ][ # # ]: 0 : if( rFmlaConv.Convert( GetPrintAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvOK )
[ # # ]
168 : 0 : meNameType |= RT_PRINTAREA;
169 : 0 : break;
170 : : case EXC_BUILTIN_PRINTTITLES:
171 [ # # ][ # # ]: 0 : if( rFmlaConv.Convert( GetTitleAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvOK )
[ # # ]
172 : 0 : meNameType |= RT_COLHEADER | RT_ROWHEADER;
173 : 0 : break;
174 : : }
175 [ + - ]: 18 : rStrm.PopPosition();
176 : :
177 : : // --- name formula ---
178 : : // JEG : double check this. It is clearly false for normal names
179 : : // but some of the builtins (sheettitle?) might be able to handle arrays
180 [ + - ]: 18 : rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize, false, FT_RangeName );
181 : :
182 : : // --- auto or advanced filter ---
183 [ + - ][ + - ]: 18 : if( (GetBiff() == EXC_BIFF8) && pTokArr && bBuiltIn )
[ + - ][ + - ]
184 : : {
185 : 18 : ScRange aRange;
186 [ + - ][ + - ]: 18 : if( pTokArr->IsReference( aRange ) )
187 : : {
188 [ + - - - ]: 18 : switch( mcBuiltIn )
189 : : {
190 : : case EXC_BUILTIN_FILTERDATABASE:
191 [ + - ][ + - ]: 18 : GetFilterManager().Insert( &GetOldRoot(), aRange);
[ + - ]
192 : 18 : break;
193 : : case EXC_BUILTIN_CRITERIA:
194 [ # # ][ # # ]: 0 : GetFilterManager().AddAdvancedRange( aRange );
195 : 0 : meNameType |= RT_CRITERIA;
196 : 0 : break;
197 : : case EXC_BUILTIN_EXTRACT:
198 [ # # ][ # # ]: 0 : if( pTokArr->IsValidReference( aRange ) )
199 [ # # ][ # # ]: 0 : GetFilterManager().AddExtractPos( aRange );
200 : 18 : break;
201 : : }
202 : : }
203 : : }
204 : : }
205 [ + - ]: 48 : else if( nFmlaSize > 0 )
206 : : {
207 : : // Regular defined name. We need to convert the tokens after all the
208 : : // names have been registered (for cross-referenced names).
209 [ + - ][ + - ]: 48 : mpTokensData.reset(new TokenStrmData(rStrm));
[ + - ]
210 : 48 : mpTokensData->mnStrmPos = rStrm.GetSvStreamPos();
211 [ + - ]: 48 : rStrm.StorePosition(mpTokensData->maStrmPos);
212 : 48 : mpTokensData->mnStrmSize = nFmlaSize;
213 : : }
214 : :
215 [ + + ][ + - ]: 66 : if (pTokArr && !bFunction && !mbVBName)
[ + - ]
216 [ + - ]: 18 : InsertName(pTokArr);
217 : 66 : }
218 : :
219 : 45 : bool XclImpName::IsMacro() const
220 : : {
221 : 45 : return mbMacro;
222 : : }
223 : :
224 : 66 : void XclImpName::ConvertTokens()
225 : : {
226 [ + + ]: 66 : if (!mpTokensData)
227 : 66 : return;
228 : :
229 [ + - ]: 48 : ExcelToSc& rFmlaConv = GetOldFmlaConverter();
230 [ + - ]: 48 : rFmlaConv.Reset();
231 : 48 : const ScTokenArray* pArray = NULL;
232 : :
233 [ + - ]: 48 : XclImpStreamPos aOldPos;
234 : 48 : XclImpStream& rStrm = mpTokensData->mrStrm;
235 [ + - ]: 48 : rStrm.StorePosition(aOldPos);
236 [ + - ]: 48 : rStrm.RestorePosition(mpTokensData->maStrmPos);
237 [ + - ]: 48 : rFmlaConv.Convert(pArray, rStrm, mpTokensData->mnStrmSize, true, FT_RangeName);
238 [ + - ]: 48 : rStrm.RestorePosition(aOldPos);
239 : :
240 [ + - ]: 48 : if (pArray)
241 [ + - ]: 48 : InsertName(pArray);
242 : :
243 [ + - ]: 66 : mpTokensData.reset();
244 : : }
245 : :
246 : 66 : void XclImpName::InsertName(const ScTokenArray* pArray)
247 : : {
248 : : // create the Calc name data
249 [ + - ][ + - ]: 66 : ScRangeData* pData = new ScRangeData(GetDocPtr(), maScName, *pArray, ScAddress(), meNameType);
250 : 66 : pData->GuessPosition(); // calculate base position for relative refs
251 : 66 : pData->SetIndex( mnNameIndex ); // used as unique identifier in formulas
252 [ + + ]: 66 : if (mnXclTab == EXC_NAME_GLOBAL)
253 : : {
254 [ - + ]: 36 : if (!GetDoc().GetRangeName()->insert(pData))
255 : 0 : pData = NULL;
256 : : }
257 : : else
258 : : {
259 : 30 : ScRangeName* pLocalNames = GetDoc().GetRangeName(mnScTab);
260 [ + - ]: 30 : if (pLocalNames)
261 : : {
262 [ - + ]: 30 : if (!pLocalNames->insert(pData))
263 : 0 : pData = NULL;
264 : : }
265 : :
266 [ + - ][ + - ]: 30 : if (GetBiff() == EXC_BIFF8 && pData)
[ + - ]
267 : : {
268 : 30 : ScRange aRange;
269 : : // discard deleted ranges ( for the moment at least )
270 [ + - ][ + - ]: 30 : if ( pData->IsValidReference( aRange ) )
271 : : {
272 [ + - ][ + - ]: 30 : GetExtDocOptions().GetOrCreateTabSettings( mnXclTab );
273 : : }
274 : : }
275 : : }
276 [ + - ]: 66 : if (pData)
277 : 66 : mpScData = pData; // cache for later use
278 : 66 : }
279 : :
280 : : // ----------------------------------------------------------------------------
281 : :
282 : 55 : XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) :
283 [ + - ]: 55 : XclImpRoot( rRoot )
284 : : {
285 : 55 : }
286 : :
287 : 66 : void XclImpNameManager::ReadName( XclImpStream& rStrm )
288 : : {
289 : 66 : sal_uLong nCount = maNameList.size();
290 [ + - ]: 66 : if( nCount < 0xFFFF )
291 [ + - ]: 66 : maNameList.push_back( new XclImpName( rStrm, static_cast< sal_uInt16 >( nCount + 1 ) ) );
292 : 66 : }
293 : :
294 : 0 : const XclImpName* XclImpNameManager::FindName( const String& rXclName, SCTAB nScTab ) const
295 : : {
296 : 0 : const XclImpName* pGlobalName = 0; // a found global name
297 : 0 : const XclImpName* pLocalName = 0; // a found local name
298 [ # # ][ # # ]: 0 : for( XclImpNameList::const_iterator itName = maNameList.begin(); itName != maNameList.end() && !pLocalName; ++itName )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
299 : : {
300 [ # # ][ # # ]: 0 : if( itName->GetXclName() == rXclName )
[ # # ]
301 : : {
302 [ # # ][ # # ]: 0 : if( itName->GetScTab() == nScTab )
303 [ # # ]: 0 : pLocalName = &(*itName);
304 [ # # ][ # # ]: 0 : else if( itName->IsGlobal() )
305 [ # # ]: 0 : pGlobalName = &(*itName);
306 : : }
307 : : }
308 [ # # ]: 0 : return pLocalName ? pLocalName : pGlobalName;
309 : : }
310 : :
311 : 48 : const XclImpName* XclImpNameManager::GetName( sal_uInt16 nXclNameIdx ) const
312 : : {
313 : : OSL_ENSURE( nXclNameIdx > 0, "XclImpNameManager::GetName - index must be >0" );
314 [ + + ]: 48 : return ( nXclNameIdx > maNameList.size() ) ? NULL : &(maNameList.at( nXclNameIdx - 1 ));
315 : : }
316 : :
317 : 52 : void XclImpNameManager::ConvertAllTokens()
318 : : {
319 [ + - ][ + - ]: 52 : XclImpNameList::iterator it = maNameList.begin(), itEnd = maNameList.end();
320 [ + - ][ + - ]: 118 : for (; it != itEnd; ++it)
[ + + ]
321 [ + - ][ + - ]: 66 : it->ConvertTokens();
322 [ + - ][ + - ]: 76 : }
323 : :
324 : : // ============================================================================
325 : :
326 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|