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 .
20 #include "scitems.hxx"
21 #include <svx/algitem.hxx>
22 #include <editeng/justifyitem.hxx>
23 #include <svl/zforlist.hxx>
25 #include "rangenam.hxx"
26 #include "compiler.hxx"
31 #include "lotrange.hxx"
32 #include "namebuff.hxx"
34 #include "stringutil.hxx"
35 #include "tokenarray.hxx"
36 #include "lotfilter.hxx"
40 void PutFormString(LotusContext
& rContext
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_Char
* pString
)
42 // evaluate Label-Format
43 OSL_ENSURE( pString
!= NULL
, "PutFormString(): pString == NULL" );
48 SvxHorJustifyItem
* pJustify
= NULL
;
54 case '"': // align-right
55 pJustify
= rContext
.pAttrRight
;
58 case '\'': // align-left
59 pJustify
= rContext
.pAttrLeft
;
63 pJustify
= rContext
.pAttrCenter
;
66 case '|': // printer command
69 case '\\': // repetition
70 pJustify
= rContext
.pAttrRepeat
;
73 default: // undefined case!
74 pJustify
= rContext
.pAttrStandard
;
80 nCol
= SanitizeCol(nCol
);
81 nRow
= SanitizeRow(nRow
);
82 nTab
= SanitizeTab(nTab
);
84 rContext
.pDoc
->ApplyAttr( nCol
, nRow
, nTab
, *pJustify
);
85 ScSetStringParam aParam
;
86 aParam
.setTextInput();
87 rContext
.pDoc
->SetString(ScAddress(nCol
,nRow
,nTab
), OUString(pString
, strlen(pString
), rContext
.pLotusRoot
->eCharsetQ
), &aParam
);
90 void SetFormat(LotusContext
& rContext
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_uInt8 nFormat
, sal_uInt8 nSt
)
92 nCol
= SanitizeCol(nCol
);
93 nRow
= SanitizeRow(nRow
);
94 nTab
= SanitizeTab(nTab
);
96 // PREC: nSt = default number of decimal places
97 rContext
.pDoc
->ApplyAttr(nCol
, nRow
, nTab
, *(rContext
.pValueFormCache
->GetAttr(nFormat
, nSt
)));
99 ScProtectionAttr aAttr
;
101 aAttr
.SetProtection( nFormat
& 0x80 );
103 rContext
.pDoc
->ApplyAttr( nCol
, nRow
, nTab
, aAttr
);
106 double SnumToDouble( sal_Int16 nVal
)
108 const double pFacts
[ 8 ] = {
122 fVal
= pFacts
[ ( nVal
>> 1 ) & 0x0007 ];
123 fVal
*= ( sal_Int16
) ( nVal
>> 4 );
126 fVal
= ( sal_Int16
) ( nVal
>> 1 );
131 double Snum32ToDouble( sal_uInt32 nValue
)
135 fValue
= nValue
>> 6;
136 temp
= nValue
& 0x0f;
139 if (nValue
& 0x00000010)
140 fValue
/= pow((double)10, temp
);
142 fValue
*= pow((double)10, temp
);
145 if ((nValue
& 0x00000020))
150 FormCache::FormCache( ScDocument
* pDoc1
, sal_uInt8 nNewDefaultFormat
)
152 { // Default format is 'Default'
153 nDefaultFormat
= nNewDefaultFormat
;
154 pFormTable
= pDoc1
->GetFormatTable();
155 for( sal_uInt16 nC
= 0 ; nC
< __nSize
; nC
++ )
156 bValid
[ nC
] = false;
157 eLanguage
= ScGlobal::eLnge
;
160 FormCache::~FormCache()
162 for( sal_uInt16 nC
= 0 ; nC
< __nSize
; nC
++ )
163 delete aIdents
[ nC
].GetAttr();
166 SfxUInt32Item
* FormCache::NewAttr( sal_uInt8 nFormat
, sal_uInt8 nSt
)
169 sal_uInt8 nL
, nH
; // Low-/High-Nibble
170 sal_uInt8 nForm
= nFormat
;
171 OUString aFormString
;
172 sal_Int16 eType
= css::util::NumberFormat::ALL
;
175 NfIndexTableOffset eIndexTableOffset
= NF_NUMERIC_START
;
176 bool bDefault
= false;
178 if( nForm
== 0xFF ) // Default-Format?
179 nForm
= nDefaultFormat
;
181 // split into Low and High byte
183 nH
= ( nFormat
& 0xF0 ) / 16;
185 nH
&= 0x07; // extract bits 4-6
188 case 0x00: // fixed-point number
190 nIndex1
= pFormTable
->GetStandardFormat(
191 css::util::NumberFormat::NUMBER
, eLanguage
);
192 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
193 eLanguage
, false, false, nL
, 1);
195 case 0x01: // scientific notation
197 nIndex1
= pFormTable
->GetStandardFormat(
198 css::util::NumberFormat::SCIENTIFIC
, eLanguage
);
199 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
200 eLanguage
, false, false, nL
, 1);
202 case 0x02: // currency
204 nIndex1
= pFormTable
->GetStandardFormat(
205 css::util::NumberFormat::CURRENCY
, eLanguage
);
206 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
207 eLanguage
, false, false, nL
, 1);
209 case 0x03: // percentage
211 nIndex1
= pFormTable
->GetStandardFormat(
212 css::util::NumberFormat::PERCENT
, eLanguage
);
213 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
214 eLanguage
, false, false, nL
, 1);
216 case 0x04: // Decimal
218 nIndex1
= pFormTable
->GetStandardFormat(
219 css::util::NumberFormat::NUMBER
, eLanguage
);
220 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
221 eLanguage
, true, false, nL
, 1);
223 case 0x05: // unspecified
225 nIndex1
= pFormTable
->GetStandardFormat(
226 css::util::NumberFormat::NUMBER
, eLanguage
);
227 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
228 eLanguage
, false, false, nL
, 1);
230 case 0x06: // unspecified
232 nIndex1
= pFormTable
->GetStandardFormat(
233 css::util::NumberFormat::NUMBER
, eLanguage
);
234 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
235 eLanguage
, false, false, nL
, 1);
238 case 0x07: // Special format
243 nIndex1
= pFormTable
->GetStandardFormat(
244 css::util::NumberFormat::NUMBER
, eLanguage
);
245 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
246 eLanguage
, false, true, nSt
, 1);
248 case 0x01: // general Format
250 nIndex1
= pFormTable
->GetStandardFormat(
251 css::util::NumberFormat::NUMBER
, eLanguage
);
252 aFormString
= pFormTable
->GenerateFormat(nIndex1
,
253 eLanguage
, false, false, nSt
, 1);
255 case 0x02: // Date: Day, Month, Year
256 //fDate;dfDayMonthYearLong;
257 eType
= css::util::NumberFormat::DATE
;
258 eIndexTableOffset
= NF_DATE_SYS_DDMMYYYY
;
260 case 0x03: // Date: Day, Month
261 //fDate;dfDayMonthLong;
262 eType
= css::util::NumberFormat::DATE
;
263 aFormString
= pFormTable
->GetKeyword( eLanguage
, NF_KEY_DD
);
264 aFormString
+= pFormTable
->GetDateSep(); // matches last eLanguage
265 aFormString
+= pFormTable
->GetKeyword( eLanguage
, NF_KEY_MMMM
);
267 case 0x04: // Date: Month, Year
268 //fDate;dfMonthYearLong;
269 eType
= css::util::NumberFormat::DATE
;
270 aFormString
= pFormTable
->GetKeyword( eLanguage
, NF_KEY_MM
);
271 aFormString
+= pFormTable
->GetDateSep(); // matches last eLanguage
272 aFormString
+= pFormTable
->GetKeyword( eLanguage
, NF_KEY_YYYY
);
274 case 0x05: // Text formats
276 eType
= css::util::NumberFormat::TEXT
;
277 eIndexTableOffset
= NF_TEXT
;
280 //wFlag |= paHideAll;bSetFormat = sal_False;
281 eType
= css::util::NumberFormat::NUMBER
;
282 aFormString
= "\"\"";
284 case 0x07: // Time: hour, min, sec
285 //fTime;tfHourMinSec24;
286 eType
= css::util::NumberFormat::TIME
;
287 eIndexTableOffset
= NF_TIME_HHMMSS
;
289 case 0x08: // Time: hour, min
291 eType
= css::util::NumberFormat::TIME
;
292 eIndexTableOffset
= NF_TIME_HHMM
;
294 case 0x09: // Date, intern sal_Int32 1
295 //fDate;dfDayMonthYearLong;
296 eType
= css::util::NumberFormat::DATE
;
297 eIndexTableOffset
= NF_DATE_SYS_DDMMYYYY
;
299 case 0x0A: // Date, intern sal_Int32 2
300 //fDate;dfDayMonthYearLong;
301 eType
= css::util::NumberFormat::DATE
;
302 eIndexTableOffset
= NF_DATE_SYS_DDMMYYYY
;
304 case 0x0B: // Time, intern sal_Int32 1
305 //fTime;tfHourMinSec24;
306 eType
= css::util::NumberFormat::TIME
;
307 eIndexTableOffset
= NF_TIME_HHMMSS
;
309 case 0x0C: // Time, intern sal_Int32 2
310 //fTime;tfHourMinSec24;
311 eType
= css::util::NumberFormat::TIME
;
312 eIndexTableOffset
= NF_TIME_HHMMSS
;
314 case 0x0F: // Default
326 // push Format into table
329 else if (eIndexTableOffset
!= NF_NUMERIC_START
)
330 nHandle
= pFormTable
->GetFormatIndex( eIndexTableOffset
, eLanguage
);
334 pFormTable
->PutEntry( aFormString
, nDummy
, eType
, nHandle
, eLanguage
);
337 return new SfxUInt32Item( ATTR_VALUE_FORMAT
, ( sal_uInt32
) nHandle
);
340 void LotusRange::MakeHash()
342 // 33222222222211111111110000000000
343 // 10987654321098765432109876543210
346 // **************** nRowS
347 // **************** nRowE
348 nHash
= static_cast<sal_uInt32
>(nColStart
);
349 nHash
+= static_cast<sal_uInt32
>(nColEnd
) << 6;
350 nHash
+= static_cast<sal_uInt32
>(nRowStart
) << 12;
351 nHash
+= static_cast<sal_uInt32
>(nRowEnd
) << 16;
354 LotusRange::LotusRange( SCCOL nCol
, SCROW nRow
)
356 nColStart
= nColEnd
= nCol
;
357 nRowStart
= nRowEnd
= nRow
;
362 LotusRange::LotusRange( SCCOL nCS
, SCROW nRS
, SCCOL nCE
, SCROW nRE
)
372 LotusRange::LotusRange( const LotusRange
& rCpy
)
377 LotusRangeList::LotusRangeList(LOTUS_ROOT
* pLotRoot
)
378 : m_pLotRoot(pLotRoot
)
380 aComplRef
.InitFlags();
382 ScSingleRefData
* pSingRef
;
385 pSingRef
= &aComplRef
.Ref1
;
386 pSingRef
->SetRelTab(0);
387 pSingRef
->SetColRel( false );
388 pSingRef
->SetRowRel( false );
389 pSingRef
->SetFlag3D( false );
391 pSingRef
= &aComplRef
.Ref2
;
392 pSingRef
->SetRelTab(0);
393 pSingRef
->SetColRel( false );
394 pSingRef
->SetRowRel( false );
395 pSingRef
->SetFlag3D( false );
398 SCCOL
LotusRangeList::nEingCol
;
399 SCROW
LotusRangeList::nEingRow
;
401 LotusRangeList::~LotusRangeList ()
403 std::vector
<LotusRange
*>::iterator pIter
;
404 for (pIter
= maRanges
.begin(); pIter
!= maRanges
.end(); ++pIter
)
408 LR_ID
LotusRangeList::GetIndex( const LotusRange
&rRef
)
410 std::vector
<LotusRange
*>::iterator pIter
;
411 for (pIter
= maRanges
.begin(); pIter
!= maRanges
.end(); ++pIter
)
413 if (rRef
== *(*pIter
))
414 return (*pIter
)->nId
;
420 void LotusRangeList::Append( LotusRange
* pLR
, const OUString
& rName
)
422 OSL_ENSURE( pLR
, "*LotusRangeList::Append(): no pointer!" );
423 maRanges
.push_back(pLR
);
425 ScTokenArray aTokArray
;
427 ScSingleRefData
* pSingRef
= &aComplRef
.Ref1
;
429 pSingRef
->SetAbsCol(pLR
->nColStart
);
430 pSingRef
->SetAbsRow(pLR
->nRowStart
);
432 if( pLR
->IsSingle() )
433 aTokArray
.AddSingleReference( *pSingRef
);
436 pSingRef
= &aComplRef
.Ref2
;
437 pSingRef
->SetAbsCol(pLR
->nColEnd
);
438 pSingRef
->SetAbsRow(pLR
->nRowEnd
);
439 aTokArray
.AddDoubleReference( aComplRef
);
442 ScRangeData
* pData
= new ScRangeData(
443 m_pLotRoot
->pDoc
, rName
, aTokArray
);
445 m_pLotRoot
->pScRangeName
->insert( pData
);
447 pLR
->SetId( nIdCnt
);
452 RangeNameBufferWK3::RangeNameBufferWK3(LOTUS_ROOT
* pLotRoot
)
453 : m_pLotRoot(pLotRoot
)
455 pScTokenArray
= new ScTokenArray
;
459 RangeNameBufferWK3::~RangeNameBufferWK3()
461 delete pScTokenArray
;
464 void RangeNameBufferWK3::Add( const OUString
& rOrgName
, const ScComplexRefData
& rCRD
)
466 OUString aScName
= ScfTools::ConvertToScDefinedName(rOrgName
);
468 Entry
aInsert( rOrgName
, aScName
, rCRD
);
470 pScTokenArray
->Clear();
472 const ScSingleRefData
& rRef1
= rCRD
.Ref1
;
473 const ScSingleRefData
& rRef2
= rCRD
.Ref2
;
474 ScAddress aAbs1
= rRef1
.toAbs(ScAddress());
475 ScAddress aAbs2
= rRef2
.toAbs(ScAddress());
478 pScTokenArray
->AddSingleReference( rCRD
.Ref1
);
479 aInsert
.bSingleRef
= true;
483 pScTokenArray
->AddDoubleReference( rCRD
);
484 aInsert
.bSingleRef
= false;
487 ScRangeData
* pData
= new ScRangeData( m_pLotRoot
->pDoc
, aScName
, *pScTokenArray
);
489 aInsert
.nRelInd
= nIntCount
;
490 pData
->SetIndex( nIntCount
);
493 maEntries
.push_back( aInsert
);
494 m_pLotRoot
->pScRangeName
->insert( pData
);
497 bool RangeNameBufferWK3::FindRel( const OUString
& rRef
, sal_uInt16
& rIndex
)
499 StringHashEntry
aRef( rRef
);
501 std::vector
<Entry
>::const_iterator itr
;
502 for ( itr
= maEntries
.begin(); itr
!= maEntries
.end(); ++itr
)
504 if ( aRef
== itr
->aStrHashEntry
)
506 rIndex
= itr
->nRelInd
;
514 bool RangeNameBufferWK3::FindAbs( const OUString
& rRef
, sal_uInt16
& rIndex
)
516 OUString
aTmp( rRef
);
518 StringHashEntry
aRef( aTmp
); // search w/o '$'!
520 std::vector
<Entry
>::iterator itr
;
521 for ( itr
= maEntries
.begin(); itr
!= maEntries
.end(); ++itr
)
523 if ( aRef
== itr
->aStrHashEntry
)
525 // setup new range if needed
527 rIndex
= itr
->nAbsInd
;
530 ScSingleRefData
* pRef
= &itr
->aScComplexRefDataRel
.Ref1
;
531 pScTokenArray
->Clear();
533 pRef
->SetColRel( false );
534 pRef
->SetRowRel( false );
535 pRef
->SetTabRel( true );
537 if( itr
->bSingleRef
)
538 pScTokenArray
->AddSingleReference( *pRef
);
541 pRef
= &itr
->aScComplexRefDataRel
.Ref2
;
542 pRef
->SetColRel( false );
543 pRef
->SetRowRel( false );
544 pRef
->SetTabRel( true );
545 pScTokenArray
->AddDoubleReference( itr
->aScComplexRefDataRel
);
548 ScRangeData
* pData
= new ScRangeData( m_pLotRoot
->pDoc
, itr
->aScAbsName
, *pScTokenArray
);
550 rIndex
= itr
->nAbsInd
= nIntCount
;
551 pData
->SetIndex( rIndex
);
554 m_pLotRoot
->pScRangeName
->insert( pData
);
564 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */