Update ooo320-m1
[ooovba.git] / sc / source / filter / lotus / tool.cxx
blobcde6f5ac7696aa363c3e21083ed15ff08cd22c93
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tool.cxx,v $
10 * $Revision: 1.17 $
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>
43 #include "cell.hxx"
44 #include "rangenam.hxx"
45 #include "compiler.hxx"
47 #include "tool.h"
48 #include "decl.h"
49 #include "root.hxx"
50 #include "lotrange.hxx"
51 #include "namebuff.hxx"
52 #include "ftools.hxx"
54 #include <math.h>
56 #ifdef _MSC_VER
57 #pragma optimize("",off)
58 #endif
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" );
93 sal_Char cForm;
94 SvxHorJustifyItem* pJustify = NULL;
96 cForm = *pString;
98 switch( cForm )
100 case '"': // rechtsbuendig
101 pJustify = pAttrRight;
102 pString++;
103 break;
104 case '\'': // linksbuendig
105 pJustify = pAttrLeft;
106 pString++;
107 break;
108 case '^': // zentriert
109 pJustify = pAttrCenter;
110 pString++;
111 break;
112 case '|': // printer command
113 pString = NULL;
114 break;
115 case '\\': // Wiederholung
116 pJustify = pAttrRepeat;
117 pString++;
118 break;
119 default: // kenn' ich nicht!
120 pJustify = pAttrStandard;
123 if( pString )
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 ] = {
155 5000.0,
156 500.0,
157 0.05,
158 0.005,
159 0.0005,
160 0.00005,
161 0.0625,
162 0.015625 };
164 double fVal;
166 if( nVal & 0x0001 )
168 fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
169 fVal *= ( INT16 ) ( nVal >> 4 );
171 else
172 fVal = ( INT16 ) ( nVal >> 1 );
174 return fVal;
177 double Snum32ToDouble( UINT32 nValue )
179 double fValue, temp;
181 fValue = nValue >> 6;
182 temp = nValue & 0x0f;
183 if (temp)
185 if (nValue & 0x00000010)
186 fValue /= pow((double)10, temp);
187 else
188 fValue *= pow((double)10, temp);
191 if ((nValue & 0x00000020))
192 fValue = -fValue;
193 return fValue;
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;
219 String aFormString;
220 const sal_Char* pFormString = 0;
221 INT16 eType = NUMBERFORMAT_ALL;
222 UINT32 nIndex1;
223 UINT32 nHandle;
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
232 nL = nFormat & 0x0F;
233 nH = ( nFormat & 0xF0 ) / 16;
235 nH &= 0x07; // Bits 4-6 'rausziehen
236 switch( nH )
238 case 0x00: // Festkommaformat (fixed)
239 //fStandard;nL;
240 nIndex1 = pFormTable->GetStandardFormat(
241 NUMBERFORMAT_NUMBER, eLanguage );
242 pFormTable->GenerateFormat( aFormString, nIndex1,
243 eLanguage, FALSE, FALSE, nL, 1 );
244 break;
245 case 0x01: // Exponentdarstellung (scientific notation)
246 //fExponent;nL;
247 nIndex1 = pFormTable->GetStandardFormat(
248 NUMBERFORMAT_SCIENTIFIC, eLanguage );
249 pFormTable->GenerateFormat( aFormString, nIndex1,
250 eLanguage, FALSE, FALSE, nL, 1 );
251 break;
252 case 0x02: // Waehrungsdarstellung (currency)
253 //fMoney;nL;
254 nIndex1 = pFormTable->GetStandardFormat(
255 NUMBERFORMAT_CURRENCY, eLanguage );
256 pFormTable->GenerateFormat( aFormString, nIndex1,
257 eLanguage, FALSE, FALSE, nL, 1 );
258 break;
259 case 0x03: // Prozent
260 //fPercent;nL;
261 nIndex1 = pFormTable->GetStandardFormat(
262 NUMBERFORMAT_PERCENT, eLanguage );
263 pFormTable->GenerateFormat( aFormString, nIndex1,
264 eLanguage, FALSE, FALSE, nL, 1 );
265 break;
266 case 0x04: // Komma
267 //fStandard;nL;
268 nIndex1 = pFormTable->GetStandardFormat(
269 NUMBERFORMAT_NUMBER, eLanguage );
270 pFormTable->GenerateFormat( aFormString, nIndex1,
271 eLanguage, TRUE, FALSE, nL, 1 );
272 break;
273 case 0x05: // frei
274 //fStandard;nL;
275 nIndex1 = pFormTable->GetStandardFormat(
276 NUMBERFORMAT_NUMBER, eLanguage );
277 pFormTable->GenerateFormat( aFormString, nIndex1,
278 eLanguage, FALSE, FALSE, nL, 1 );
279 break;
280 case 0x06: // frei
281 //fStandard;nL;
282 nIndex1 = pFormTable->GetStandardFormat(
283 NUMBERFORMAT_NUMBER, eLanguage );
284 pFormTable->GenerateFormat( aFormString, nIndex1,
285 eLanguage, FALSE, FALSE, nL, 1 );
286 nIndex1 = 0;
287 break;
288 case 0x07: // Spezialformat
289 switch( nL )
291 case 0x00: // +/-
292 //fStandard;nSt;
293 nIndex1 = pFormTable->GetStandardFormat(
294 NUMBERFORMAT_NUMBER, eLanguage );
295 pFormTable->GenerateFormat( aFormString, nIndex1,
296 eLanguage, FALSE, TRUE, nSt, 1 );
297 break;
298 case 0x01: // generelles Format
299 //fStandard;nSt;
300 nIndex1 = pFormTable->GetStandardFormat(
301 NUMBERFORMAT_NUMBER, eLanguage );
302 pFormTable->GenerateFormat( aFormString, nIndex1,
303 eLanguage, FALSE, FALSE, nSt, 1 );
304 break;
305 case 0x02: // Datum: Tag, Monat, Jahr
306 //fDate;dfDayMonthYearLong;
307 eType = NUMBERFORMAT_DATE;
308 pFormString = "TT.MM.JJJJ";
309 break;
310 case 0x03: // Datum: Tag, Monat
311 //fDate;dfDayMonthLong;
312 eType = NUMBERFORMAT_DATE;
313 pFormString = "TT.MMMM";
314 break;
315 case 0x04: // Datum: Monat, Jahr
316 //fDate;dfMonthYearLong;
317 eType = NUMBERFORMAT_DATE;
318 pFormString = "MM.JJJJ";
319 break;
320 case 0x05: // Textformate
321 //fString;nSt;
322 eType = NUMBERFORMAT_TEXT;
323 pFormString = "@";
324 break;
325 case 0x06: // versteckt
326 //wFlag |= paHideAll;bSetFormat = FALSE;
327 eType = NUMBERFORMAT_NUMBER;
328 pFormString = "";
329 break;
330 case 0x07: // Time: hour, min, sec
331 //fTime;tfHourMinSec24;
332 eType = NUMBERFORMAT_TIME;
333 pFormString = "HH:MM:SS";
334 break;
335 case 0x08: // Time: hour, min
336 //fTime;tfHourMin24;
337 eType = NUMBERFORMAT_TIME;
338 pFormString = "HH:MM";
339 break;
340 case 0x09: // Date, intern INT32 1
341 //fDate;dfDayMonthYearLong;
342 eType = NUMBERFORMAT_DATE;
343 pFormString = "TT.MM.JJJJ";
344 break;
345 case 0x0A: // Date, intern INT32 2
346 //fDate;dfDayMonthYearLong;
347 eType = NUMBERFORMAT_DATE;
348 pFormString = "TT.MM.JJJJ";
349 break;
350 case 0x0B: // Time, intern INT32 1
351 //fTime;tfHourMinSec24;
352 eType = NUMBERFORMAT_TIME;
353 pFormString = "HH:MM:SS";
354 break;
355 case 0x0C: // Time, intern INT32 2
356 //fTime;tfHourMinSec24;
357 eType = NUMBERFORMAT_TIME;
358 pFormString = "HH:MM:SS";
359 break;
360 case 0x0F: // Standardeinstellung
361 //fStandard;nSt;
362 bDefault = TRUE;
363 break;
364 default:
365 //fStandard;nSt;
366 bDefault = TRUE;
367 break;
369 break;
370 default:
371 //fStandard;nL;
372 nIndex1 = pFormTable->GetStandardFormat(
373 NUMBERFORMAT_NUMBER, eLanguage );
374 pFormTable->GenerateFormat( aFormString, nIndex1,
375 eLanguage, FALSE, FALSE, nL, 1 );
376 nIndex1 = 0;
377 break;
380 // Format in Table schieben
381 if( bDefault )
382 nHandle = 0;
383 else
385 if( pFormString )
386 aFormString.AssignAscii( pFormString );
388 xub_StrLen nDummy;
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
402 // ******** nColS
403 // ******** nColE
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;
417 nId = ID_FAIL;
418 MakeHash();
422 LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
424 nColStart = nCS;
425 nColEnd = nCE;
426 nRowStart = nRS;
427 nRowEnd = nRE;
428 nId = ID_FAIL;
429 MakeHash();
433 LotusRange::LotusRange( const LotusRange& rCpy )
435 Copy( rCpy );
442 LotusRangeList::LotusRangeList( void )
444 aComplRef.InitFlags();
446 ScSingleRefData* pSingRef;
447 nIdCnt = 1;
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();
469 while( pDel )
471 delete pDel;
472 pDel = ( LotusRange * ) List::Next();
477 LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
479 LotusRange* pComp = ( LotusRange* ) List::First();
481 while( pComp )
483 if( *pComp == rRef )
484 return pComp->nId;
485 pComp = ( LotusRange* ) List::Next();
488 return ID_FAIL;
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 );
506 else
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 );
521 nIdCnt++;
527 RangeNameBufferWK3::RangeNameBufferWK3( void )
529 pScTokenArray = new ScTokenArray;
530 nIntCount = 1;
534 RangeNameBufferWK3::~RangeNameBufferWK3()
536 ENTRY* pDel = ( ENTRY* ) List::First();
538 while( pDel )
540 delete pDel;
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;
567 else
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 );
577 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();
589 while( pFind )
591 if( aRef == pFind->aStrHashEntry )
593 rIndex = pFind->nRelInd;
594 return TRUE;
596 pFind = ( ENTRY* ) List::Next();
599 return FALSE;
603 BOOL RangeNameBufferWK3::FindAbs( const String& rRef, UINT16& rIndex )
605 String aTmp( rRef );
606 StringHashEntry aRef( aTmp.Erase( 0, 1 ) ); // ohne '$' suchen!
608 ENTRY* pFind = ( ENTRY* ) List::First();
610 while( pFind )
612 if( aRef == pFind->aStrHashEntry )
614 // eventuell neuen Range Name aufbauen
615 if( pFind->nAbsInd )
616 rIndex = pFind->nAbsInd;
617 else
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 );
628 else
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 );
641 nIntCount++;
643 pLotusRoot->pScRangeName->Insert( pData );
646 return TRUE;
648 pFind = ( ENTRY* ) List::Next();
651 return FALSE;