1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include "namebuff.hxx"
25 #include "rangenam.hxx"
26 #include "document.hxx"
27 #include "compiler.hxx"
28 #include "scextopt.hxx"
31 #include "tokstack.hxx"
32 #include "xltools.hxx"
36 sal_uInt32
StringHashEntry::MakeHashCode( const String
& r
)
38 register sal_uInt32 n
= 0;
39 const sal_Unicode
* pAkt
= r
.GetBuffer();
40 register sal_Unicode cAkt
= *pAkt
;
45 n
+= ( sal_uInt32
) cAkt
;
56 NameBuffer::~NameBuffer()
58 std::vector
<StringHashEntry
*>::iterator pIter
;
59 for ( pIter
= maHashes
.begin(); pIter
!= maHashes
.end(); ++pIter
)
64 //void NameBuffer::operator <<( const SpString &rNewString )
65 void NameBuffer::operator <<( const String
&rNewString
)
67 OSL_ENSURE( maHashes
.size() + nBase
< 0xFFFF,
68 "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );
70 maHashes
.push_back( new StringHashEntry( rNewString
) );
74 #if OSL_DEBUG_LEVEL > 0
79 size_t ShrfmlaBuffer::ScAddressHashFunc::operator() (const ScAddress
&addr
) const
81 // Use something simple, it is just a hash.
82 return static_cast< sal_uInt16
>( addr
.Row() ) | (static_cast< sal_uInt8
>( addr
.Col() ) << 16);
85 const size_t nBase
= 16384; // Range~ und Shared~ Dingens mit jeweils der Haelfte Ids
86 ShrfmlaBuffer::ShrfmlaBuffer( RootData
* pRD
) :
90 #if OSL_DEBUG_LEVEL > 0
95 ShrfmlaBuffer::~ShrfmlaBuffer()
99 void ShrfmlaBuffer::Clear()
102 // do not clear index_list, index calculation depends on complete list size...
103 // do not change mnCurrIdx
106 void ShrfmlaBuffer::Store( const ScRange
& rRange
, const ScTokenArray
& rToken
)
108 String
aName( CreateName( rRange
.aStart
) );
110 OSL_ENSURE( mnCurrIdx
<= 0xFFFF, "*ShrfmlaBuffer::Store(): I'm getting sick...!" );
112 ScRangeData
* pData
= new ScRangeData( pExcRoot
->pIR
->GetDocPtr(), aName
, rToken
, rRange
.aStart
, RT_SHARED
);
113 const ScAddress
& rMaxPos
= pExcRoot
->pIR
->GetMaxPos();
114 pData
->SetMaxCol(rMaxPos
.Col());
115 pData
->SetMaxRow(rMaxPos
.Row());
116 pData
->SetIndex( static_cast< sal_uInt16
>( mnCurrIdx
) );
117 pExcRoot
->pIR
->GetNamedRanges().insert( pData
);
118 index_hash
[rRange
.aStart
] = static_cast< sal_uInt16
>( mnCurrIdx
);
119 index_list
.push_front (rRange
);
124 sal_uInt16
ShrfmlaBuffer::Find( const ScAddress
& aAddr
) const
126 ShrfmlaHash::const_iterator hash
= index_hash
.find (aAddr
);
127 if (hash
!= index_hash
.end())
130 // It was not hashed on the top left corner ? do a brute force search
131 unsigned int ind
= nBase
;
132 for (ShrfmlaList::const_iterator ptr
= index_list
.end(); ptr
!= index_list
.begin() ; ind
++)
133 if ((--ptr
)->In (aAddr
))
134 return static_cast< sal_uInt16
>( ind
);
135 return static_cast< sal_uInt16
>( mnCurrIdx
);
139 #define SHRFMLA_BASENAME "SHARED_FORMULA_"
141 String
ShrfmlaBuffer::CreateName( const ScRange
& r
)
143 OUString aName
= SHRFMLA_BASENAME
+
144 OUString::number( r
.aStart
.Col() ) + "_" +
145 OUString::number( r
.aStart
.Row() ) + "_" +
146 OUString::number( r
.aEnd
.Col() ) + "_" +
147 OUString::number( r
.aEnd
.Row() ) + "_" +
148 OUString::number( r
.aStart
.Tab() );
153 sal_Int16
ExtSheetBuffer::Add( const String
& rFPAN
, const String
& rTN
, const sal_Bool bSWB
)
155 maEntries
.push_back( Cont( rFPAN
, rTN
, bSWB
) );
156 // return 1-based index of EXTERNSHEET
157 return static_cast< sal_Int16
>( maEntries
.size() );
161 sal_Bool
ExtSheetBuffer::GetScTabIndex( sal_uInt16 nExcIndex
, sal_uInt16
& rScIndex
)
163 OSL_ENSURE( nExcIndex
,
164 "*ExtSheetBuffer::GetScTabIndex(): Sheet-Index == 0!" );
166 if ( !nExcIndex
|| nExcIndex
> maEntries
.size() )
169 Cont
* pCur
= &maEntries
[ nExcIndex
- 1 ];
170 sal_uInt16
& rTabNum
= pCur
->nTabNum
;
172 if( rTabNum
< 0xFFFD )
178 if( rTabNum
== 0xFFFF )
179 {// neue Tabelle erzeugen
182 {// Tabelle ist im selben Workbook!
183 if( pExcRoot
->pIR
->GetDoc().GetTable( pCur
->aTab
, nNewTabNum
) )
185 rScIndex
= rTabNum
= static_cast<sal_uInt16
>(nNewTabNum
);
191 else if( pExcRoot
->pIR
->GetDocShell() )
192 {// Tabelle ist 'echt' extern
193 if( pExcRoot
->pIR
->GetExtDocOptions().GetDocSettings().mnLinkCnt
== 0 )
195 String
aURL( ScGlobal::GetAbsDocName( pCur
->aFile
,
196 pExcRoot
->pIR
->GetDocShell() ) );
197 String
aTabName( ScGlobal::GetDocTabName( aURL
, pCur
->aTab
) );
198 if( pExcRoot
->pIR
->GetDoc().LinkExternalTab( nNewTabNum
, aTabName
, aURL
, pCur
->aTab
) )
200 rScIndex
= rTabNum
= static_cast<sal_uInt16
>(nNewTabNum
);
204 rTabNum
= 0xFFFE; // Tabelle einmal nicht angelegt -> wird
205 // wohl auch nicht mehr gehen...
217 sal_Bool
ExtSheetBuffer::IsLink( const sal_uInt16 nExcIndex
) const
219 OSL_ENSURE( nExcIndex
> 0, "*ExtSheetBuffer::IsLink(): Index has to be >0!" );
221 if (!nExcIndex
|| nExcIndex
> maEntries
.size() )
224 return maEntries
[ nExcIndex
-1 ].bLink
;
228 sal_Bool
ExtSheetBuffer::GetLink( const sal_uInt16 nExcIndex
, String
& rAppl
, String
& rDoc
) const
230 OSL_ENSURE( nExcIndex
> 0, "*ExtSheetBuffer::GetLink(): Index has to be >0!" );
232 if (!nExcIndex
|| nExcIndex
> maEntries
.size() )
235 const Cont
&rRet
= maEntries
[ nExcIndex
-1 ];
244 void ExtSheetBuffer::Reset( void )
252 sal_Bool
ExtName::IsDDE( void ) const
254 return ( nFlags
& 0x0001 ) != 0;
258 sal_Bool
ExtName::IsOLE( void ) const
260 return ( nFlags
& 0x0002 ) != 0;
264 ExtNameBuff::ExtNameBuff( const XclImpRoot
& rRoot
) :
270 void ExtNameBuff::AddDDE( const String
& rName
, sal_Int16 nRefIdx
)
272 ExtName
aNew( rName
, 0x0001 );
273 maExtNames
[ nRefIdx
].push_back( aNew
);
277 void ExtNameBuff::AddOLE( const String
& rName
, sal_Int16 nRefIdx
, sal_uInt32 nStorageId
)
279 ExtName
aNew( rName
, 0x0002 );
280 aNew
.nStorageId
= nStorageId
;
281 maExtNames
[ nRefIdx
].push_back( aNew
);
285 void ExtNameBuff::AddName( const String
& rName
, sal_Int16 nRefIdx
)
287 ExtName
aNew( GetScAddInName( rName
), 0x0004 );
288 maExtNames
[ nRefIdx
].push_back( aNew
);
292 const ExtName
* ExtNameBuff::GetNameByIndex( sal_Int16 nRefIdx
, sal_uInt16 nNameIdx
) const
294 OSL_ENSURE( nNameIdx
> 0, "ExtNameBuff::GetNameByIndex() - invalid name index" );
295 ExtNameMap::const_iterator aIt
= maExtNames
.find( nRefIdx
);
296 return ((aIt
!= maExtNames
.end()) && (0 < nNameIdx
) && (nNameIdx
<= aIt
->second
.size())) ? &aIt
->second
[ nNameIdx
- 1 ] : 0;
300 void ExtNameBuff::Reset( void )
306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */