1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
33 //------------------------------------------------------------------------
35 #include "scitems.hxx"
36 #include <svx/algitem.hxx>
37 #include <svl/zforlist.hxx>
38 #include <tools/solar.h>
41 #include "rangenam.hxx"
42 #include "compiler.hxx"
47 #include "lotrange.hxx"
48 #include "namebuff.hxx"
54 #pragma optimize("",off)
57 //--------------------------------------------------------- EXTERNE VARIABLEN -
58 extern WKTYP eTyp
; // -> filter.cxx, aktueller Dateityp
59 extern sal_Char
* pDummy2
; // -> memory.cxx
60 extern ScDocument
* pDoc
; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
61 extern CharSet eCharNach
; // -> filter.cxx, Zeichenkonvertierung von->nach
63 extern BOOL bFormInit
; // -> memory.cxx, fuer GetFormHandle()
65 //--------------------------------------------------------- GLOBALE VARIABLEN -
66 BYTE nDefaultFormat
; // -> op.cpp, Standard-Zellenformat
68 extern SvxHorJustifyItem
*pAttrRight
, *pAttrLeft
, *pAttrCenter
, *pAttrRepeat
, *pAttrStandard
;
69 extern ScProtectionAttr
* pAttrUnprot
;
70 extern SfxUInt32Item
** pAttrValForms
;
72 SvxHorJustifyItem
*pAttrRight
, *pAttrLeft
, *pAttrCenter
, *pAttrRepeat
, *pAttrStandard
;
73 // -> in memory.cxx initialisiert
74 ScProtectionAttr
* pAttrUnprot
; // -> " memory.cxx "
76 extern FormCache
* pValueFormCache
; // -> in memory.cxx initialisiert
77 FormCache
* pValueFormCache
;
79 SCCOL
LotusRangeList::nEingCol
;
80 SCROW
LotusRangeList::nEingRow
;
85 void PutFormString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_Char
* pString
)
87 // Label-Format-Auswertung
88 DBG_ASSERT( pString
!= NULL
, "PutFormString(): pString == NULL" );
91 SvxHorJustifyItem
* pJustify
= NULL
;
97 case '"': // rechtsbuendig
98 pJustify
= pAttrRight
;
101 case '\'': // linksbuendig
102 pJustify
= pAttrLeft
;
105 case '^': // zentriert
106 pJustify
= pAttrCenter
;
109 case '|': // printer command
112 case '\\': // Wiederholung
113 pJustify
= pAttrRepeat
;
116 default: // kenn' ich nicht!
117 pJustify
= pAttrStandard
;
122 pDoc
->ApplyAttr( nCol
, nRow
, nTab
, *pJustify
);
123 ScStringCell
* pZelle
= new ScStringCell( String( pString
, pLotusRoot
->eCharsetQ
) );
124 pDoc
->PutCell( nCol
, nRow
, nTab
, pZelle
, ( BOOL
) TRUE
);
131 void SetFormat( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, BYTE nFormat
, BYTE nSt
)
133 // PREC: nSt = Standard-Dezimalstellenanzahl
134 pDoc
->ApplyAttr( nCol
, nRow
, nTab
, *( pValueFormCache
->GetAttr( nFormat
, nSt
) ) );
136 ScProtectionAttr aAttr
;
138 aAttr
.SetProtection( nFormat
& 0x80 );
140 pDoc
->ApplyAttr( nCol
, nRow
, nTab
, aAttr
);
143 void InitPage( void )
144 { // Seitenformat initialisieren, d.h. Default-Werte von SC holen
145 //scGetPageFormat( 0, &aPage );
149 double SnumToDouble( INT16 nVal
)
151 const double pFacts
[ 8 ] = {
165 fVal
= pFacts
[ ( nVal
>> 1 ) & 0x0007 ];
166 fVal
*= ( INT16
) ( nVal
>> 4 );
169 fVal
= ( INT16
) ( nVal
>> 1 );
174 double Snum32ToDouble( UINT32 nValue
)
178 fValue
= nValue
>> 6;
179 temp
= nValue
& 0x0f;
182 if (nValue
& 0x00000010)
183 fValue
/= pow((double)10, temp
);
185 fValue
*= pow((double)10, temp
);
188 if ((nValue
& 0x00000020))
194 FormCache::FormCache( ScDocument
* pDoc1
, BYTE nNewDefaultFormat
)
195 { // Default-Format ist 'Default'
196 nDefaultFormat
= nNewDefaultFormat
;
197 pFormTable
= pDoc1
->GetFormatTable();
198 for( UINT16 nC
= 0 ; nC
< __nSize
; nC
++ )
199 bValid
[ nC
] = FALSE
;
200 eLanguage
= ScGlobal::eLnge
;
204 FormCache::~FormCache()
206 for( UINT16 nC
= 0 ; nC
< __nSize
; nC
++ )
207 delete aIdents
[ nC
].GetAttr();
211 SfxUInt32Item
* FormCache::NewAttr( BYTE nFormat
, BYTE nSt
)
213 // neues Format erzeugen
214 BYTE nL
, nH
; // Low-/High-Nibble
215 BYTE nForm
= nFormat
;
217 const sal_Char
* pFormString
= 0;
218 INT16 eType
= NUMBERFORMAT_ALL
;
221 BOOL bDefault
= FALSE
;
222 //void GenerateFormat( aFormString, eType, COUNTRY_SYSTEM, LANGUAGE_SYSTEM,
223 // BOOL bThousand, BOOL IsRed, UINT16 nPrecision, UINT16 nAnzLeading );
225 if( nForm
== 0xFF ) // Default-Format?
226 nForm
= nDefaultFormat
;
228 // Aufdroeseln in Low- und High-Nibble
230 nH
= ( nFormat
& 0xF0 ) / 16;
232 nH
&= 0x07; // Bits 4-6 'rausziehen
235 case 0x00: // Festkommaformat (fixed)
237 nIndex1
= pFormTable
->GetStandardFormat(
238 NUMBERFORMAT_NUMBER
, eLanguage
);
239 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
240 eLanguage
, FALSE
, FALSE
, nL
, 1 );
242 case 0x01: // Exponentdarstellung (scientific notation)
244 nIndex1
= pFormTable
->GetStandardFormat(
245 NUMBERFORMAT_SCIENTIFIC
, eLanguage
);
246 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
247 eLanguage
, FALSE
, FALSE
, nL
, 1 );
249 case 0x02: // Waehrungsdarstellung (currency)
251 nIndex1
= pFormTable
->GetStandardFormat(
252 NUMBERFORMAT_CURRENCY
, eLanguage
);
253 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
254 eLanguage
, FALSE
, FALSE
, nL
, 1 );
256 case 0x03: // Prozent
258 nIndex1
= pFormTable
->GetStandardFormat(
259 NUMBERFORMAT_PERCENT
, eLanguage
);
260 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
261 eLanguage
, FALSE
, FALSE
, nL
, 1 );
265 nIndex1
= pFormTable
->GetStandardFormat(
266 NUMBERFORMAT_NUMBER
, eLanguage
);
267 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
268 eLanguage
, TRUE
, FALSE
, nL
, 1 );
272 nIndex1
= pFormTable
->GetStandardFormat(
273 NUMBERFORMAT_NUMBER
, eLanguage
);
274 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
275 eLanguage
, FALSE
, FALSE
, nL
, 1 );
279 nIndex1
= pFormTable
->GetStandardFormat(
280 NUMBERFORMAT_NUMBER
, eLanguage
);
281 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
282 eLanguage
, FALSE
, FALSE
, nL
, 1 );
285 case 0x07: // Spezialformat
290 nIndex1
= pFormTable
->GetStandardFormat(
291 NUMBERFORMAT_NUMBER
, eLanguage
);
292 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
293 eLanguage
, FALSE
, TRUE
, nSt
, 1 );
295 case 0x01: // generelles Format
297 nIndex1
= pFormTable
->GetStandardFormat(
298 NUMBERFORMAT_NUMBER
, eLanguage
);
299 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
300 eLanguage
, FALSE
, FALSE
, nSt
, 1 );
302 case 0x02: // Datum: Tag, Monat, Jahr
303 //fDate;dfDayMonthYearLong;
304 eType
= NUMBERFORMAT_DATE
;
305 pFormString
= "TT.MM.JJJJ";
307 case 0x03: // Datum: Tag, Monat
308 //fDate;dfDayMonthLong;
309 eType
= NUMBERFORMAT_DATE
;
310 pFormString
= "TT.MMMM";
312 case 0x04: // Datum: Monat, Jahr
313 //fDate;dfMonthYearLong;
314 eType
= NUMBERFORMAT_DATE
;
315 pFormString
= "MM.JJJJ";
317 case 0x05: // Textformate
319 eType
= NUMBERFORMAT_TEXT
;
322 case 0x06: // versteckt
323 //wFlag |= paHideAll;bSetFormat = FALSE;
324 eType
= NUMBERFORMAT_NUMBER
;
327 case 0x07: // Time: hour, min, sec
328 //fTime;tfHourMinSec24;
329 eType
= NUMBERFORMAT_TIME
;
330 pFormString
= "HH:MM:SS";
332 case 0x08: // Time: hour, min
334 eType
= NUMBERFORMAT_TIME
;
335 pFormString
= "HH:MM";
337 case 0x09: // Date, intern INT32 1
338 //fDate;dfDayMonthYearLong;
339 eType
= NUMBERFORMAT_DATE
;
340 pFormString
= "TT.MM.JJJJ";
342 case 0x0A: // Date, intern INT32 2
343 //fDate;dfDayMonthYearLong;
344 eType
= NUMBERFORMAT_DATE
;
345 pFormString
= "TT.MM.JJJJ";
347 case 0x0B: // Time, intern INT32 1
348 //fTime;tfHourMinSec24;
349 eType
= NUMBERFORMAT_TIME
;
350 pFormString
= "HH:MM:SS";
352 case 0x0C: // Time, intern INT32 2
353 //fTime;tfHourMinSec24;
354 eType
= NUMBERFORMAT_TIME
;
355 pFormString
= "HH:MM:SS";
357 case 0x0F: // Standardeinstellung
369 nIndex1
= pFormTable
->GetStandardFormat(
370 NUMBERFORMAT_NUMBER
, eLanguage
);
371 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
372 eLanguage
, FALSE
, FALSE
, nL
, 1 );
377 // Format in Table schieben
383 aFormString
.AssignAscii( pFormString
);
386 pFormTable
->PutEntry( aFormString
, nDummy
, eType
, nHandle
, eLanguage
);
389 return new SfxUInt32Item( ATTR_VALUE_FORMAT
, ( UINT32
) nHandle
);
395 void LotusRange::MakeHash( void )
397 // 33222222222211111111110000000000
398 // 10987654321098765432109876543210
401 // **************** nRowS
402 // **************** nRowE
403 nHash
= static_cast<UINT32
>(nColStart
);
404 nHash
+= static_cast<UINT32
>(nColEnd
) << 6;
405 nHash
+= static_cast<UINT32
>(nRowStart
) << 12;
406 nHash
+= static_cast<UINT32
>(nRowEnd
) << 16;
410 LotusRange::LotusRange( SCCOL nCol
, SCROW nRow
)
412 nColStart
= nColEnd
= nCol
;
413 nRowStart
= nRowEnd
= nRow
;
419 LotusRange::LotusRange( SCCOL nCS
, SCROW nRS
, SCCOL nCE
, SCROW nRE
)
430 LotusRange::LotusRange( const LotusRange
& rCpy
)
439 LotusRangeList::LotusRangeList( void )
441 aComplRef
.InitFlags();
443 ScSingleRefData
* pSingRef
;
446 pSingRef
= &aComplRef
.Ref1
;
447 pSingRef
->nTab
= pSingRef
->nRelTab
= 0;
448 pSingRef
->SetColRel( FALSE
);
449 pSingRef
->SetRowRel( FALSE
);
450 pSingRef
->SetTabRel( TRUE
);
451 pSingRef
->SetFlag3D( FALSE
);
453 pSingRef
= &aComplRef
.Ref2
;
454 pSingRef
->nTab
= pSingRef
->nRelTab
= 0;
455 pSingRef
->SetColRel( FALSE
);
456 pSingRef
->SetRowRel( FALSE
);
457 pSingRef
->SetTabRel( TRUE
);
458 pSingRef
->SetFlag3D( FALSE
);
462 LotusRangeList::~LotusRangeList( void )
464 LotusRange
*pDel
= ( LotusRange
* ) List::First();
469 pDel
= ( LotusRange
* ) List::Next();
474 LR_ID
LotusRangeList::GetIndex( const LotusRange
&rRef
)
476 LotusRange
* pComp
= ( LotusRange
* ) List::First();
482 pComp
= ( LotusRange
* ) List::Next();
489 void LotusRangeList::Append( LotusRange
* pLR
, const String
& rName
)
491 DBG_ASSERT( pLR
, "*LotusRangeList::Append(): das wird nichts!" );
492 List::Insert( pLR
, CONTAINER_APPEND
);
494 ScTokenArray aTokArray
;
496 ScSingleRefData
* pSingRef
= &aComplRef
.Ref1
;
498 pSingRef
->nCol
= pLR
->nColStart
;
499 pSingRef
->nRow
= pLR
->nRowStart
;
501 if( pLR
->IsSingle() )
502 aTokArray
.AddSingleReference( *pSingRef
);
505 pSingRef
= &aComplRef
.Ref2
;
506 pSingRef
->nCol
= pLR
->nColEnd
;
507 pSingRef
->nRow
= pLR
->nRowEnd
;
508 aTokArray
.AddDoubleReference( aComplRef
);
511 ScRangeData
* pData
= new ScRangeData(
512 pLotusRoot
->pDoc
, rName
, aTokArray
);
514 pLotusRoot
->pScRangeName
->Insert( pData
);
516 pLR
->SetId( nIdCnt
);
524 RangeNameBufferWK3::RangeNameBufferWK3( void )
526 pScTokenArray
= new ScTokenArray
;
531 RangeNameBufferWK3::~RangeNameBufferWK3()
533 ENTRY
* pDel
= ( ENTRY
* ) List::First();
538 pDel
= ( ENTRY
* ) List::Next();
541 delete pScTokenArray
;
545 void RangeNameBufferWK3::Add( const String
& rOrgName
, const ScComplexRefData
& rCRD
)
547 String
aScName( rOrgName
);
548 ScfTools::ConvertToScDefinedName( aScName
);
550 register ENTRY
* pInsert
= new ENTRY( rOrgName
, aScName
, rCRD
);
552 List::Insert( pInsert
, CONTAINER_APPEND
);
554 pScTokenArray
->Clear();
556 register const ScSingleRefData
& rRef1
= rCRD
.Ref1
;
557 register const ScSingleRefData
& rRef2
= rCRD
.Ref2
;
559 if( rRef1
.nCol
== rRef2
.nCol
&& rRef1
.nRow
== rRef2
.nRow
&& rRef1
.nTab
== rRef2
.nTab
)
561 pScTokenArray
->AddSingleReference( rCRD
.Ref1
);
562 pInsert
->bSingleRef
= TRUE
;
566 pScTokenArray
->AddDoubleReference( rCRD
);
567 pInsert
->bSingleRef
= FALSE
;
570 ScRangeData
* pData
= new ScRangeData( pLotusRoot
->pDoc
, aScName
, *pScTokenArray
);
572 pInsert
->nRelInd
= nIntCount
;
573 pData
->SetIndex( nIntCount
);
576 pLotusRoot
->pScRangeName
->Insert( pData
);
580 BOOL
RangeNameBufferWK3::FindRel( const String
& rRef
, UINT16
& rIndex
)
582 StringHashEntry
aRef( rRef
);
584 ENTRY
* pFind
= ( ENTRY
* ) List::First();
588 if( aRef
== pFind
->aStrHashEntry
)
590 rIndex
= pFind
->nRelInd
;
593 pFind
= ( ENTRY
* ) List::Next();
600 BOOL
RangeNameBufferWK3::FindAbs( const String
& rRef
, UINT16
& rIndex
)
603 StringHashEntry
aRef( aTmp
.Erase( 0, 1 ) ); // ohne '$' suchen!
605 ENTRY
* pFind
= ( ENTRY
* ) List::First();
609 if( aRef
== pFind
->aStrHashEntry
)
611 // eventuell neuen Range Name aufbauen
613 rIndex
= pFind
->nAbsInd
;
616 ScSingleRefData
* pRef
= &pFind
->aScComplexRefDataRel
.Ref1
;
617 pScTokenArray
->Clear();
619 pRef
->SetColRel( FALSE
);
620 pRef
->SetRowRel( FALSE
);
621 pRef
->SetTabRel( TRUE
);
623 if( pFind
->bSingleRef
)
624 pScTokenArray
->AddSingleReference( *pRef
);
627 pRef
= &pFind
->aScComplexRefDataRel
.Ref2
;
628 pRef
->SetColRel( FALSE
);
629 pRef
->SetRowRel( FALSE
);
630 pRef
->SetTabRel( TRUE
);
631 pScTokenArray
->AddDoubleReference( pFind
->aScComplexRefDataRel
);
634 ScRangeData
* pData
= new ScRangeData( pLotusRoot
->pDoc
, pFind
->aScAbsName
, *pScTokenArray
);
636 rIndex
= pFind
->nAbsInd
= nIntCount
;
637 pData
->SetIndex( rIndex
);
640 pLotusRoot
->pScRangeName
->Insert( pData
);
645 pFind
= ( ENTRY
* ) List::Next();