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: tool.cxx,v $
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"
36 //------------------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/algitem.hxx>
40 #include <svtools/zforlist.hxx>
41 #include <tools/solar.h>
44 #include "rangenam.hxx"
45 #include "compiler.hxx"
50 #include "lotrange.hxx"
51 #include "namebuff.hxx"
57 #pragma optimize("",off)
60 //--------------------------------------------------------- EXTERNE VARIABLEN -
61 extern WKTYP eTyp
; // -> filter.cxx, aktueller Dateityp
62 extern sal_Char
* pDummy2
; // -> memory.cxx
63 extern ScDocument
* pDoc
; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
64 extern CharSet eCharNach
; // -> filter.cxx, Zeichenkonvertierung von->nach
66 extern BOOL bFormInit
; // -> memory.cxx, fuer GetFormHandle()
68 //--------------------------------------------------------- GLOBALE VARIABLEN -
69 BYTE nDefaultFormat
; // -> op.cpp, Standard-Zellenformat
71 extern SvxHorJustifyItem
*pAttrRight
, *pAttrLeft
, *pAttrCenter
, *pAttrRepeat
, *pAttrStandard
;
72 extern ScProtectionAttr
* pAttrUnprot
;
73 extern SfxUInt32Item
** pAttrValForms
;
75 SvxHorJustifyItem
*pAttrRight
, *pAttrLeft
, *pAttrCenter
, *pAttrRepeat
, *pAttrStandard
;
76 // -> in memory.cxx initialisiert
77 ScProtectionAttr
* pAttrUnprot
; // -> " memory.cxx "
79 extern FormCache
* pValueFormCache
; // -> in memory.cxx initialisiert
80 FormCache
* pValueFormCache
;
82 SCCOL
LotusRangeList::nEingCol
;
83 SCROW
LotusRangeList::nEingRow
;
88 void PutFormString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_Char
* pString
)
90 // Label-Format-Auswertung
91 DBG_ASSERT( pString
!= NULL
, "PutFormString(): pString == NULL" );
94 SvxHorJustifyItem
* pJustify
= NULL
;
100 case '"': // rechtsbuendig
101 pJustify
= pAttrRight
;
104 case '\'': // linksbuendig
105 pJustify
= pAttrLeft
;
108 case '^': // zentriert
109 pJustify
= pAttrCenter
;
112 case '|': // printer command
115 case '\\': // Wiederholung
116 pJustify
= pAttrRepeat
;
119 default: // kenn' ich nicht!
120 pJustify
= pAttrStandard
;
125 pDoc
->ApplyAttr( nCol
, nRow
, nTab
, *pJustify
);
126 ScStringCell
* pZelle
= new ScStringCell( String( pString
, pLotusRoot
->eCharsetQ
) );
127 pDoc
->PutCell( nCol
, nRow
, nTab
, pZelle
, ( BOOL
) TRUE
);
134 void SetFormat( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, BYTE nFormat
, BYTE nSt
)
136 // PREC: nSt = Standard-Dezimalstellenanzahl
137 pDoc
->ApplyAttr( nCol
, nRow
, nTab
, *( pValueFormCache
->GetAttr( nFormat
, nSt
) ) );
139 ScProtectionAttr aAttr
;
141 aAttr
.SetProtection( nFormat
& 0x80 );
143 pDoc
->ApplyAttr( nCol
, nRow
, nTab
, aAttr
);
146 void InitPage( void )
147 { // Seitenformat initialisieren, d.h. Default-Werte von SC holen
148 //scGetPageFormat( 0, &aPage );
152 double SnumToDouble( INT16 nVal
)
154 const double pFacts
[ 8 ] = {
168 fVal
= pFacts
[ ( nVal
>> 1 ) & 0x0007 ];
169 fVal
*= ( INT16
) ( nVal
>> 4 );
172 fVal
= ( INT16
) ( nVal
>> 1 );
177 double Snum32ToDouble( UINT32 nValue
)
181 fValue
= nValue
>> 6;
182 temp
= nValue
& 0x0f;
185 if (nValue
& 0x00000010)
186 fValue
/= pow((double)10, temp
);
188 fValue
*= pow((double)10, temp
);
191 if ((nValue
& 0x00000020))
197 FormCache::FormCache( ScDocument
* pDoc1
, BYTE nNewDefaultFormat
)
198 { // Default-Format ist 'Default'
199 nDefaultFormat
= nNewDefaultFormat
;
200 pFormTable
= pDoc1
->GetFormatTable();
201 for( UINT16 nC
= 0 ; nC
< __nSize
; nC
++ )
202 bValid
[ nC
] = FALSE
;
203 eLanguage
= ScGlobal::eLnge
;
207 FormCache::~FormCache()
209 for( UINT16 nC
= 0 ; nC
< __nSize
; nC
++ )
210 delete aIdents
[ nC
].GetAttr();
214 SfxUInt32Item
* FormCache::NewAttr( BYTE nFormat
, BYTE nSt
)
216 // neues Format erzeugen
217 BYTE nL
, nH
; // Low-/High-Nibble
218 BYTE nForm
= nFormat
;
220 const sal_Char
* pFormString
= 0;
221 INT16 eType
= NUMBERFORMAT_ALL
;
224 BOOL bDefault
= FALSE
;
225 //void GenerateFormat( aFormString, eType, COUNTRY_SYSTEM, LANGUAGE_SYSTEM,
226 // BOOL bThousand, BOOL IsRed, UINT16 nPrecision, UINT16 nAnzLeading );
228 if( nForm
== 0xFF ) // Default-Format?
229 nForm
= nDefaultFormat
;
231 // Aufdroeseln in Low- und High-Nibble
233 nH
= ( nFormat
& 0xF0 ) / 16;
235 nH
&= 0x07; // Bits 4-6 'rausziehen
238 case 0x00: // Festkommaformat (fixed)
240 nIndex1
= pFormTable
->GetStandardFormat(
241 NUMBERFORMAT_NUMBER
, eLanguage
);
242 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
243 eLanguage
, FALSE
, FALSE
, nL
, 1 );
245 case 0x01: // Exponentdarstellung (scientific notation)
247 nIndex1
= pFormTable
->GetStandardFormat(
248 NUMBERFORMAT_SCIENTIFIC
, eLanguage
);
249 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
250 eLanguage
, FALSE
, FALSE
, nL
, 1 );
252 case 0x02: // Waehrungsdarstellung (currency)
254 nIndex1
= pFormTable
->GetStandardFormat(
255 NUMBERFORMAT_CURRENCY
, eLanguage
);
256 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
257 eLanguage
, FALSE
, FALSE
, nL
, 1 );
259 case 0x03: // Prozent
261 nIndex1
= pFormTable
->GetStandardFormat(
262 NUMBERFORMAT_PERCENT
, eLanguage
);
263 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
264 eLanguage
, FALSE
, FALSE
, nL
, 1 );
268 nIndex1
= pFormTable
->GetStandardFormat(
269 NUMBERFORMAT_NUMBER
, eLanguage
);
270 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
271 eLanguage
, TRUE
, FALSE
, nL
, 1 );
275 nIndex1
= pFormTable
->GetStandardFormat(
276 NUMBERFORMAT_NUMBER
, eLanguage
);
277 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
278 eLanguage
, FALSE
, FALSE
, nL
, 1 );
282 nIndex1
= pFormTable
->GetStandardFormat(
283 NUMBERFORMAT_NUMBER
, eLanguage
);
284 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
285 eLanguage
, FALSE
, FALSE
, nL
, 1 );
288 case 0x07: // Spezialformat
293 nIndex1
= pFormTable
->GetStandardFormat(
294 NUMBERFORMAT_NUMBER
, eLanguage
);
295 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
296 eLanguage
, FALSE
, TRUE
, nSt
, 1 );
298 case 0x01: // generelles Format
300 nIndex1
= pFormTable
->GetStandardFormat(
301 NUMBERFORMAT_NUMBER
, eLanguage
);
302 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
303 eLanguage
, FALSE
, FALSE
, nSt
, 1 );
305 case 0x02: // Datum: Tag, Monat, Jahr
306 //fDate;dfDayMonthYearLong;
307 eType
= NUMBERFORMAT_DATE
;
308 pFormString
= "TT.MM.JJJJ";
310 case 0x03: // Datum: Tag, Monat
311 //fDate;dfDayMonthLong;
312 eType
= NUMBERFORMAT_DATE
;
313 pFormString
= "TT.MMMM";
315 case 0x04: // Datum: Monat, Jahr
316 //fDate;dfMonthYearLong;
317 eType
= NUMBERFORMAT_DATE
;
318 pFormString
= "MM.JJJJ";
320 case 0x05: // Textformate
322 eType
= NUMBERFORMAT_TEXT
;
325 case 0x06: // versteckt
326 //wFlag |= paHideAll;bSetFormat = FALSE;
327 eType
= NUMBERFORMAT_NUMBER
;
330 case 0x07: // Time: hour, min, sec
331 //fTime;tfHourMinSec24;
332 eType
= NUMBERFORMAT_TIME
;
333 pFormString
= "HH:MM:SS";
335 case 0x08: // Time: hour, min
337 eType
= NUMBERFORMAT_TIME
;
338 pFormString
= "HH:MM";
340 case 0x09: // Date, intern INT32 1
341 //fDate;dfDayMonthYearLong;
342 eType
= NUMBERFORMAT_DATE
;
343 pFormString
= "TT.MM.JJJJ";
345 case 0x0A: // Date, intern INT32 2
346 //fDate;dfDayMonthYearLong;
347 eType
= NUMBERFORMAT_DATE
;
348 pFormString
= "TT.MM.JJJJ";
350 case 0x0B: // Time, intern INT32 1
351 //fTime;tfHourMinSec24;
352 eType
= NUMBERFORMAT_TIME
;
353 pFormString
= "HH:MM:SS";
355 case 0x0C: // Time, intern INT32 2
356 //fTime;tfHourMinSec24;
357 eType
= NUMBERFORMAT_TIME
;
358 pFormString
= "HH:MM:SS";
360 case 0x0F: // Standardeinstellung
372 nIndex1
= pFormTable
->GetStandardFormat(
373 NUMBERFORMAT_NUMBER
, eLanguage
);
374 pFormTable
->GenerateFormat( aFormString
, nIndex1
,
375 eLanguage
, FALSE
, FALSE
, nL
, 1 );
380 // Format in Table schieben
386 aFormString
.AssignAscii( pFormString
);
389 pFormTable
->PutEntry( aFormString
, nDummy
, eType
, nHandle
, eLanguage
);
392 return new SfxUInt32Item( ATTR_VALUE_FORMAT
, ( UINT32
) nHandle
);
398 void LotusRange::MakeHash( void )
400 // 33222222222211111111110000000000
401 // 10987654321098765432109876543210
404 // **************** nRowS
405 // **************** nRowE
406 nHash
= static_cast<UINT32
>(nColStart
);
407 nHash
+= static_cast<UINT32
>(nColEnd
) << 6;
408 nHash
+= static_cast<UINT32
>(nRowStart
) << 12;
409 nHash
+= static_cast<UINT32
>(nRowEnd
) << 16;
413 LotusRange::LotusRange( SCCOL nCol
, SCROW nRow
)
415 nColStart
= nColEnd
= nCol
;
416 nRowStart
= nRowEnd
= nRow
;
422 LotusRange::LotusRange( SCCOL nCS
, SCROW nRS
, SCCOL nCE
, SCROW nRE
)
433 LotusRange::LotusRange( const LotusRange
& rCpy
)
442 LotusRangeList::LotusRangeList( void )
444 aComplRef
.InitFlags();
446 ScSingleRefData
* pSingRef
;
449 pSingRef
= &aComplRef
.Ref1
;
450 pSingRef
->nTab
= pSingRef
->nRelTab
= 0;
451 pSingRef
->SetColRel( FALSE
);
452 pSingRef
->SetRowRel( FALSE
);
453 pSingRef
->SetTabRel( TRUE
);
454 pSingRef
->SetFlag3D( FALSE
);
456 pSingRef
= &aComplRef
.Ref2
;
457 pSingRef
->nTab
= pSingRef
->nRelTab
= 0;
458 pSingRef
->SetColRel( FALSE
);
459 pSingRef
->SetRowRel( FALSE
);
460 pSingRef
->SetTabRel( TRUE
);
461 pSingRef
->SetFlag3D( FALSE
);
465 LotusRangeList::~LotusRangeList( void )
467 LotusRange
*pDel
= ( LotusRange
* ) List::First();
472 pDel
= ( LotusRange
* ) List::Next();
477 LR_ID
LotusRangeList::GetIndex( const LotusRange
&rRef
)
479 LotusRange
* pComp
= ( LotusRange
* ) List::First();
485 pComp
= ( LotusRange
* ) List::Next();
492 void LotusRangeList::Append( LotusRange
* pLR
, const String
& rName
)
494 DBG_ASSERT( pLR
, "*LotusRangeList::Append(): das wird nichts!" );
495 List::Insert( pLR
, CONTAINER_APPEND
);
497 ScTokenArray aTokArray
;
499 ScSingleRefData
* pSingRef
= &aComplRef
.Ref1
;
501 pSingRef
->nCol
= pLR
->nColStart
;
502 pSingRef
->nRow
= pLR
->nRowStart
;
504 if( pLR
->IsSingle() )
505 aTokArray
.AddSingleReference( *pSingRef
);
508 pSingRef
= &aComplRef
.Ref2
;
509 pSingRef
->nCol
= pLR
->nColEnd
;
510 pSingRef
->nRow
= pLR
->nRowEnd
;
511 aTokArray
.AddDoubleReference( aComplRef
);
514 ScRangeData
* pData
= new ScRangeData(
515 pLotusRoot
->pDoc
, rName
, aTokArray
);
517 pLotusRoot
->pScRangeName
->Insert( pData
);
519 pLR
->SetId( nIdCnt
);
527 RangeNameBufferWK3::RangeNameBufferWK3( void )
529 pScTokenArray
= new ScTokenArray
;
534 RangeNameBufferWK3::~RangeNameBufferWK3()
536 ENTRY
* pDel
= ( ENTRY
* ) List::First();
541 pDel
= ( ENTRY
* ) List::Next();
544 delete pScTokenArray
;
548 void RangeNameBufferWK3::Add( const String
& rOrgName
, const ScComplexRefData
& rCRD
)
550 String
aScName( rOrgName
);
551 ScfTools::ConvertToScDefinedName( aScName
);
553 register ENTRY
* pInsert
= new ENTRY( rOrgName
, aScName
, rCRD
);
555 List::Insert( pInsert
, CONTAINER_APPEND
);
557 pScTokenArray
->Clear();
559 register const ScSingleRefData
& rRef1
= rCRD
.Ref1
;
560 register const ScSingleRefData
& rRef2
= rCRD
.Ref2
;
562 if( rRef1
.nCol
== rRef2
.nCol
&& rRef1
.nRow
== rRef2
.nRow
&& rRef1
.nTab
== rRef2
.nTab
)
564 pScTokenArray
->AddSingleReference( rCRD
.Ref1
);
565 pInsert
->bSingleRef
= TRUE
;
569 pScTokenArray
->AddDoubleReference( rCRD
);
570 pInsert
->bSingleRef
= FALSE
;
573 ScRangeData
* pData
= new ScRangeData( pLotusRoot
->pDoc
, aScName
, *pScTokenArray
);
575 pInsert
->nRelInd
= nIntCount
;
576 pData
->SetIndex( nIntCount
);
579 pLotusRoot
->pScRangeName
->Insert( pData
);
583 BOOL
RangeNameBufferWK3::FindRel( const String
& rRef
, UINT16
& rIndex
)
585 StringHashEntry
aRef( rRef
);
587 ENTRY
* pFind
= ( ENTRY
* ) List::First();
591 if( aRef
== pFind
->aStrHashEntry
)
593 rIndex
= pFind
->nRelInd
;
596 pFind
= ( ENTRY
* ) List::Next();
603 BOOL
RangeNameBufferWK3::FindAbs( const String
& rRef
, UINT16
& rIndex
)
606 StringHashEntry
aRef( aTmp
.Erase( 0, 1 ) ); // ohne '$' suchen!
608 ENTRY
* pFind
= ( ENTRY
* ) List::First();
612 if( aRef
== pFind
->aStrHashEntry
)
614 // eventuell neuen Range Name aufbauen
616 rIndex
= pFind
->nAbsInd
;
619 ScSingleRefData
* pRef
= &pFind
->aScComplexRefDataRel
.Ref1
;
620 pScTokenArray
->Clear();
622 pRef
->SetColRel( FALSE
);
623 pRef
->SetRowRel( FALSE
);
624 pRef
->SetTabRel( TRUE
);
626 if( pFind
->bSingleRef
)
627 pScTokenArray
->AddSingleReference( *pRef
);
630 pRef
= &pFind
->aScComplexRefDataRel
.Ref2
;
631 pRef
->SetColRel( FALSE
);
632 pRef
->SetRowRel( FALSE
);
633 pRef
->SetTabRel( TRUE
);
634 pScTokenArray
->AddDoubleReference( pFind
->aScComplexRefDataRel
);
637 ScRangeData
* pData
= new ScRangeData( pLotusRoot
->pDoc
, pFind
->aScAbsName
, *pScTokenArray
);
639 rIndex
= pFind
->nAbsInd
= nIntCount
;
640 pData
->SetIndex( rIndex
);
643 pLotusRoot
->pScRangeName
->Insert( pData
);
648 pFind
= ( ENTRY
* ) List::Next();