LibreOffice Module sc (master) 1
xiname.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <xiname.hxx>
21#include <xlname.hxx>
22#include <rangenam.hxx>
23#include <xistream.hxx>
24#include <excform.hxx>
25#include <excimp8.hxx>
26#include <scextopt.hxx>
27#include <document.hxx>
28
29// *** Implementation ***
30
32 mrStrm(rStrm), mnStrmPos(0), mnStrmSize(0) {}
33
34XclImpName::XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx ) :
36 mpScData( nullptr ),
40 mnNameIndex( nXclNameIdx ),
41 mbVBName( false ),
42 mbMacro( false )
43{
44 ExcelToSc& rFmlaConv = GetOldFmlaConverter();
45
46 // 1) *** read data from stream *** ---------------------------------------
47
48 sal_uInt16 nFlags = 0, nFmlaSize = 0, nExtSheet = EXC_NAME_GLOBAL;
49 sal_uInt8 nNameLen = 0;
51
52 switch( GetBiff() )
53 {
54 case EXC_BIFF2:
55 {
56 sal_uInt8 nFlagsBiff2;
57 nFlagsBiff2 = rStrm.ReaduInt8();
58 rStrm.Ignore( 1 );
59 rStrm.Ignore( 1 ); //nShortCut
60 nNameLen = rStrm.ReaduInt8();
61 nFmlaSize = rStrm.ReaduInt8();
62 ::set_flag( nFlags, EXC_NAME_FUNC, ::get_flag( nFlagsBiff2, EXC_NAME2_FUNC ) );
63 }
64 break;
65
66 case EXC_BIFF3:
67 case EXC_BIFF4:
68 {
69 nFlags = rStrm.ReaduInt16();
70 rStrm.Ignore( 1 ); //nShortCut
71 nNameLen = rStrm.ReaduInt8();
72 nFmlaSize = rStrm.ReaduInt16();
73 }
74 break;
75
76 case EXC_BIFF5:
77 case EXC_BIFF8:
78 {
79 nFlags = rStrm.ReaduInt16();
80 rStrm.Ignore( 1 ); //nShortCut
81 nNameLen = rStrm.ReaduInt8();
82 nFmlaSize = rStrm.ReaduInt16();
83 nExtSheet = rStrm.ReaduInt16();
84 mnXclTab = rStrm.ReaduInt16();
85 rStrm.Ignore( 4 );
86 }
87 break;
88
89 default: DBG_ERROR_BIFF();
90 }
91
92 if( GetBiff() <= EXC_BIFF5 )
93 maXclName = rStrm.ReadRawByteString( nNameLen );
94 else
95 maXclName = rStrm.ReadUniString( nNameLen );
96
97 // 2) *** convert sheet index and name *** --------------------------------
98
99 // functions and VBA
100 bool bFunction = ::get_flag( nFlags, EXC_NAME_FUNC );
101 mbVBName = ::get_flag( nFlags, EXC_NAME_VB );
102 mbMacro = ::get_flag( nFlags, EXC_NAME_PROC );
103
104 // get built-in name, or convert characters invalid in Calc
105 bool bBuiltIn = ::get_flag( nFlags, EXC_NAME_BUILTIN );
106
107 // special case for BIFF5 filter range - name appears as plain text without built-in flag
109 {
110 bBuiltIn = true;
112 }
113
114 // convert Excel name to Calc name
115 if( mbVBName )
116 {
117 // VB macro name
119 }
120 else if( bBuiltIn )
121 {
122 // built-in name
123 if( !maXclName.isEmpty() )
124 cBuiltIn = maXclName[0];
125 if( cBuiltIn == '?' ) // NUL character is imported as '?'
126 cBuiltIn = '\0';
128 }
129 else
130 {
131 // any other name
133 }
134
135 // add index for local names
137 {
138 sal_uInt16 nUsedTab = (GetBiff() == EXC_BIFF8) ? mnXclTab : nExtSheet;
139 // TODO: may not work for BIFF5, handle skipped sheets (all BIFF)
140 mnScTab = static_cast< SCTAB >( nUsedTab - 1 );
141 }
142
143 // 3) *** convert the name definition formula *** -------------------------
144
145 rFmlaConv.Reset();
146 std::unique_ptr<ScTokenArray> pTokArr;
147
148 if( ::get_flag( nFlags, EXC_NAME_BIG ) )
149 {
150 // special, unsupported name
151 pTokArr = rFmlaConv.GetDummy();
152 }
153 else if( bBuiltIn )
154 {
155 SCTAB const nLocalTab = (mnXclTab == EXC_NAME_GLOBAL) ? SCTAB_MAX : (mnXclTab - 1);
156
157 // --- print ranges or title ranges ---
158 rStrm.PushPosition();
159 switch( cBuiltIn )
160 {
162 if( rFmlaConv.Convert( GetPrintAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvErr::OK )
164 break;
166 if( rFmlaConv.Convert( GetTitleAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvErr::OK )
168 break;
169 }
170 rStrm.PopPosition();
171
172 // --- name formula ---
173 // JEG : double check this. It is clearly false for normal names
174 // but some of the builtins (sheettitle?) might be able to handle arrays
175 rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize, false, FT_RangeName );
176
177 // --- auto or advanced filter ---
178 if ((GetBiff() == EXC_BIFF8) && pTokArr)
179 {
180 ScRange aRange;
181 if (pTokArr->IsReference(aRange, ScAddress()))
182 {
183 switch( cBuiltIn )
184 {
186 GetFilterManager().Insert( &GetOldRoot(), aRange);
187 break;
191 break;
193 if (pTokArr->IsValidReference(aRange, ScAddress()))
195 break;
196 }
197 }
198 }
199 }
200 else if( nFmlaSize > 0 )
201 {
202 // Regular defined name. We need to convert the tokens after all the
203 // names have been registered (for cross-referenced names).
204 mpTokensData.reset(new TokenStrmData(rStrm));
205 mpTokensData->mnStrmPos = rStrm.GetSvStreamPos();
206 rStrm.StorePosition(mpTokensData->maStrmPos);
207 mpTokensData->mnStrmSize = nFmlaSize;
208 }
209
210 if (pTokArr && !bFunction && !mbVBName)
211 InsertName(pTokArr.get());
212}
213
215{
216 if (!mpTokensData)
217 return;
218
219 ExcelToSc& rFmlaConv = GetOldFmlaConverter();
220 rFmlaConv.Reset();
221 std::unique_ptr<ScTokenArray> pArray;
222
223 XclImpStreamPos aOldPos;
225 rStrm.StorePosition(aOldPos);
226 rStrm.RestorePosition(mpTokensData->maStrmPos);
227 rFmlaConv.Convert(pArray, rStrm, mpTokensData->mnStrmSize, true, FT_RangeName);
228 rStrm.RestorePosition(aOldPos);
229
230 if (pArray)
231 InsertName(pArray.get());
232
233 mpTokensData.reset();
234}
235
237{
238 // create the Calc name data
240 pData->GuessPosition(); // calculate base position for relative refs
241 pData->SetIndex( mnNameIndex ); // used as unique identifier in formulas
243 {
244 if (!GetDoc().GetRangeName()->insert(pData))
245 pData = nullptr;
246 }
247 else
248 {
249 ScRangeName* pLocalNames = GetDoc().GetRangeName(mnScTab);
250 if (pLocalNames)
251 {
252 if (!pLocalNames->insert(pData))
253 pData = nullptr;
254 }
255 else
256 {
257 delete pData;
258 pData = nullptr;
259 }
260
261 if (GetBiff() == EXC_BIFF8 && pData)
262 {
263 ScRange aRange;
264 // discard deleted ranges ( for the moment at least )
265 if ( pData->IsValidReference( aRange ) )
266 {
268 }
269 }
270 }
271 if (pData)
272 {
274 mpScData = pData; // cache for later use
275 }
276}
277
279 XclImpRoot( rRoot )
280{
281}
282
284{
285 size_t nCount = maNameList.size();
286 if( nCount < 0xFFFF )
287 maNameList.push_back( std::make_unique<XclImpName>( rStrm, static_cast< sal_uInt16 >( nCount + 1 ) ) );
288}
289
290const XclImpName* XclImpNameManager::FindName( std::u16string_view rXclName, SCTAB nScTab ) const
291{
292 const XclImpName* pGlobalName = nullptr; // a found global name
293 const XclImpName* pLocalName = nullptr; // a found local name
294 // If a duplicate name is seen by ScRangeName::insert then the existing
295 // name is erased and the new one inserted, so in the case of duplicates
296 // the last one seen is valid and the others invalid. So do this lookup in
297 // reverse in order to return the XclImpName* that references the valid
298 // entry (see tdf#44831 for the insert behavior and 'forum-mso-en4-30276.xls'
299 // for an example of this problem)
300 for (auto itName = maNameList.rbegin(); itName != maNameList.rend(); ++itName)
301 {
302 const auto& rxName = *itName;
303 if( rxName->GetXclName() == rXclName )
304 {
305 if( rxName->GetScTab() == nScTab )
306 pLocalName = rxName.get();
307 else if( rxName->IsGlobal() )
308 pGlobalName = rxName.get();
309 }
310
311 if (pLocalName)
312 break;
313 }
314 return pLocalName ? pLocalName : pGlobalName;
315}
316
317const XclImpName* XclImpNameManager::GetName( sal_uInt16 nXclNameIdx ) const
318{
319 OSL_ENSURE( nXclNameIdx > 0, "XclImpNameManager::GetName - index must be >0" );
320 return ( nXclNameIdx <= 0 || nXclNameIdx > maNameList.size() ) ? nullptr : maNameList.at( nXclNameIdx - 1 ).get();
321}
322
324{
325 for (auto& rxName : maNameList)
326 rxName->ConvertTokens();
327}
328
329/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SCTAB SCTAB_MAX
Definition: address.hxx:57
std::unique_ptr< ScTokenArray > GetDummy()
Definition: excform.cxx:191
virtual ConvErr Convert(std::unique_ptr< ScTokenArray > &, XclImpStream &rStrm, std::size_t nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT=FT_CellFormula) override
Definition: excform.cxx:201
SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck(const ScTokenArray &rCode)
Check token array and set link check if ocDde/ocWebservice is contained.
Definition: documen8.cxx:1149
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:171
ScExtTabSettings & GetOrCreateTabSettings(SCTAB nTab)
Definition: scextopt.cxx:190
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:802
static OUString ConvertToScDefinedName(const OUString &rName)
Converts a string to a valid Calc defined name or database range name.
Definition: ftools.cxx:149
void AddAdvancedRange(const ScRange &rRange)
Definition: excimp8.cxx:790
void AddExtractPos(const ScRange &rRange)
Definition: excimp8.cxx:797
void Insert(RootData *pRoot, const ScRange &rRange)
Definition: excimp8.cxx:784
void ConvertAllTokens()
Definition: xiname.cxx:323
XclImpNameManager(const XclImpRoot &rRoot)
Definition: xiname.cxx:278
XclImpNameList maNameList
Definition: xiname.hxx:104
const XclImpName * FindName(std::u16string_view rXclName, SCTAB nScTab) const
Tries to find the name used in Calc, based on the original Excel defined name.
Definition: xiname.cxx:290
void ReadName(XclImpStream &rStrm)
Reads a NAME record and creates an entry in this buffer.
Definition: xiname.cxx:283
const XclImpName * GetName(sal_uInt16 nXclNameIdx) const
Returns the defined name specified by its Excel index.
Definition: xiname.cxx:317
Represents a defined name.
Definition: xiname.hxx:34
OUString maXclName
Definition: xiname.hxx:63
sal_uInt16 mnXclTab
Definition: xiname.hxx:68
void ConvertTokens()
Definition: xiname.cxx:214
sal_uInt16 mnNameIndex
Definition: xiname.hxx:69
XclImpName(const XclImpName &)=delete
const ScRangeData * mpScData
Name inserted into the Calc document.
Definition: xiname.hxx:65
SCTAB mnScTab
Pointer to Calc defined name (no ownership).
Definition: xiname.hxx:66
std::unique_ptr< TokenStrmData > mpTokensData
Whether it's a user-defined macro.
Definition: xiname.hxx:73
OUString maScName
Original name read from the file.
Definition: xiname.hxx:64
ScRangeData::Type meNameType
Calc sheet index of local names.
Definition: xiname.hxx:67
bool mbMacro
true = Visual Basic procedure or function.
Definition: xiname.hxx:71
bool mbVBName
Definition: xiname.hxx:70
void InsertName(const ScTokenArray *pArray)
Definition: xiname.cxx:236
Access to global data from other classes.
Definition: xiroot.hxx:129
ScRangeListTabs & GetPrintAreaBuffer() const
Returns the buffer that contains all print areas in the document.
Definition: xiroot.cxx:170
ExcelToSc & GetOldFmlaConverter() const
Returns the old formula converter.
Definition: xiroot.cxx:133
ScRangeListTabs & GetTitleAreaBuffer() const
Returns the buffer that contains all print titles in the document.
Definition: xiroot.cxx:175
XclImpAutoFilterBuffer & GetFilterManager() const
Returns the filter manager.
Definition: xiroot.cxx:219
const XclImpRoot & GetRoot() const
Returns this root instance - for code readability in derived classes.
Definition: xiroot.hxx:134
This class represents an Excel stream position.
Definition: xistream.hxx:202
This class is used to import record oriented streams.
Definition: xistream.hxx:278
ScExtDocOptions & GetExtDocOptions() const
Returns the extended document options.
Definition: xlroot.cxx:429
XclBiff GetBiff() const
Returns the current BIFF version of the importer/exporter.
Definition: xlroot.hxx:141
RootData & GetOldRoot() const
Returns old RootData struct.
Definition: xlroot.hxx:138
ScDocument & GetDoc() const
Returns reference to the destination document (import) or source document (export).
Definition: xlroot.cxx:285
static OUString GetXclBuiltInDefName(sal_Unicode cBuiltIn)
Returns the raw English UI representation of a built-in defined name used in NAME records.
Definition: xltools.cxx:484
static OUString GetBuiltInDefName(sal_Unicode cBuiltIn)
Returns the Calc UI representation of a built-in defined name used in NAME records.
Definition: xltools.cxx:495
int nCount
@ FT_RangeName
Definition: formel.hxx:50
bool get_flag(Type nBitField, Type nMask)
Returns true, if at least one of the bits set in nMask is set in nBitField.
Definition: ftools.hxx:75
void set_flag(Type &rnBitField, Type nMask, bool bSet=true)
Sets or clears (according to bSet) all set bits of nMask in rnBitField.
Definition: ftools.hxx:95
std::unique_ptr< sal_Int32[]> pData
Type
void SvStream & rStrm
TokenStrmData(XclImpStream &rStrm)
Definition: xiname.cxx:31
OUString Name
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
sal_Int16 SCTAB
Definition: types.hxx:22
@ EXC_BIFF5
MS Excel 4.0.
Definition: xlconst.hxx:34
@ EXC_BIFF4
MS Excel 3.0.
Definition: xlconst.hxx:33
@ EXC_BIFF2
Definition: xlconst.hxx:31
@ EXC_BIFF8
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:35
@ EXC_BIFF3
MS Excel 2.1.
Definition: xlconst.hxx:32
const sal_Unicode EXC_BUILTIN_UNKNOWN
Definition: xlname.hxx:61
const sal_uInt16 EXC_NAME_BIG
Definition: xlname.hxx:40
const sal_Unicode EXC_BUILTIN_EXTRACT
Definition: xlname.hxx:50
const sal_uInt16 EXC_NAME_VB
Definition: xlname.hxx:35
const sal_Unicode EXC_BUILTIN_FILTERDATABASE
Definition: xlname.hxx:60
const sal_uInt16 EXC_NAME_BUILTIN
Definition: xlname.hxx:38
const sal_Unicode EXC_BUILTIN_PRINTTITLES
Definition: xlname.hxx:54
const sal_uInt16 EXC_NAME_GLOBAL
BIFF2 function/command flag.
Definition: xlname.hxx:44
const sal_uInt16 EXC_NAME_PROC
Definition: xlname.hxx:36
const sal_Unicode EXC_BUILTIN_CRITERIA
Definition: xlname.hxx:52
const sal_Unicode EXC_BUILTIN_PRINTAREA
Definition: xlname.hxx:53
const sal_uInt16 EXC_NAME_FUNC
Definition: xlname.hxx:34
const sal_uInt8 EXC_NAME2_FUNC
Definition: xlname.hxx:42
#define DBG_ERROR_BIFF()
Definition: xltools.hxx:33