Update ooo320-m1
[ooovba.git] / sc / source / filter / excel / namebuff.cxx
blob5ecea62ba49565fccd3bd2712ed0b50ea11b1938
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: namebuff.cxx,v $
10 * $Revision: 1.26.32.1 $
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"
34 #include "namebuff.hxx"
36 #include <tools/urlobj.hxx>
37 #include <string.h>
39 #include "rangenam.hxx"
40 #include "document.hxx"
41 #include "compiler.hxx"
42 #include "scextopt.hxx"
44 #include "root.hxx"
45 #include "tokstack.hxx"
46 #include "xltools.hxx"
47 #include "xiroot.hxx"
50 UINT32 StringHashEntry::MakeHashCode( const String& r )
52 register UINT32 n = 0;
53 const sal_Unicode* pAkt = r.GetBuffer();
54 register sal_Unicode cAkt = *pAkt;
56 while( cAkt )
58 n *= 70;
59 n += ( UINT32 ) cAkt;
60 pAkt++;
61 cAkt = *pAkt;
64 return n;
70 NameBuffer::~NameBuffer()
72 register StringHashEntry* pDel = ( StringHashEntry* ) List::First();
73 while( pDel )
75 delete pDel;
76 pDel = ( StringHashEntry* ) List::Next();
81 //void NameBuffer::operator <<( const SpString &rNewString )
82 void NameBuffer::operator <<( const String &rNewString )
84 DBG_ASSERT( Count() + nBase < 0xFFFF,
85 "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );
87 List::Insert( new StringHashEntry( rNewString ), LIST_APPEND );
91 #ifdef DBG_UTIL
92 UINT16 nShrCnt;
93 #endif
96 size_t ShrfmlaBuffer::ScAddressHashFunc::operator() (const ScAddress &addr) const
98 // Use something simple, it is just a hash.
99 return static_cast< UINT16 >( addr.Row() ) | (static_cast< UINT8 >( addr.Col() ) << 16);
102 const size_t nBase = 16384; // Range~ und Shared~ Dingens mit jeweils der Haelfte Ids
103 ShrfmlaBuffer::ShrfmlaBuffer( RootData* pRD ) :
104 ExcRoot( pRD ),
105 mnCurrIdx (nBase)
107 #ifdef DBG_UTIL
108 nShrCnt = 0;
109 #endif
112 ShrfmlaBuffer::~ShrfmlaBuffer()
116 void ShrfmlaBuffer::Clear()
118 index_hash.clear();
119 // do not clear index_list, index calculation depends on complete list size...
120 // do not change mnCurrIdx
123 void ShrfmlaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
125 String aName( CreateName( rRange.aStart ) );
127 DBG_ASSERT( mnCurrIdx <= 0xFFFF, "*ShrfmlaBuffer::Store(): Gleich wird mir schlecht...!" );
129 ScRangeData* pData = new ScRangeData( pExcRoot->pIR->GetDocPtr(), aName, rToken, rRange.aStart, RT_SHARED );
130 const ScAddress& rMaxPos = pExcRoot->pIR->GetMaxPos();
131 pData->SetMaxCol(rMaxPos.Col());
132 pData->SetMaxRow(rMaxPos.Row());
133 pData->SetIndex( static_cast< USHORT >( mnCurrIdx ) );
134 pExcRoot->pIR->GetNamedRanges().Insert( pData );
135 index_hash[rRange.aStart] = static_cast< USHORT >( mnCurrIdx );
136 index_list.push_front (rRange);
137 ++mnCurrIdx;
141 USHORT ShrfmlaBuffer::Find( const ScAddress & aAddr ) const
143 ShrfmlaHash::const_iterator hash = index_hash.find (aAddr);
144 if (hash != index_hash.end())
145 return hash->second;
147 // It was not hashed on the top left corner ? do a brute force search
148 unsigned int ind = nBase;
149 for (ShrfmlaList::const_iterator ptr = index_list.end(); ptr != index_list.begin() ; ind++)
150 if ((--ptr)->In (aAddr))
151 return static_cast< USHORT >( ind );
152 return static_cast< USHORT >( mnCurrIdx );
156 #define SHRFMLA_BASENAME "SHARED_FORMULA_"
158 String ShrfmlaBuffer::CreateName( const ScRange& r )
160 String aName( RTL_CONSTASCII_USTRINGPARAM( SHRFMLA_BASENAME ) );
161 aName += String::CreateFromInt32( r.aStart.Col() );
162 aName.Append( '_' );
163 aName += String::CreateFromInt32( r.aStart.Row() );
164 aName.Append( '_' );
165 aName += String::CreateFromInt32( r.aEnd.Col() );
166 aName.Append( '_' );
167 aName += String::CreateFromInt32( r.aEnd.Row() );
168 aName.Append( '_' );
169 aName += String::CreateFromInt32( r.aStart.Tab() );
171 return aName;
175 ExtSheetBuffer::~ExtSheetBuffer()
177 Cont *pAkt = ( Cont * ) List::First();
178 while( pAkt )
180 delete pAkt;
181 pAkt = ( Cont * ) List::Next();
186 sal_Int16 ExtSheetBuffer::Add( const String& rFPAN, const String& rTN, const BOOL bSWB )
188 List::Insert( new Cont( rFPAN, rTN, bSWB ), LIST_APPEND );
189 // return 1-based index of EXTERNSHEET
190 return static_cast< sal_Int16 >( List::Count() );
194 BOOL ExtSheetBuffer::GetScTabIndex( UINT16 nExcIndex, UINT16& rScIndex )
196 DBG_ASSERT( nExcIndex,
197 "*ExtSheetBuffer::GetScTabIndex(): Sheet-Index == 0!" );
199 nExcIndex--;
200 Cont* pCur = ( Cont * ) List::GetObject( nExcIndex );
201 UINT16& rTabNum = pCur->nTabNum;
203 if( pCur )
205 if( rTabNum < 0xFFFD )
207 rScIndex = rTabNum;
208 return TRUE;
211 if( rTabNum == 0xFFFF )
212 {// neue Tabelle erzeugen
213 SCTAB nNewTabNum;
214 if( pCur->bSWB )
215 {// Tabelle ist im selben Workbook!
216 if( pExcRoot->pIR->GetDoc().GetTable( pCur->aTab, nNewTabNum ) )
218 rScIndex = rTabNum = static_cast<UINT16>(nNewTabNum);
219 return TRUE;
221 else
222 rTabNum = 0xFFFD;
224 else if( pExcRoot->pIR->GetDocShell() )
225 {// Tabelle ist 'echt' extern
226 if( pExcRoot->pIR->GetExtDocOptions().GetDocSettings().mnLinkCnt == 0 )
228 String aURL( ScGlobal::GetAbsDocName( pCur->aFile,
229 pExcRoot->pIR->GetDocShell() ) );
230 String aTabName( ScGlobal::GetDocTabName( aURL, pCur->aTab ) );
231 if( pExcRoot->pIR->GetDoc().LinkExternalTab( nNewTabNum, aTabName, aURL, pCur->aTab ) )
233 rScIndex = rTabNum = static_cast<UINT16>(nNewTabNum);
234 return TRUE;
236 else
237 rTabNum = 0xFFFE; // Tabelle einmal nicht angelegt -> wird
238 // wohl auch nicht mehr gehen...
240 else
241 rTabNum = 0xFFFE;
247 return FALSE;
251 BOOL ExtSheetBuffer::IsLink( const UINT16 nExcIndex ) const
253 DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::IsLink(): Index muss >0 sein!" );
254 Cont* pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
256 if( pRet )
257 return pRet->bLink;
258 else
259 return FALSE;
263 BOOL ExtSheetBuffer::GetLink( const UINT16 nExcIndex, String& rAppl, String& rDoc ) const
265 DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::GetLink(): Index muss >0 sein!" );
266 Cont* pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
268 if( pRet )
270 rAppl = pRet->aFile;
271 rDoc = pRet->aTab;
272 return TRUE;
274 else
275 return FALSE;
279 void ExtSheetBuffer::Reset( void )
281 Cont *pAkt = ( Cont * ) List::First();
282 while( pAkt )
284 delete pAkt;
285 pAkt = ( Cont * ) List::Next();
288 List::Clear();
294 BOOL ExtName::IsDDE( void ) const
296 return ( nFlags & 0x0001 ) != 0;
300 BOOL ExtName::IsOLE( void ) const
302 return ( nFlags & 0x0002 ) != 0;
306 ExtNameBuff::ExtNameBuff( const XclImpRoot& rRoot ) :
307 XclImpRoot( rRoot )
312 void ExtNameBuff::AddDDE( const String& rName, sal_Int16 nRefIdx )
314 ExtName aNew( rName, 0x0001 );
315 maExtNames[ nRefIdx ].push_back( aNew );
319 void ExtNameBuff::AddOLE( const String& rName, sal_Int16 nRefIdx, UINT32 nStorageId )
321 ExtName aNew( rName, 0x0002 );
322 aNew.nStorageId = nStorageId;
323 maExtNames[ nRefIdx ].push_back( aNew );
327 void ExtNameBuff::AddName( const String& rName, sal_Int16 nRefIdx )
329 ExtName aNew( GetScAddInName( rName ), 0x0004 );
330 maExtNames[ nRefIdx ].push_back( aNew );
334 const ExtName* ExtNameBuff::GetNameByIndex( sal_Int16 nRefIdx, sal_uInt16 nNameIdx ) const
336 DBG_ASSERT( nNameIdx > 0, "ExtNameBuff::GetNameByIndex() - invalid name index" );
337 ExtNameMap::const_iterator aIt = maExtNames.find( nRefIdx );
338 return ((aIt != maExtNames.end()) && (0 < nNameIdx) && (nNameIdx <= aIt->second.size())) ? &aIt->second[ nNameIdx - 1 ] : 0;
342 void ExtNameBuff::Reset( void )
344 maExtNames.clear();