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>
39 #include "rangenam.hxx"
40 #include "document.hxx"
41 #include "compiler.hxx"
42 #include "scextopt.hxx"
45 #include "tokstack.hxx"
46 #include "xltools.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
;
70 NameBuffer::~NameBuffer()
72 register StringHashEntry
* pDel
= ( StringHashEntry
* ) List::First();
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
);
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
) :
112 ShrfmlaBuffer::~ShrfmlaBuffer()
116 void ShrfmlaBuffer::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
);
141 USHORT
ShrfmlaBuffer::Find( const ScAddress
& aAddr
) const
143 ShrfmlaHash::const_iterator hash
= index_hash
.find (aAddr
);
144 if (hash
!= index_hash
.end())
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() );
163 aName
+= String::CreateFromInt32( r
.aStart
.Row() );
165 aName
+= String::CreateFromInt32( r
.aEnd
.Col() );
167 aName
+= String::CreateFromInt32( r
.aEnd
.Row() );
169 aName
+= String::CreateFromInt32( r
.aStart
.Tab() );
175 ExtSheetBuffer::~ExtSheetBuffer()
177 Cont
*pAkt
= ( Cont
* ) List::First();
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!" );
200 Cont
* pCur
= ( Cont
* ) List::GetObject( nExcIndex
);
201 UINT16
& rTabNum
= pCur
->nTabNum
;
205 if( rTabNum
< 0xFFFD )
211 if( rTabNum
== 0xFFFF )
212 {// neue Tabelle erzeugen
215 {// Tabelle ist im selben Workbook!
216 if( pExcRoot
->pIR
->GetDoc().GetTable( pCur
->aTab
, nNewTabNum
) )
218 rScIndex
= rTabNum
= static_cast<UINT16
>(nNewTabNum
);
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
);
237 rTabNum
= 0xFFFE; // Tabelle einmal nicht angelegt -> wird
238 // wohl auch nicht mehr gehen...
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 );
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 );
279 void ExtSheetBuffer::Reset( void )
281 Cont
*pAkt
= ( Cont
* ) List::First();
285 pAkt
= ( Cont
* ) List::Next();
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
) :
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 )