xref: /aoo42x/main/sc/source/filter/excel/namebuff.cxx (revision b77af630)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scfilt.hxx"
26 
27 #include "namebuff.hxx"
28 
29 #include <tools/urlobj.hxx>
30 #include <string.h>
31 
32 #include "rangenam.hxx"
33 #include "document.hxx"
34 #include "compiler.hxx"
35 #include "scextopt.hxx"
36 
37 #include "root.hxx"
38 #include "tokstack.hxx"
39 #include "xltools.hxx"
40 #include "xiroot.hxx"
41 
42 
MakeHashCode(const String & r)43 sal_uInt32 StringHashEntry::MakeHashCode( const String& r )
44 {
45 	register sal_uInt32					n = 0;
46 	const sal_Unicode*				pAkt = r.GetBuffer();
47 	register sal_Unicode			cAkt = *pAkt;
48 
49 	while( cAkt )
50 	{
51 		n *= 70;
52 		n += ( sal_uInt32 ) cAkt;
53 		pAkt++;
54 		cAkt = *pAkt;
55 	}
56 
57 	return n;
58 }
59 
60 
61 
62 
~NameBuffer()63 NameBuffer::~NameBuffer()
64 {
65 	register StringHashEntry*	pDel = ( StringHashEntry* ) List::First();
66 	while( pDel )
67 	{
68 		delete pDel;
69 		pDel = ( StringHashEntry* ) List::Next();
70 	}
71 }
72 
73 
74 //void NameBuffer::operator <<( const SpString &rNewString )
operator <<(const String & rNewString)75 void NameBuffer::operator <<( const String &rNewString )
76 {
77 	DBG_ASSERT( Count() + nBase < 0xFFFF,
78 		"*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );
79 
80 	List::Insert( new StringHashEntry( rNewString ), LIST_APPEND );
81 }
82 
83 
84 #ifdef DBG_UTIL
85 sal_uInt16	nShrCnt;
86 #endif
87 
88 
operator ()(const ScAddress & addr) const89 size_t ShrfmlaBuffer::ScAddressHashFunc::operator() (const ScAddress &addr) const
90 {
91 	// Use something simple, it is just a hash.
92     return static_cast< sal_uInt16 >( addr.Row() ) | (static_cast< sal_uInt8 >( addr.Col() ) << 16);
93 }
94 
95 const size_t nBase = 16384; // Range~ und Shared~ Dingens mit jeweils der Haelfte Ids
ShrfmlaBuffer(RootData * pRD)96 ShrfmlaBuffer::ShrfmlaBuffer( RootData* pRD ) :
97 	ExcRoot( pRD ),
98     mnCurrIdx (nBase)
99 {
100 #ifdef DBG_UTIL
101 	nShrCnt = 0;
102 #endif
103 }
104 
~ShrfmlaBuffer()105 ShrfmlaBuffer::~ShrfmlaBuffer()
106 {
107 }
108 
Clear()109 void ShrfmlaBuffer::Clear()
110 {
111     index_hash.clear();
112     // do not clear index_list, index calculation depends on complete list size...
113     // do not change mnCurrIdx
114 }
115 
Store(const ScRange & rRange,const ScTokenArray & rToken)116 void ShrfmlaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
117 {
118 	String			aName( CreateName( rRange.aStart ) );
119 
120     DBG_ASSERT( mnCurrIdx <= 0xFFFF, "*ShrfmlaBuffer::Store(): Gleich wird mir schlecht...!" );
121 
122     ScRangeData* pData = new ScRangeData( pExcRoot->pIR->GetDocPtr(), aName, rToken, rRange.aStart, RT_SHARED );
123     const ScAddress& rMaxPos = pExcRoot->pIR->GetMaxPos();
124     pData->SetMaxCol(rMaxPos.Col());
125     pData->SetMaxRow(rMaxPos.Row());
126     pData->SetIndex( static_cast< sal_uInt16 >( mnCurrIdx ) );
127     pExcRoot->pIR->GetNamedRanges().Insert( pData );
128     index_hash[rRange.aStart] = static_cast< sal_uInt16 >( mnCurrIdx );
129 	index_list.push_front (rRange);
130     ++mnCurrIdx;
131 }
132 
133 
Find(const ScAddress & aAddr) const134 sal_uInt16 ShrfmlaBuffer::Find( const ScAddress & aAddr ) const
135 {
136 	ShrfmlaHash::const_iterator hash = index_hash.find (aAddr);
137 	if (hash != index_hash.end())
138 		return hash->second;
139 
140 	// It was not hashed on the top left corner ?  do a brute force search
141 	unsigned int ind = nBase;
142 	for (ShrfmlaList::const_iterator ptr = index_list.end(); ptr != index_list.begin() ; ind++)
143 		if ((--ptr)->In (aAddr))
144             return static_cast< sal_uInt16 >( ind );
145     return static_cast< sal_uInt16 >( mnCurrIdx );
146 }
147 
148 
149 #define SHRFMLA_BASENAME	"SHARED_FORMULA_"
150 
CreateName(const ScRange & r)151 String ShrfmlaBuffer::CreateName( const ScRange& r )
152 {
153 	String			aName( RTL_CONSTASCII_USTRINGPARAM( SHRFMLA_BASENAME ) );
154 	aName += String::CreateFromInt32( r.aStart.Col() );
155 	aName.Append( '_' );
156 	aName += String::CreateFromInt32( r.aStart.Row() );
157 	aName.Append( '_' );
158 	aName += String::CreateFromInt32( r.aEnd.Col() );
159 	aName.Append( '_' );
160 	aName += String::CreateFromInt32( r.aEnd.Row() );
161 	aName.Append( '_' );
162 	aName += String::CreateFromInt32( r.aStart.Tab() );
163 
164 	return aName;
165 }
166 
167 
~ExtSheetBuffer()168 ExtSheetBuffer::~ExtSheetBuffer()
169 {
170 	Cont	*pAkt = ( Cont * ) List::First();
171 	while( pAkt )
172 	{
173 		delete pAkt;
174 		pAkt = ( Cont * ) List::Next();
175 	}
176 }
177 
178 
Add(const String & rFPAN,const String & rTN,const sal_Bool bSWB)179 sal_Int16 ExtSheetBuffer::Add( const String& rFPAN, const String& rTN, const sal_Bool bSWB )
180 {
181 	List::Insert( new Cont( rFPAN, rTN, bSWB ), LIST_APPEND );
182     // return 1-based index of EXTERNSHEET
183     return static_cast< sal_Int16 >( List::Count() );
184 }
185 
186 
GetScTabIndex(sal_uInt16 nExcIndex,sal_uInt16 & rScIndex)187 sal_Bool ExtSheetBuffer::GetScTabIndex( sal_uInt16 nExcIndex, sal_uInt16& rScIndex )
188 {
189 	DBG_ASSERT( nExcIndex,
190 		"*ExtSheetBuffer::GetScTabIndex(): Sheet-Index == 0!" );
191 
192 	nExcIndex--;
193 	Cont*		pCur = ( Cont * ) List::GetObject( nExcIndex );
194 	sal_uInt16&		rTabNum = pCur->nTabNum;
195 
196 	if( pCur )
197 	{
198 		if( rTabNum < 0xFFFD )
199 		{
200 			rScIndex = rTabNum;
201 			return sal_True;
202 		}
203 
204 		if( rTabNum == 0xFFFF )
205 		{// neue Tabelle erzeugen
206 			SCTAB	nNewTabNum;
207 			if( pCur->bSWB )
208 			{// Tabelle ist im selben Workbook!
209                 if( pExcRoot->pIR->GetDoc().GetTable( pCur->aTab, nNewTabNum ) )
210 				{
211 					rScIndex = rTabNum = static_cast<sal_uInt16>(nNewTabNum);
212 					return sal_True;
213 				}
214 				else
215 					rTabNum = 0xFFFD;
216 			}
217             else if( pExcRoot->pIR->GetDocShell() )
218 			{// Tabelle ist 'echt' extern
219                 if( pExcRoot->pIR->GetExtDocOptions().GetDocSettings().mnLinkCnt == 0 )
220 				{
221 					String		aURL( ScGlobal::GetAbsDocName( pCur->aFile,
222                                         pExcRoot->pIR->GetDocShell() ) );
223 					String		aTabName( ScGlobal::GetDocTabName( aURL, pCur->aTab ) );
224                     if( pExcRoot->pIR->GetDoc().LinkExternalTab( nNewTabNum, aTabName, aURL, pCur->aTab ) )
225 					{
226 						rScIndex = rTabNum = static_cast<sal_uInt16>(nNewTabNum);
227 						return sal_True;
228 					}
229 					else
230 						rTabNum = 0xFFFE;		// Tabelle einmal nicht angelegt -> wird
231 												//  wohl auch nicht mehr gehen...
232 				}
233 				else
234 					rTabNum = 0xFFFE;
235 
236 			}
237 		}
238 	}
239 
240 	return sal_False;
241 }
242 
243 
IsLink(const sal_uInt16 nExcIndex) const244 sal_Bool ExtSheetBuffer::IsLink( const sal_uInt16 nExcIndex ) const
245 {
246 	DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::IsLink(): Index muss >0 sein!" );
247 	Cont*	pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
248 
249 	if( pRet )
250 		return pRet->bLink;
251 	else
252 		return sal_False;
253 }
254 
255 
GetLink(const sal_uInt16 nExcIndex,String & rAppl,String & rDoc) const256 sal_Bool ExtSheetBuffer::GetLink( const sal_uInt16 nExcIndex, String& rAppl, String& rDoc ) const
257 {
258 	DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::GetLink(): Index muss >0 sein!" );
259 	Cont*	pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
260 
261 	if( pRet )
262 	{
263 		rAppl = pRet->aFile;
264 		rDoc = pRet->aTab;
265 		return sal_True;
266 	}
267 	else
268 		return sal_False;
269 }
270 
271 
Reset(void)272 void ExtSheetBuffer::Reset( void )
273 {
274 	Cont	*pAkt = ( Cont * ) List::First();
275 	while( pAkt )
276 	{
277 		delete pAkt;
278 		pAkt = ( Cont * ) List::Next();
279 	}
280 
281 	List::Clear();
282 }
283 
284 
285 
286 
IsDDE(void) const287 sal_Bool ExtName::IsDDE( void ) const
288 {
289 	return ( nFlags & 0x0001 ) != 0;
290 }
291 
292 
IsOLE(void) const293 sal_Bool ExtName::IsOLE( void ) const
294 {
295     return ( nFlags & 0x0002 ) != 0;
296 }
297 
298 
ExtNameBuff(const XclImpRoot & rRoot)299 ExtNameBuff::ExtNameBuff( const XclImpRoot& rRoot ) :
300     XclImpRoot( rRoot )
301 {
302 }
303 
304 
AddDDE(const String & rName,sal_Int16 nRefIdx)305 void ExtNameBuff::AddDDE( const String& rName, sal_Int16 nRefIdx )
306 {
307     ExtName aNew( rName, 0x0001 );
308     maExtNames[ nRefIdx ].push_back( aNew );
309 }
310 
311 
AddOLE(const String & rName,sal_Int16 nRefIdx,sal_uInt32 nStorageId)312 void ExtNameBuff::AddOLE( const String& rName, sal_Int16 nRefIdx, sal_uInt32 nStorageId )
313 {
314     ExtName aNew( rName, 0x0002 );
315     aNew.nStorageId = nStorageId;
316     maExtNames[ nRefIdx ].push_back( aNew );
317 }
318 
319 
AddName(const String & rName,sal_Int16 nRefIdx)320 void ExtNameBuff::AddName( const String& rName, sal_Int16 nRefIdx )
321 {
322     ExtName aNew( GetScAddInName( rName ), 0x0004 );
323     maExtNames[ nRefIdx ].push_back( aNew );
324 }
325 
326 
GetNameByIndex(sal_Int16 nRefIdx,sal_uInt16 nNameIdx) const327 const ExtName* ExtNameBuff::GetNameByIndex( sal_Int16 nRefIdx, sal_uInt16 nNameIdx ) const
328 {
329     DBG_ASSERT( nNameIdx > 0, "ExtNameBuff::GetNameByIndex() - invalid name index" );
330     ExtNameMap::const_iterator aIt = maExtNames.find( nRefIdx );
331     return ((aIt != maExtNames.end()) && (0 < nNameIdx) && (nNameIdx <= aIt->second.size())) ? &aIt->second[ nNameIdx - 1 ] : 0;
332 }
333 
334 
Reset(void)335 void ExtNameBuff::Reset( void )
336 {
337     maExtNames.clear();
338 }
339 
340 
341