bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / filter / lotus / tool.cxx
blob136e607e49f28f95f4fac8cb3d31cc5f9b677a7f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
24 #include <tools/solar.h>
26 #include "rangenam.hxx"
27 #include "compiler.hxx"
29 #include "tool.h"
30 #include "decl.h"
31 #include "root.hxx"
32 #include "lotrange.hxx"
33 #include "namebuff.hxx"
34 #include "ftools.hxx"
35 #include "stringutil.hxx"
36 #include "tokenarray.hxx"
38 #include <math.h>
40 //--------------------------------------------------------- EXTERNE VARIABLEN -
41 extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
42 extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
44 //--------------------------------------------------------- GLOBALE VARIABLEN -
45 sal_uInt8 nDefaultFormat; // -> op.cpp, Standard-Zellenformat
47 extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
48 extern ScProtectionAttr* pAttrUnprot;
49 extern SfxUInt32Item** pAttrValForms;
51 SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
52 // -> in memory.cxx initialisiert
53 ScProtectionAttr* pAttrUnprot; // -> " memory.cxx "
55 extern FormCache* pValueFormCache; // -> in memory.cxx initialisiert
56 FormCache* pValueFormCache;
58 SCCOL LotusRangeList::nEingCol;
59 SCROW LotusRangeList::nEingRow;
64 void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char* pString )
66 // Label-Format-Auswertung
67 OSL_ENSURE( pString != NULL, "PutFormString(): pString == NULL" );
68 if (!pString)
69 return;
71 sal_Char cForm;
72 SvxHorJustifyItem* pJustify = NULL;
74 cForm = *pString;
76 switch( cForm )
78 case '"': // rechtsbuendig
79 pJustify = pAttrRight;
80 pString++;
81 break;
82 case '\'': // linksbuendig
83 pJustify = pAttrLeft;
84 pString++;
85 break;
86 case '^': // zentriert
87 pJustify = pAttrCenter;
88 pString++;
89 break;
90 case '|': // printer command
91 pString = NULL;
92 break;
93 case '\\': // Wiederholung
94 pJustify = pAttrRepeat;
95 pString++;
96 break;
97 default: // kenn' ich nicht!
98 pJustify = pAttrStandard;
101 pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify );
102 ScSetStringParam aParam;
103 aParam.setTextInput();
104 pDoc->SetString(ScAddress(nCol,nRow,nTab), String(pString, pLotusRoot->eCharsetQ), &aParam);
110 void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt )
112 // PREC: nSt = Standard-Dezimalstellenanzahl
113 pDoc->ApplyAttr( nCol, nRow, nTab, *( pValueFormCache->GetAttr( nFormat, nSt ) ) );
115 ScProtectionAttr aAttr;
117 aAttr.SetProtection( nFormat & 0x80 );
119 pDoc->ApplyAttr( nCol, nRow, nTab, aAttr );
122 void InitPage( void )
123 { // Seitenformat initialisieren, d.h. Default-Werte von SC holen
124 //scGetPageFormat( 0, &aPage );
128 double SnumToDouble( sal_Int16 nVal )
130 const double pFacts[ 8 ] = {
131 5000.0,
132 500.0,
133 0.05,
134 0.005,
135 0.0005,
136 0.00005,
137 0.0625,
138 0.015625 };
140 double fVal;
142 if( nVal & 0x0001 )
144 fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
145 fVal *= ( sal_Int16 ) ( nVal >> 4 );
147 else
148 fVal = ( sal_Int16 ) ( nVal >> 1 );
150 return fVal;
153 double Snum32ToDouble( sal_uInt32 nValue )
155 double fValue, temp;
157 fValue = nValue >> 6;
158 temp = nValue & 0x0f;
159 if (temp)
161 if (nValue & 0x00000010)
162 fValue /= pow((double)10, temp);
163 else
164 fValue *= pow((double)10, temp);
167 if ((nValue & 0x00000020))
168 fValue = -fValue;
169 return fValue;
173 FormCache::FormCache( ScDocument* pDoc1, sal_uInt8 nNewDefaultFormat )
174 { // Default-Format ist 'Default'
175 nDefaultFormat = nNewDefaultFormat;
176 pFormTable = pDoc1->GetFormatTable();
177 for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
178 bValid[ nC ] = false;
179 eLanguage = ScGlobal::eLnge;
183 FormCache::~FormCache()
185 for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
186 delete aIdents[ nC ].GetAttr();
190 SfxUInt32Item* FormCache::NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt )
192 // neues Format erzeugen
193 sal_uInt8 nL, nH; // Low-/High-Nibble
194 sal_uInt8 nForm = nFormat;
195 OUString aFormString;
196 sal_Int16 eType = NUMBERFORMAT_ALL;
197 sal_uInt32 nIndex1;
198 sal_uInt32 nHandle;
199 NfIndexTableOffset eIndexTableOffset = NF_NUMERIC_START;
200 sal_Bool bDefault = false;
202 if( nForm == 0xFF ) // Default-Format?
203 nForm = nDefaultFormat;
205 // Aufdroeseln in Low- und High-Nibble
206 nL = nFormat & 0x0F;
207 nH = ( nFormat & 0xF0 ) / 16;
209 nH &= 0x07; // Bits 4-6 'rausziehen
210 switch( nH )
212 case 0x00: // Festkommaformat (fixed)
213 //fStandard;nL;
214 nIndex1 = pFormTable->GetStandardFormat(
215 NUMBERFORMAT_NUMBER, eLanguage );
216 aFormString = pFormTable->GenerateFormat(nIndex1,
217 eLanguage, false, false, nL, 1);
218 break;
219 case 0x01: // Exponentdarstellung (scientific notation)
220 //fExponent;nL;
221 nIndex1 = pFormTable->GetStandardFormat(
222 NUMBERFORMAT_SCIENTIFIC, eLanguage );
223 aFormString = pFormTable->GenerateFormat(nIndex1,
224 eLanguage, false, false, nL, 1);
225 break;
226 case 0x02: // Waehrungsdarstellung (currency)
227 //fMoney;nL;
228 nIndex1 = pFormTable->GetStandardFormat(
229 NUMBERFORMAT_CURRENCY, eLanguage );
230 aFormString = pFormTable->GenerateFormat(nIndex1,
231 eLanguage, false, false, nL, 1);
232 break;
233 case 0x03: // Prozent
234 //fPercent;nL;
235 nIndex1 = pFormTable->GetStandardFormat(
236 NUMBERFORMAT_PERCENT, eLanguage );
237 aFormString = pFormTable->GenerateFormat(nIndex1,
238 eLanguage, false, false, nL, 1);
239 break;
240 case 0x04: // Komma
241 //fStandard;nL;
242 nIndex1 = pFormTable->GetStandardFormat(
243 NUMBERFORMAT_NUMBER, eLanguage );
244 aFormString = pFormTable->GenerateFormat(nIndex1,
245 eLanguage, sal_True, false, nL, 1);
246 break;
247 case 0x05: // frei
248 //fStandard;nL;
249 nIndex1 = pFormTable->GetStandardFormat(
250 NUMBERFORMAT_NUMBER, eLanguage );
251 aFormString = pFormTable->GenerateFormat(nIndex1,
252 eLanguage, false, false, nL, 1);
253 break;
254 case 0x06: // frei
255 //fStandard;nL;
256 nIndex1 = pFormTable->GetStandardFormat(
257 NUMBERFORMAT_NUMBER, eLanguage );
258 aFormString = pFormTable->GenerateFormat(nIndex1,
259 eLanguage, false, false, nL, 1);
260 nIndex1 = 0;
261 break;
262 case 0x07: // Spezialformat
263 switch( nL )
265 case 0x00: // +/-
266 //fStandard;nSt;
267 nIndex1 = pFormTable->GetStandardFormat(
268 NUMBERFORMAT_NUMBER, eLanguage );
269 aFormString = pFormTable->GenerateFormat(nIndex1,
270 eLanguage, false, sal_True, nSt, 1);
271 break;
272 case 0x01: // generelles Format
273 //fStandard;nSt;
274 nIndex1 = pFormTable->GetStandardFormat(
275 NUMBERFORMAT_NUMBER, eLanguage );
276 aFormString = pFormTable->GenerateFormat(nIndex1,
277 eLanguage, false, false, nSt, 1);
278 break;
279 case 0x02: // Datum: Tag, Monat, Jahr
280 //fDate;dfDayMonthYearLong;
281 eType = NUMBERFORMAT_DATE;
282 eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
283 break;
284 case 0x03: // Datum: Tag, Monat
285 //fDate;dfDayMonthLong;
286 eType = NUMBERFORMAT_DATE;
287 aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_DD);
288 aFormString += pFormTable->GetDateSep(); // matches last eLanguage
289 aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_MMMM);
290 break;
291 case 0x04: // Datum: Monat, Jahr
292 //fDate;dfMonthYearLong;
293 eType = NUMBERFORMAT_DATE;
294 aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_MM);
295 aFormString += pFormTable->GetDateSep(); // matches last eLanguage
296 aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_YYYY);
297 break;
298 case 0x05: // Textformate
299 //fString;nSt;
300 eType = NUMBERFORMAT_TEXT;
301 eIndexTableOffset = NF_TEXT;
302 break;
303 case 0x06: // versteckt
304 //wFlag |= paHideAll;bSetFormat = sal_False;
305 eType = NUMBERFORMAT_NUMBER;
306 aFormString = "\"\"";
307 break;
308 case 0x07: // Time: hour, min, sec
309 //fTime;tfHourMinSec24;
310 eType = NUMBERFORMAT_TIME;
311 eIndexTableOffset = NF_TIME_HHMMSS;
312 break;
313 case 0x08: // Time: hour, min
314 //fTime;tfHourMin24;
315 eType = NUMBERFORMAT_TIME;
316 eIndexTableOffset = NF_TIME_HHMM;
317 break;
318 case 0x09: // Date, intern sal_Int32 1
319 //fDate;dfDayMonthYearLong;
320 eType = NUMBERFORMAT_DATE;
321 eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
322 break;
323 case 0x0A: // Date, intern sal_Int32 2
324 //fDate;dfDayMonthYearLong;
325 eType = NUMBERFORMAT_DATE;
326 eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
327 break;
328 case 0x0B: // Time, intern sal_Int32 1
329 //fTime;tfHourMinSec24;
330 eType = NUMBERFORMAT_TIME;
331 eIndexTableOffset = NF_TIME_HHMMSS;
332 break;
333 case 0x0C: // Time, intern sal_Int32 2
334 //fTime;tfHourMinSec24;
335 eType = NUMBERFORMAT_TIME;
336 eIndexTableOffset = NF_TIME_HHMMSS;
337 break;
338 case 0x0F: // Standardeinstellung
339 //fStandard;nSt;
340 bDefault = sal_True;
341 break;
342 default:
343 //fStandard;nSt;
344 bDefault = sal_True;
345 break;
347 break;
348 default:
349 //fStandard;nL;
350 nIndex1 = pFormTable->GetStandardFormat(
351 NUMBERFORMAT_NUMBER, eLanguage );
352 aFormString = pFormTable->GenerateFormat(nIndex1,
353 eLanguage, false, false, nL, 1);
354 nIndex1 = 0;
355 break;
358 // Format in Table schieben
359 if( bDefault )
360 nHandle = 0;
361 else if (eIndexTableOffset != NF_NUMERIC_START)
362 nHandle = pFormTable->GetFormatIndex( eIndexTableOffset, eLanguage);
363 else
365 sal_Int32 nDummy;
366 pFormTable->PutEntry( aFormString, nDummy, eType, nHandle, eLanguage );
369 return new SfxUInt32Item( ATTR_VALUE_FORMAT, ( sal_uInt32 ) nHandle );
375 void LotusRange::MakeHash( void )
377 // 33222222222211111111110000000000
378 // 10987654321098765432109876543210
379 // ******** nColS
380 // ******** nColE
381 // **************** nRowS
382 // **************** nRowE
383 nHash = static_cast<sal_uInt32>(nColStart);
384 nHash += static_cast<sal_uInt32>(nColEnd) << 6;
385 nHash += static_cast<sal_uInt32>(nRowStart) << 12;
386 nHash += static_cast<sal_uInt32>(nRowEnd ) << 16;
390 LotusRange::LotusRange( SCCOL nCol, SCROW nRow )
392 nColStart = nColEnd = nCol;
393 nRowStart = nRowEnd = nRow;
394 nId = ID_FAIL;
395 MakeHash();
399 LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
401 nColStart = nCS;
402 nColEnd = nCE;
403 nRowStart = nRS;
404 nRowEnd = nRE;
405 nId = ID_FAIL;
406 MakeHash();
410 LotusRange::LotusRange( const LotusRange& rCpy )
412 Copy( rCpy );
419 LotusRangeList::LotusRangeList( void )
421 aComplRef.InitFlags();
423 ScSingleRefData* pSingRef;
424 nIdCnt = 1;
426 pSingRef = &aComplRef.Ref1;
427 pSingRef->nTab = pSingRef->nRelTab = 0;
428 pSingRef->SetColRel( false );
429 pSingRef->SetRowRel( false );
430 pSingRef->SetTabRel( sal_True );
431 pSingRef->SetFlag3D( false );
433 pSingRef = &aComplRef.Ref2;
434 pSingRef->nTab = pSingRef->nRelTab = 0;
435 pSingRef->SetColRel( false );
436 pSingRef->SetRowRel( false );
437 pSingRef->SetTabRel( sal_True );
438 pSingRef->SetFlag3D( false );
441 LotusRangeList::~LotusRangeList ()
443 std::vector<LotusRange*>::iterator pIter;
444 for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter)
445 delete (*pIter);
448 LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
450 std::vector<LotusRange*>::iterator pIter;
451 for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter)
453 if (rRef == *(*pIter))
454 return (*pIter)->nId;
457 return ID_FAIL;
461 void LotusRangeList::Append( LotusRange* pLR, const String& rName )
463 OSL_ENSURE( pLR, "*LotusRangeList::Append(): das wird nichts!" );
464 maRanges.push_back(pLR);
466 ScTokenArray aTokArray;
468 ScSingleRefData* pSingRef = &aComplRef.Ref1;
470 pSingRef->nCol = pLR->nColStart;
471 pSingRef->nRow = pLR->nRowStart;
473 if( pLR->IsSingle() )
474 aTokArray.AddSingleReference( *pSingRef );
475 else
477 pSingRef = &aComplRef.Ref2;
478 pSingRef->nCol = pLR->nColEnd;
479 pSingRef->nRow = pLR->nRowEnd;
480 aTokArray.AddDoubleReference( aComplRef );
483 ScRangeData* pData = new ScRangeData(
484 pLotusRoot->pDoc, rName, aTokArray );
486 pLotusRoot->pScRangeName->insert( pData );
488 pLR->SetId( nIdCnt );
490 nIdCnt++;
496 RangeNameBufferWK3::RangeNameBufferWK3( void )
498 pScTokenArray = new ScTokenArray;
499 nIntCount = 1;
503 RangeNameBufferWK3::~RangeNameBufferWK3()
505 delete pScTokenArray;
509 void RangeNameBufferWK3::Add( const String& rOrgName, const ScComplexRefData& rCRD )
511 String aScName( rOrgName );
512 ScfTools::ConvertToScDefinedName( aScName );
514 Entry aInsert( rOrgName, aScName, rCRD );
516 pScTokenArray->Clear();
518 register const ScSingleRefData& rRef1 = rCRD.Ref1;
519 register const ScSingleRefData& rRef2 = rCRD.Ref2;
521 if( rRef1.nCol == rRef2.nCol && rRef1.nRow == rRef2.nRow && rRef1.nTab == rRef2.nTab )
523 pScTokenArray->AddSingleReference( rCRD.Ref1 );
524 aInsert.bSingleRef = sal_True;
526 else
528 pScTokenArray->AddDoubleReference( rCRD );
529 aInsert.bSingleRef = false;
532 ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, aScName, *pScTokenArray );
534 aInsert.nRelInd = nIntCount;
535 pData->SetIndex( nIntCount );
536 nIntCount++;
538 maEntries.push_back( aInsert );
539 pLotusRoot->pScRangeName->insert( pData );
543 sal_Bool RangeNameBufferWK3::FindRel( const String& rRef, sal_uInt16& rIndex )
545 StringHashEntry aRef( rRef );
547 std::vector<Entry>::const_iterator itr;
548 for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr )
550 if ( aRef == itr->aStrHashEntry )
552 rIndex = itr->nRelInd;
553 return true;
557 return false;
561 sal_Bool RangeNameBufferWK3::FindAbs( const String& rRef, sal_uInt16& rIndex )
563 String aTmp( rRef );
564 StringHashEntry aRef( aTmp.Erase( 0, 1 ) ); // ohne '$' suchen!
566 std::vector<Entry>::iterator itr;
567 for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr )
569 if ( aRef == itr->aStrHashEntry )
571 // eventuell neuen Range Name aufbauen
572 if( itr->nAbsInd )
573 rIndex = itr->nAbsInd;
574 else
576 ScSingleRefData* pRef = &itr->aScComplexRefDataRel.Ref1;
577 pScTokenArray->Clear();
579 pRef->SetColRel( false );
580 pRef->SetRowRel( false );
581 pRef->SetTabRel( sal_True );
583 if( itr->bSingleRef )
584 pScTokenArray->AddSingleReference( *pRef );
585 else
587 pRef = &itr->aScComplexRefDataRel.Ref2;
588 pRef->SetColRel( false );
589 pRef->SetRowRel( false );
590 pRef->SetTabRel( sal_True );
591 pScTokenArray->AddDoubleReference( itr->aScComplexRefDataRel );
594 ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, itr->aScAbsName, *pScTokenArray );
596 rIndex = itr->nAbsInd = nIntCount;
597 pData->SetIndex( rIndex );
598 nIntCount++;
600 pLotusRoot->pScRangeName->insert( pData );
603 return true;
607 return false;
611 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */