fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / filter / excel / xename.cxx
blob4466a1e12584b3316dbb69615344cea35cd4a9ad
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "xename.hxx"
22 #include <map>
24 #include "globstr.hrc"
25 #include "document.hxx"
26 #include "rangenam.hxx"
27 #include "dbdata.hxx"
28 #include "xehelper.hxx"
29 #include "xelink.hxx"
30 #include "globalnames.hxx"
31 #include "excrecds.hxx"
33 #include <formula/grammar.hxx>
35 using namespace ::oox;
37 // *** Helper classes ***
39 /** Represents an internal defined name, supports writing it to a NAME record. */
40 class XclExpName : public XclExpRecord, protected XclExpRoot
42 public:
43 /** Creates a standard defined name. */
44 explicit XclExpName( const XclExpRoot& rRoot, const OUString& rName );
45 /** Creates a built-in defined name. */
46 explicit XclExpName( const XclExpRoot& rRoot, sal_Unicode cBuiltIn );
48 /** Sets a token array containing the definition of this name. */
49 void SetTokenArray( XclTokenArrayRef xTokArr );
50 /** Changes this defined name to be local on the specified Calc sheet. */
51 void SetLocalTab( SCTAB nScTab );
52 /** Hides or unhides the defined name. */
53 void SetHidden( bool bHidden = true );
54 /** Changes this name to be the call to a VB macro function or procedure.
55 @param bVBasic true = Visual Basic macro, false = Sheet macro.
56 @param bFunc true = Macro function; false = Macro procedure. */
57 void SetMacroCall( bool bVBasic, bool bFunc );
59 /** Sets the name's symbol value
60 @param sValue the name's symbolic value */
61 void SetSymbol( const OUString& rValue );
63 /** Returns the original name (title) of this defined name. */
64 inline const OUString& GetOrigName() const { return maOrigName; }
65 /** Returns the Excel built-in name index of this defined name.
66 @return The built-in name index or EXC_BUILTIN_UNKNOWN for user-defined names. */
67 inline sal_Unicode GetBuiltInName() const { return mcBuiltIn; }
69 /** Returns the token array for this defined name. */
70 inline XclTokenArrayRef GetTokenArray() const { return mxTokArr; }
72 /** Returns true, if this is a document-global defined name. */
73 inline bool IsGlobal() const { return mnXclTab == EXC_NAME_GLOBAL; }
74 /** Returns the Calc sheet of a local defined name. */
75 inline SCTAB GetScTab() const { return mnScTab; }
77 /** Returns true, if this defined name is volatile. */
78 bool IsVolatile() const;
79 /** Returns true, if this defined name describes a macro call.
80 @param bFunc true = Macro function; false = Macro procedure. */
81 bool IsMacroCall( bool bVBasic, bool bFunc ) const;
83 /** Writes the entire NAME record to the passed stream. */
84 virtual void Save( XclExpStream& rStrm ) SAL_OVERRIDE;
86 virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
88 private:
89 /** Writes the body of the NAME record to the passed stream. */
90 virtual void WriteBody( XclExpStream& rStrm ) SAL_OVERRIDE;
92 private:
93 OUString maOrigName; /// The original user-defined name.
94 OUString msSymbol; /// The value of the symbol
95 XclExpStringRef mxName; /// The name as Excel string object.
96 XclTokenArrayRef mxTokArr; /// The definition of the defined name.
97 sal_Unicode mcBuiltIn; /// The built-in index for built-in names.
98 SCTAB mnScTab; /// The Calc sheet index for local names.
99 sal_uInt16 mnFlags; /// Additional flags for this defined name.
100 sal_uInt16 mnExtSheet; /// The 1-based index to a global EXTERNSHEET record.
101 sal_uInt16 mnXclTab; /// The 1-based Excel sheet index for local names.
104 class ScRangeData;
105 class ScDBData;
107 /** Implementation class of the name manager. */
108 class XclExpNameManagerImpl : protected XclExpRoot
110 public:
111 explicit XclExpNameManagerImpl( const XclExpRoot& rRoot );
113 /** Creates NAME records for built-in and user defined names. */
114 void Initialize();
116 /** Inserts the Calc name with the passed index and returns the Excel NAME index. */
117 sal_uInt16 InsertName( SCTAB nTab, sal_uInt16 nScNameIdx );
119 /** Inserts a new built-in defined name. */
120 sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab, const ScRangeList& aRangeList );
121 sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, const ScRange& aRange );
122 /** Inserts a new defined name. Sets another unused name, if rName already exists. */
123 sal_uInt16 InsertUniqueName( const OUString& rName, XclTokenArrayRef xTokArr, SCTAB nScTab );
124 /** Returns index of an existing name, or creates a name without definition. */
125 sal_uInt16 InsertRawName( const OUString& rName );
126 /** Searches or inserts a defined name describing a macro name.
127 @param bVBasic true = Visual Basic macro; false = Sheet macro.
128 @param bFunc true = Macro function; false = Macro procedure. */
129 sal_uInt16 InsertMacroCall( const OUString& rMacroName, bool bVBasic, bool bFunc, bool bHidden );
131 /** Returns the NAME record at the specified position or 0 on error. */
132 const XclExpName* GetName( sal_uInt16 nNameIdx ) const;
134 /** Writes the entire list of NAME records.
135 @descr In BIFF7 and lower, writes the entire global link table, which
136 consists of an EXTERNCOUNT record, several EXTERNSHEET records, and
137 the list of NAME records. */
138 void Save( XclExpStream& rStrm );
140 void SaveXml( XclExpXmlStream& rStrm );
142 private:
143 typedef XclExpRecordList< XclExpName > XclExpNameList;
144 typedef XclExpNameList::RecordRefType XclExpNameRef;
146 typedef ::std::map< ::std::pair<SCTAB, sal_uInt16>, sal_uInt16> NamedExpIndexMap;
148 private:
150 * @param nTab 0-based table index, or SCTAB_GLOBAL for global names.
151 * @param nScIdx calc's name index.
153 * @return excel's name index.
155 sal_uInt16 FindNamedExpIndex( SCTAB nTab, sal_uInt16 nScIdx );
157 /** Returns the index of an existing built-in NAME record with the passed definition, otherwise 0. */
158 sal_uInt16 FindBuiltInNameIdx( const OUString& rName,
159 const XclTokenArray& rTokArr, bool bDBRange ) const;
160 /** Returns an unused name for the passed name. */
161 OUString GetUnusedName( const OUString& rName ) const;
163 /** Appends a new NAME record to the record list.
164 @return The 1-based NAME record index used elsewhere in the Excel file. */
165 sal_uInt16 Append( XclExpNameRef xName );
166 /** Creates a new NAME record for the passed user-defined name.
167 @return The 1-based NAME record index used elsewhere in the Excel file. */
168 sal_uInt16 CreateName( SCTAB nTab, const ScRangeData& rRangeData );
170 /** Creates NAME records for all built-in names in the document. */
171 void CreateBuiltInNames();
172 /** Creates NAME records for all user-defined names in the document. */
173 void CreateUserNames();
175 private:
177 * Maps Calc's named range to Excel's NAME records. Global names use
178 * -1 as their table index, whereas sheet-local names have 0-based table
179 * index.
181 NamedExpIndexMap maNamedExpMap;
182 XclExpNameList maNameList; /// List of NAME records.
183 size_t mnFirstUserIdx; /// List index of first user-defined NAME record.
186 // *** Implementation ***
188 XclExpName::XclExpName( const XclExpRoot& rRoot, const OUString& rName ) :
189 XclExpRecord( EXC_ID_NAME ),
190 XclExpRoot( rRoot ),
191 maOrigName( rName ),
192 mxName( XclExpStringHelper::CreateString( rRoot, rName, EXC_STR_8BITLENGTH ) ),
193 mcBuiltIn( EXC_BUILTIN_UNKNOWN ),
194 mnScTab( SCTAB_GLOBAL ),
195 mnFlags( EXC_NAME_DEFAULT ),
196 mnExtSheet( EXC_NAME_GLOBAL ),
197 mnXclTab( EXC_NAME_GLOBAL )
201 XclExpName::XclExpName( const XclExpRoot& rRoot, sal_Unicode cBuiltIn ) :
202 XclExpRecord( EXC_ID_NAME ),
203 XclExpRoot( rRoot ),
204 mcBuiltIn( cBuiltIn ),
205 mnScTab( SCTAB_GLOBAL ),
206 mnFlags( EXC_NAME_DEFAULT ),
207 mnExtSheet( EXC_NAME_GLOBAL ),
208 mnXclTab( EXC_NAME_GLOBAL )
210 // filter source range is hidden in Excel
211 if( cBuiltIn == EXC_BUILTIN_FILTERDATABASE )
212 SetHidden();
214 // special case for BIFF5/7 filter source range - name appears as plain text without built-in flag
215 if( (GetBiff() <= EXC_BIFF5) && (cBuiltIn == EXC_BUILTIN_FILTERDATABASE) )
217 OUString aName( XclTools::GetXclBuiltInDefName( EXC_BUILTIN_FILTERDATABASE ) );
218 mxName = XclExpStringHelper::CreateString( rRoot, aName, EXC_STR_8BITLENGTH );
219 maOrigName = XclTools::GetXclBuiltInDefName( cBuiltIn );
221 else
223 maOrigName = XclTools::GetBuiltInDefNameXml( cBuiltIn ) ;
224 mxName = XclExpStringHelper::CreateString( rRoot, cBuiltIn, EXC_STR_8BITLENGTH );
225 ::set_flag( mnFlags, EXC_NAME_BUILTIN );
229 void XclExpName::SetTokenArray( XclTokenArrayRef xTokArr )
231 mxTokArr = xTokArr;
234 void XclExpName::SetLocalTab( SCTAB nScTab )
236 OSL_ENSURE( GetTabInfo().IsExportTab( nScTab ), "XclExpName::SetLocalTab - invalid sheet index" );
237 if( GetTabInfo().IsExportTab( nScTab ) )
239 mnScTab = nScTab;
240 GetGlobalLinkManager().FindExtSheet( mnExtSheet, mnXclTab, nScTab );
242 // special handling for NAME record
243 switch( GetBiff() )
245 case EXC_BIFF5: // EXTERNSHEET index is positive in NAME record
246 mnExtSheet = ~mnExtSheet + 1;
247 break;
248 case EXC_BIFF8: // EXTERNSHEET index not used, but must be created in link table
249 mnExtSheet = 0;
250 break;
251 default: DBG_ERROR_BIFF();
254 // Excel sheet index is 1-based
255 ++mnXclTab;
259 void XclExpName::SetHidden( bool bHidden )
261 ::set_flag( mnFlags, EXC_NAME_HIDDEN, bHidden );
264 void XclExpName::SetMacroCall( bool bVBasic, bool bFunc )
266 ::set_flag( mnFlags, EXC_NAME_PROC );
267 ::set_flag( mnFlags, EXC_NAME_VB, bVBasic );
268 ::set_flag( mnFlags, EXC_NAME_FUNC, bFunc );
271 void XclExpName::SetSymbol( const OUString& rSymbol )
273 msSymbol = rSymbol;
276 bool XclExpName::IsVolatile() const
278 return mxTokArr && mxTokArr->IsVolatile();
281 bool XclExpName::IsMacroCall( bool bVBasic, bool bFunc ) const
283 return
284 (::get_flag( mnFlags, EXC_NAME_VB ) == bVBasic) &&
285 (::get_flag( mnFlags, EXC_NAME_FUNC ) == bFunc);
288 void XclExpName::Save( XclExpStream& rStrm )
290 OSL_ENSURE( mxName && (mxName->Len() > 0), "XclExpName::Save - missing name" );
291 OSL_ENSURE( !(IsGlobal() && ::get_flag( mnFlags, EXC_NAME_BUILTIN )), "XclExpName::Save - global built-in name" );
292 SetRecSize( 11 + mxName->GetSize() + (mxTokArr ? mxTokArr->GetSize() : 2) );
293 XclExpRecord::Save( rStrm );
296 void XclExpName::SaveXml( XclExpXmlStream& rStrm )
298 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
299 rWorkbook->startElement( XML_definedName,
300 // OOXTODO: XML_comment, "",
301 // OOXTODO: XML_customMenu, "",
302 // OOXTODO: XML_description, "",
303 XML_function, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_VB ) ),
304 // OOXTODO: XML_functionGroupId, "",
305 // OOXTODO: XML_help, "",
306 XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_HIDDEN ) ),
307 XML_localSheetId, mnScTab == SCTAB_GLOBAL ? NULL : OString::number( mnScTab ).getStr(),
308 XML_name, XclXmlUtils::ToOString( maOrigName ).getStr(),
309 // OOXTODO: XML_publishToServer, "",
310 // OOXTODO: XML_shortcutKey, "",
311 // OOXTODO: XML_statusBar, "",
312 XML_vbProcedure, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_VB ) ),
313 // OOXTODO: XML_workbookParameter, "",
314 // OOXTODO: XML_xlm, "",
315 FSEND );
316 rWorkbook->writeEscaped( msSymbol );
317 rWorkbook->endElement( XML_definedName );
320 void XclExpName::WriteBody( XclExpStream& rStrm )
322 sal_uInt16 nFmlaSize = mxTokArr ? mxTokArr->GetSize() : 0;
324 rStrm << mnFlags // flags
325 << sal_uInt8( 0 ); // keyboard shortcut
326 mxName->WriteLenField( rStrm ); // length of name
327 rStrm << nFmlaSize // size of token array
328 << mnExtSheet // BIFF5/7: EXTSHEET index, BIFF8: not used
329 << mnXclTab // 1-based sheet index for local names
330 << sal_uInt32( 0 ); // length of menu/descr/help/status text
331 mxName->WriteFlagField( rStrm ); // BIFF8 flag field (no-op in <=BIFF7)
332 mxName->WriteBuffer( rStrm ); // character array of the name
333 if( mxTokArr )
334 mxTokArr->WriteArray( rStrm ); // token array without size
337 XclExpNameManagerImpl::XclExpNameManagerImpl( const XclExpRoot& rRoot ) :
338 XclExpRoot( rRoot ),
339 mnFirstUserIdx( 0 )
343 void XclExpNameManagerImpl::Initialize()
345 CreateBuiltInNames();
346 mnFirstUserIdx = maNameList.GetSize();
347 CreateUserNames();
350 sal_uInt16 XclExpNameManagerImpl::InsertName( SCTAB nTab, sal_uInt16 nScNameIdx )
352 sal_uInt16 nNameIdx = FindNamedExpIndex( nTab, nScNameIdx );
353 if (nNameIdx)
354 return nNameIdx;
356 const ScRangeData* pData = NULL;
357 ScRangeName* pRN = (nTab == SCTAB_GLOBAL) ? GetDoc().GetRangeName() : GetDoc().GetRangeName(nTab);
358 if (pRN)
359 pData = pRN->findByIndex(nScNameIdx);
361 if (pData)
362 nNameIdx = CreateName(nTab, *pData);
364 return nNameIdx;
367 sal_uInt16 XclExpNameManagerImpl::InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, const ScRange& aRange )
369 XclExpNameRef xName( new XclExpName( GetRoot(), cBuiltIn ) );
370 xName->SetTokenArray( xTokArr );
371 xName->SetLocalTab( aRange.aStart.Tab() );
372 OUString sSymbol(aRange.Format(SCR_ABS_3D, GetDocPtr(), ScAddress::Details( ::formula::FormulaGrammar::CONV_XL_A1)));
373 xName->SetSymbol( sSymbol );
374 return Append( xName );
377 sal_uInt16 XclExpNameManagerImpl::InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab, const ScRangeList& rRangeList )
379 XclExpNameRef xName( new XclExpName( GetRoot(), cBuiltIn ) );
380 xName->SetTokenArray( xTokArr );
381 xName->SetLocalTab( nScTab );
382 OUString sSymbol;
383 rRangeList.Format( sSymbol, SCR_ABS_3D, GetDocPtr(), ::formula::FormulaGrammar::CONV_XL_A1 );
384 xName->SetSymbol( sSymbol );
385 return Append( xName );
388 sal_uInt16 XclExpNameManagerImpl::InsertUniqueName(
389 const OUString& rName, XclTokenArrayRef xTokArr, SCTAB nScTab )
391 OSL_ENSURE( !rName.isEmpty(), "XclExpNameManagerImpl::InsertUniqueName - empty name" );
392 XclExpNameRef xName( new XclExpName( GetRoot(), GetUnusedName( rName ) ) );
393 xName->SetTokenArray( xTokArr );
394 xName->SetLocalTab( nScTab );
395 return Append( xName );
398 sal_uInt16 XclExpNameManagerImpl::InsertRawName( const OUString& rName )
400 // empty name? may occur in broken external Calc tokens
401 if( rName.isEmpty() )
402 return 0;
404 // try to find an existing NAME record, regardless of its type
405 for( size_t nListIdx = mnFirstUserIdx, nListSize = maNameList.GetSize(); nListIdx < nListSize; ++nListIdx )
407 XclExpNameRef xName = maNameList.GetRecord( nListIdx );
408 if( xName->IsGlobal() && (xName->GetOrigName() == rName) )
409 return static_cast< sal_uInt16 >( nListIdx + 1 );
412 // create a new NAME record
413 XclExpNameRef xName( new XclExpName( GetRoot(), rName ) );
414 return Append( xName );
417 sal_uInt16 XclExpNameManagerImpl::InsertMacroCall( const OUString& rMacroName, bool bVBasic, bool bFunc, bool bHidden )
419 // empty name? may occur in broken external Calc tokens
420 if( rMacroName.isEmpty() )
421 return 0;
423 // try to find an existing NAME record
424 for( size_t nListIdx = mnFirstUserIdx, nListSize = maNameList.GetSize(); nListIdx < nListSize; ++nListIdx )
426 XclExpNameRef xName = maNameList.GetRecord( nListIdx );
427 if( xName->IsMacroCall( bVBasic, bFunc ) && (xName->GetOrigName() == rMacroName) )
428 return static_cast< sal_uInt16 >( nListIdx + 1 );
431 // create a new NAME record
432 XclExpNameRef xName( new XclExpName( GetRoot(), rMacroName ) );
433 xName->SetMacroCall( bVBasic, bFunc );
434 xName->SetHidden( bHidden );
436 // for sheet macros, add a #NAME! error
437 if( !bVBasic )
438 xName->SetTokenArray( GetFormulaCompiler().CreateErrorFormula( EXC_ERR_NAME ) );
440 return Append( xName );
443 const XclExpName* XclExpNameManagerImpl::GetName( sal_uInt16 nNameIdx ) const
445 OSL_ENSURE( maNameList.HasRecord( nNameIdx - 1 ), "XclExpNameManagerImpl::GetName - wrong record index" );
446 return maNameList.GetRecord( nNameIdx - 1 ).get();
449 void XclExpNameManagerImpl::Save( XclExpStream& rStrm )
451 maNameList.Save( rStrm );
454 void XclExpNameManagerImpl::SaveXml( XclExpXmlStream& rStrm )
456 if( maNameList.IsEmpty() )
457 return;
458 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
459 rWorkbook->startElement( XML_definedNames, FSEND );
460 maNameList.SaveXml( rStrm );
461 rWorkbook->endElement( XML_definedNames );
464 // private --------------------------------------------------------------------
466 sal_uInt16 XclExpNameManagerImpl::FindNamedExpIndex( SCTAB nTab, sal_uInt16 nScIdx )
468 NamedExpIndexMap::key_type key = NamedExpIndexMap::key_type(nTab, nScIdx);
469 NamedExpIndexMap::const_iterator itr = maNamedExpMap.find(key);
470 return (itr == maNamedExpMap.end()) ? 0 : itr->second;
473 sal_uInt16 XclExpNameManagerImpl::FindBuiltInNameIdx(
474 const OUString& rName, const XclTokenArray& rTokArr, bool bDBRange ) const
476 /* Get built-in index from the name. Special case: the database range
477 'unnamed' will be mapped to Excel's built-in '_FilterDatabase' name. */
478 sal_Unicode cBuiltIn = (bDBRange && (rName == STR_DB_LOCAL_NONAME)) ?
479 EXC_BUILTIN_FILTERDATABASE : XclTools::GetBuiltInDefNameIndex( rName );
481 if( cBuiltIn < EXC_BUILTIN_UNKNOWN )
483 // try to find the record in existing built-in NAME record list
484 for( size_t nPos = 0; nPos < mnFirstUserIdx; ++nPos )
486 XclExpNameRef xName = maNameList.GetRecord( nPos );
487 if( xName->GetBuiltInName() == cBuiltIn )
489 XclTokenArrayRef xTokArr = xName->GetTokenArray();
490 if( xTokArr && (*xTokArr == rTokArr) )
491 return static_cast< sal_uInt16 >( nPos + 1 );
495 return 0;
498 OUString XclExpNameManagerImpl::GetUnusedName( const OUString& rName ) const
500 OUString aNewName( rName );
501 sal_Int32 nAppIdx = 0;
502 bool bExist = true;
503 while( bExist )
505 // search the list of user-defined names
506 bExist = false;
507 for( size_t nPos = mnFirstUserIdx, nSize = maNameList.GetSize(); !bExist && (nPos < nSize); ++nPos )
509 XclExpNameRef xName = maNameList.GetRecord( nPos );
510 bExist = xName->GetOrigName() == aNewName;
511 // name exists -> create a new name "<originalname>_<counter>"
512 if( bExist )
513 aNewName = rName + "_" + OUString::number( ++nAppIdx );
516 return aNewName;
519 sal_uInt16 XclExpNameManagerImpl::Append( XclExpNameRef xName )
521 if( maNameList.GetSize() == 0xFFFF )
522 return 0;
523 maNameList.AppendRecord( xName );
524 return static_cast< sal_uInt16 >( maNameList.GetSize() ); // 1-based
527 sal_uInt16 XclExpNameManagerImpl::CreateName( SCTAB nTab, const ScRangeData& rRangeData )
529 const OUString& rName = rRangeData.GetName();
531 /* #i38821# recursive names: first insert the (empty) name object,
532 otherwise a recursive call of this function from the formula compiler
533 with the same defined name will not find it and will create it again. */
534 size_t nOldListSize = maNameList.GetSize();
535 XclExpNameRef xName( new XclExpName( GetRoot(), rName ) );
536 if (nTab != SCTAB_GLOBAL)
537 xName->SetLocalTab(nTab);
538 sal_uInt16 nNameIdx = Append( xName );
539 // store the index of the NAME record in the lookup map
540 NamedExpIndexMap::key_type key = NamedExpIndexMap::key_type(nTab, rRangeData.GetIndex());
541 maNamedExpMap[key] = nNameIdx;
543 /* Create the definition formula.
544 This may cause recursive creation of other defined names. */
545 if( const ScTokenArray* pScTokArr = const_cast< ScRangeData& >( rRangeData ).GetCode() )
547 XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, *pScTokArr );
548 xName->SetTokenArray( xTokArr );
550 OUString sSymbol;
551 rRangeData.GetSymbol( sSymbol, ((GetOutput() == EXC_OUTPUT_BINARY) ?
552 formula::FormulaGrammar::GRAM_ENGLISH_XL_A1 : formula::FormulaGrammar::GRAM_OOXML));
553 xName->SetSymbol( sSymbol );
555 /* Try to replace by existing built-in name - complete token array is
556 needed for comparison, and due to the recursion problem above this
557 cannot be done earlier. If a built-in name is found, the created NAME
558 record for this name and all following records in the list must be
559 deleted, otherwise they may contain wrong name list indexes. */
560 sal_uInt16 nBuiltInIdx = FindBuiltInNameIdx( rName, *xTokArr, false );
561 if( nBuiltInIdx != 0 )
563 // delete the new NAME records
564 while( maNameList.GetSize() > nOldListSize )
565 maNameList.RemoveRecord( maNameList.GetSize() - 1 );
566 // use index of the found built-in NAME record
567 key = NamedExpIndexMap::key_type(nTab, rRangeData.GetIndex());
568 maNamedExpMap[key] = nNameIdx = nBuiltInIdx;
572 return nNameIdx;
575 void XclExpNameManagerImpl::CreateBuiltInNames()
577 ScDocument& rDoc = GetDoc();
578 XclExpTabInfo& rTabInfo = GetTabInfo();
580 /* #i2394# built-in defined names must be sorted by the name of the
581 containing sheet. Example: SheetA!Print_Range must be stored *before*
582 SheetB!Print_Range, regardless of the position of SheetA in the document! */
583 for( SCTAB nScTabIdx = 0, nScTabCount = rTabInfo.GetScTabCount(); nScTabIdx < nScTabCount; ++nScTabIdx )
585 // find real sheet index from the nScTabIdx counter
586 SCTAB nScTab = rTabInfo.GetRealScTab( nScTabIdx );
587 // create NAME records for all built-in names of this sheet
588 if( rTabInfo.IsExportTab( nScTab ) )
590 // *** 1) print ranges *** ----------------------------------------
592 if( rDoc.HasPrintRange() )
594 ScRangeList aRangeList;
595 for( sal_uInt16 nIdx = 0, nCount = rDoc.GetPrintRangeCount( nScTab ); nIdx < nCount; ++nIdx )
597 const ScRange* pPrintRange = rDoc.GetPrintRange( nScTab, nIdx );
598 if (!pPrintRange)
599 continue;
600 ScRange aRange( *pPrintRange );
601 // Calc document does not care about sheet index in print ranges
602 aRange.aStart.SetTab( nScTab );
603 aRange.aEnd.SetTab( nScTab );
604 aRange.Justify();
605 aRangeList.Append( aRange );
607 // create the NAME record (do not warn if ranges are shrunken)
608 GetAddressConverter().ValidateRangeList( aRangeList, false );
609 if( !aRangeList.empty() )
610 GetNameManager().InsertBuiltInName( EXC_BUILTIN_PRINTAREA, aRangeList );
613 // *** 2) print titles *** ----------------------------------------
615 ScRangeList aTitleList;
616 // repeated columns
617 if( const ScRange* pColRange = rDoc.GetRepeatColRange( nScTab ) )
618 aTitleList.Append( ScRange(
619 pColRange->aStart.Col(), 0, nScTab,
620 pColRange->aEnd.Col(), GetXclMaxPos().Row(), nScTab ) );
621 // repeated rows
622 if( const ScRange* pRowRange = rDoc.GetRepeatRowRange( nScTab ) )
623 aTitleList.Append( ScRange(
624 0, pRowRange->aStart.Row(), nScTab,
625 GetXclMaxPos().Col(), pRowRange->aEnd.Row(), nScTab ) );
626 // create the NAME record
627 GetAddressConverter().ValidateRangeList( aTitleList, false );
628 if( !aTitleList.empty() )
629 GetNameManager().InsertBuiltInName( EXC_BUILTIN_PRINTTITLES, aTitleList );
631 // *** 3) filter ranges *** ---------------------------------------
633 if( GetBiff() == EXC_BIFF8 )
634 GetFilterManager().InitTabFilter( nScTab );
639 void XclExpNameManagerImpl::CreateUserNames()
641 const ScRangeName& rNamedRanges = GetNamedRanges();
642 ScRangeName::const_iterator itr = rNamedRanges.begin(), itrEnd = rNamedRanges.end();
643 for (; itr != itrEnd; ++itr)
645 // skip definitions of shared formulas
646 if (!FindNamedExpIndex(SCTAB_GLOBAL, itr->second->GetIndex()))
647 CreateName(SCTAB_GLOBAL, *itr->second);
649 //look at every sheet for local range names
650 ScRangeName::TabNameCopyMap rLocalNames;
651 GetDoc().GetAllTabRangeNames(rLocalNames);
652 ScRangeName::TabNameCopyMap::iterator tabIt = rLocalNames.begin(), tabItEnd = rLocalNames.end();
653 for (; tabIt != tabItEnd; ++tabIt)
655 itr = tabIt->second->begin(), itrEnd = tabIt->second->end();
656 for (; itr != itrEnd; ++itr)
658 // skip definitions of shared formulas
659 if (!FindNamedExpIndex(tabIt->first, itr->second->GetIndex()))
660 CreateName(tabIt->first, *itr->second);
665 XclExpNameManager::XclExpNameManager( const XclExpRoot& rRoot ) :
666 XclExpRoot( rRoot ),
667 mxImpl( new XclExpNameManagerImpl( rRoot ) )
671 XclExpNameManager::~XclExpNameManager()
675 void XclExpNameManager::Initialize()
677 mxImpl->Initialize();
680 sal_uInt16 XclExpNameManager::InsertName( SCTAB nTab, sal_uInt16 nScNameIdx )
682 return mxImpl->InsertName( nTab, nScNameIdx );
685 sal_uInt16 XclExpNameManager::InsertBuiltInName( sal_Unicode cBuiltIn, const ScRange& rRange )
687 XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, rRange );
688 return mxImpl->InsertBuiltInName( cBuiltIn, xTokArr, rRange );
691 sal_uInt16 XclExpNameManager::InsertBuiltInName( sal_Unicode cBuiltIn, const ScRangeList& rRangeList )
693 sal_uInt16 nNameIdx = 0;
694 if( !rRangeList.empty() )
696 XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, rRangeList );
697 nNameIdx = mxImpl->InsertBuiltInName( cBuiltIn, xTokArr, rRangeList.front()->aStart.Tab(), rRangeList );
699 return nNameIdx;
702 sal_uInt16 XclExpNameManager::InsertUniqueName(
703 const OUString& rName, XclTokenArrayRef xTokArr, SCTAB nScTab )
705 return mxImpl->InsertUniqueName( rName, xTokArr, nScTab );
708 sal_uInt16 XclExpNameManager::InsertRawName( const OUString& rName )
710 return mxImpl->InsertRawName( rName );
713 sal_uInt16 XclExpNameManager::InsertMacroCall( const OUString& rMacroName, bool bVBasic, bool bFunc, bool bHidden )
715 return mxImpl->InsertMacroCall( rMacroName, bVBasic, bFunc, bHidden );
718 const OUString& XclExpNameManager::GetOrigName( sal_uInt16 nNameIdx ) const
720 const XclExpName* pName = mxImpl->GetName( nNameIdx );
721 return pName ? pName->GetOrigName() : EMPTY_OUSTRING;
724 SCTAB XclExpNameManager::GetScTab( sal_uInt16 nNameIdx ) const
726 const XclExpName* pName = mxImpl->GetName( nNameIdx );
727 return pName ? pName->GetScTab() : SCTAB_GLOBAL;
730 bool XclExpNameManager::IsVolatile( sal_uInt16 nNameIdx ) const
732 const XclExpName* pName = mxImpl->GetName( nNameIdx );
733 return pName && pName->IsVolatile();
736 void XclExpNameManager::Save( XclExpStream& rStrm )
738 mxImpl->Save( rStrm );
741 void XclExpNameManager::SaveXml( XclExpXmlStream& rStrm )
743 mxImpl->SaveXml( rStrm );
746 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */