merged tag ooo/OOO330_m14
[LibreOffice.git] / sc / source / filter / lotus / tool.cxx
blob0e99b1140c2af9c94a3a29790921658ab5dcb853
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>
40 #include "cell.hxx"
41 #include "rangenam.hxx"
42 #include "compiler.hxx"
44 #include "tool.h"
45 #include "decl.h"
46 #include "root.hxx"
47 #include "lotrange.hxx"
48 #include "namebuff.hxx"
49 #include "ftools.hxx"
51 #include <math.h>
53 #ifdef _MSC_VER
54 #pragma optimize("",off)
55 #endif
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" );
90 sal_Char cForm;
91 SvxHorJustifyItem* pJustify = NULL;
93 cForm = *pString;
95 switch( cForm )
97 case '"': // rechtsbuendig
98 pJustify = pAttrRight;
99 pString++;
100 break;
101 case '\'': // linksbuendig
102 pJustify = pAttrLeft;
103 pString++;
104 break;
105 case '^': // zentriert
106 pJustify = pAttrCenter;
107 pString++;
108 break;
109 case '|': // printer command
110 pString = NULL;
111 break;
112 case '\\': // Wiederholung
113 pJustify = pAttrRepeat;
114 pString++;
115 break;
116 default: // kenn' ich nicht!
117 pJustify = pAttrStandard;
120 if( pString )
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 ] = {
152 5000.0,
153 500.0,
154 0.05,
155 0.005,
156 0.0005,
157 0.00005,
158 0.0625,
159 0.015625 };
161 double fVal;
163 if( nVal & 0x0001 )
165 fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
166 fVal *= ( INT16 ) ( nVal >> 4 );
168 else
169 fVal = ( INT16 ) ( nVal >> 1 );
171 return fVal;
174 double Snum32ToDouble( UINT32 nValue )
176 double fValue, temp;
178 fValue = nValue >> 6;
179 temp = nValue & 0x0f;
180 if (temp)
182 if (nValue & 0x00000010)
183 fValue /= pow((double)10, temp);
184 else
185 fValue *= pow((double)10, temp);
188 if ((nValue & 0x00000020))
189 fValue = -fValue;
190 return fValue;
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;
216 String aFormString;
217 const sal_Char* pFormString = 0;
218 INT16 eType = NUMBERFORMAT_ALL;
219 UINT32 nIndex1;
220 UINT32 nHandle;
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
229 nL = nFormat & 0x0F;
230 nH = ( nFormat & 0xF0 ) / 16;
232 nH &= 0x07; // Bits 4-6 'rausziehen
233 switch( nH )
235 case 0x00: // Festkommaformat (fixed)
236 //fStandard;nL;
237 nIndex1 = pFormTable->GetStandardFormat(
238 NUMBERFORMAT_NUMBER, eLanguage );
239 pFormTable->GenerateFormat( aFormString, nIndex1,
240 eLanguage, FALSE, FALSE, nL, 1 );
241 break;
242 case 0x01: // Exponentdarstellung (scientific notation)
243 //fExponent;nL;
244 nIndex1 = pFormTable->GetStandardFormat(
245 NUMBERFORMAT_SCIENTIFIC, eLanguage );
246 pFormTable->GenerateFormat( aFormString, nIndex1,
247 eLanguage, FALSE, FALSE, nL, 1 );
248 break;
249 case 0x02: // Waehrungsdarstellung (currency)
250 //fMoney;nL;
251 nIndex1 = pFormTable->GetStandardFormat(
252 NUMBERFORMAT_CURRENCY, eLanguage );
253 pFormTable->GenerateFormat( aFormString, nIndex1,
254 eLanguage, FALSE, FALSE, nL, 1 );
255 break;
256 case 0x03: // Prozent
257 //fPercent;nL;
258 nIndex1 = pFormTable->GetStandardFormat(
259 NUMBERFORMAT_PERCENT, eLanguage );
260 pFormTable->GenerateFormat( aFormString, nIndex1,
261 eLanguage, FALSE, FALSE, nL, 1 );
262 break;
263 case 0x04: // Komma
264 //fStandard;nL;
265 nIndex1 = pFormTable->GetStandardFormat(
266 NUMBERFORMAT_NUMBER, eLanguage );
267 pFormTable->GenerateFormat( aFormString, nIndex1,
268 eLanguage, TRUE, FALSE, nL, 1 );
269 break;
270 case 0x05: // frei
271 //fStandard;nL;
272 nIndex1 = pFormTable->GetStandardFormat(
273 NUMBERFORMAT_NUMBER, eLanguage );
274 pFormTable->GenerateFormat( aFormString, nIndex1,
275 eLanguage, FALSE, FALSE, nL, 1 );
276 break;
277 case 0x06: // frei
278 //fStandard;nL;
279 nIndex1 = pFormTable->GetStandardFormat(
280 NUMBERFORMAT_NUMBER, eLanguage );
281 pFormTable->GenerateFormat( aFormString, nIndex1,
282 eLanguage, FALSE, FALSE, nL, 1 );
283 nIndex1 = 0;
284 break;
285 case 0x07: // Spezialformat
286 switch( nL )
288 case 0x00: // +/-
289 //fStandard;nSt;
290 nIndex1 = pFormTable->GetStandardFormat(
291 NUMBERFORMAT_NUMBER, eLanguage );
292 pFormTable->GenerateFormat( aFormString, nIndex1,
293 eLanguage, FALSE, TRUE, nSt, 1 );
294 break;
295 case 0x01: // generelles Format
296 //fStandard;nSt;
297 nIndex1 = pFormTable->GetStandardFormat(
298 NUMBERFORMAT_NUMBER, eLanguage );
299 pFormTable->GenerateFormat( aFormString, nIndex1,
300 eLanguage, FALSE, FALSE, nSt, 1 );
301 break;
302 case 0x02: // Datum: Tag, Monat, Jahr
303 //fDate;dfDayMonthYearLong;
304 eType = NUMBERFORMAT_DATE;
305 pFormString = "TT.MM.JJJJ";
306 break;
307 case 0x03: // Datum: Tag, Monat
308 //fDate;dfDayMonthLong;
309 eType = NUMBERFORMAT_DATE;
310 pFormString = "TT.MMMM";
311 break;
312 case 0x04: // Datum: Monat, Jahr
313 //fDate;dfMonthYearLong;
314 eType = NUMBERFORMAT_DATE;
315 pFormString = "MM.JJJJ";
316 break;
317 case 0x05: // Textformate
318 //fString;nSt;
319 eType = NUMBERFORMAT_TEXT;
320 pFormString = "@";
321 break;
322 case 0x06: // versteckt
323 //wFlag |= paHideAll;bSetFormat = FALSE;
324 eType = NUMBERFORMAT_NUMBER;
325 pFormString = "";
326 break;
327 case 0x07: // Time: hour, min, sec
328 //fTime;tfHourMinSec24;
329 eType = NUMBERFORMAT_TIME;
330 pFormString = "HH:MM:SS";
331 break;
332 case 0x08: // Time: hour, min
333 //fTime;tfHourMin24;
334 eType = NUMBERFORMAT_TIME;
335 pFormString = "HH:MM";
336 break;
337 case 0x09: // Date, intern INT32 1
338 //fDate;dfDayMonthYearLong;
339 eType = NUMBERFORMAT_DATE;
340 pFormString = "TT.MM.JJJJ";
341 break;
342 case 0x0A: // Date, intern INT32 2
343 //fDate;dfDayMonthYearLong;
344 eType = NUMBERFORMAT_DATE;
345 pFormString = "TT.MM.JJJJ";
346 break;
347 case 0x0B: // Time, intern INT32 1
348 //fTime;tfHourMinSec24;
349 eType = NUMBERFORMAT_TIME;
350 pFormString = "HH:MM:SS";
351 break;
352 case 0x0C: // Time, intern INT32 2
353 //fTime;tfHourMinSec24;
354 eType = NUMBERFORMAT_TIME;
355 pFormString = "HH:MM:SS";
356 break;
357 case 0x0F: // Standardeinstellung
358 //fStandard;nSt;
359 bDefault = TRUE;
360 break;
361 default:
362 //fStandard;nSt;
363 bDefault = TRUE;
364 break;
366 break;
367 default:
368 //fStandard;nL;
369 nIndex1 = pFormTable->GetStandardFormat(
370 NUMBERFORMAT_NUMBER, eLanguage );
371 pFormTable->GenerateFormat( aFormString, nIndex1,
372 eLanguage, FALSE, FALSE, nL, 1 );
373 nIndex1 = 0;
374 break;
377 // Format in Table schieben
378 if( bDefault )
379 nHandle = 0;
380 else
382 if( pFormString )
383 aFormString.AssignAscii( pFormString );
385 xub_StrLen nDummy;
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
399 // ******** nColS
400 // ******** nColE
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;
414 nId = ID_FAIL;
415 MakeHash();
419 LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
421 nColStart = nCS;
422 nColEnd = nCE;
423 nRowStart = nRS;
424 nRowEnd = nRE;
425 nId = ID_FAIL;
426 MakeHash();
430 LotusRange::LotusRange( const LotusRange& rCpy )
432 Copy( rCpy );
439 LotusRangeList::LotusRangeList( void )
441 aComplRef.InitFlags();
443 ScSingleRefData* pSingRef;
444 nIdCnt = 1;
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();
466 while( pDel )
468 delete pDel;
469 pDel = ( LotusRange * ) List::Next();
474 LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
476 LotusRange* pComp = ( LotusRange* ) List::First();
478 while( pComp )
480 if( *pComp == rRef )
481 return pComp->nId;
482 pComp = ( LotusRange* ) List::Next();
485 return ID_FAIL;
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 );
503 else
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 );
518 nIdCnt++;
524 RangeNameBufferWK3::RangeNameBufferWK3( void )
526 pScTokenArray = new ScTokenArray;
527 nIntCount = 1;
531 RangeNameBufferWK3::~RangeNameBufferWK3()
533 ENTRY* pDel = ( ENTRY* ) List::First();
535 while( pDel )
537 delete pDel;
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;
564 else
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 );
574 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();
586 while( pFind )
588 if( aRef == pFind->aStrHashEntry )
590 rIndex = pFind->nRelInd;
591 return TRUE;
593 pFind = ( ENTRY* ) List::Next();
596 return FALSE;
600 BOOL RangeNameBufferWK3::FindAbs( const String& rRef, UINT16& rIndex )
602 String aTmp( rRef );
603 StringHashEntry aRef( aTmp.Erase( 0, 1 ) ); // ohne '$' suchen!
605 ENTRY* pFind = ( ENTRY* ) List::First();
607 while( pFind )
609 if( aRef == pFind->aStrHashEntry )
611 // eventuell neuen Range Name aufbauen
612 if( pFind->nAbsInd )
613 rIndex = pFind->nAbsInd;
614 else
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 );
625 else
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 );
638 nIntCount++;
640 pLotusRoot->pScRangeName->Insert( pData );
643 return TRUE;
645 pFind = ( ENTRY* ) List::Next();
648 return FALSE;