Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "scitems.hxx"
21 : #include <svx/algitem.hxx>
22 : #include <editeng/justifyitem.hxx>
23 : #include <svl/zforlist.hxx>
24 :
25 : #include "rangenam.hxx"
26 : #include "compiler.hxx"
27 :
28 : #include "tool.h"
29 : #include "decl.h"
30 : #include "root.hxx"
31 : #include "lotrange.hxx"
32 : #include "namebuff.hxx"
33 : #include "ftools.hxx"
34 : #include "stringutil.hxx"
35 : #include "tokenarray.hxx"
36 :
37 : #include <math.h>
38 :
39 : // External variable
40 : extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
41 : extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
42 :
43 : // Global variable
44 : sal_uInt8 nDefaultFormat; // -> op.cpp, Standard-Zellenformat
45 :
46 : extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
47 : extern ScProtectionAttr* pAttrUnprot;
48 : extern SfxUInt32Item** pAttrValForms;
49 :
50 : SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
51 : // -> in memory.cxx initialisiert
52 : ScProtectionAttr* pAttrUnprot; // -> " memory.cxx "
53 :
54 : extern FormCache* pValueFormCache; // -> in memory.cxx initialisiert
55 : FormCache* pValueFormCache;
56 :
57 : SCCOL LotusRangeList::nEingCol;
58 : SCROW LotusRangeList::nEingRow;
59 :
60 0 : void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char* pString )
61 : {
62 : // Label-Format-Auswertung
63 : OSL_ENSURE( pString != NULL, "PutFormString(): pString == NULL" );
64 0 : if (!pString)
65 0 : return;
66 :
67 : sal_Char cForm;
68 0 : SvxHorJustifyItem* pJustify = NULL;
69 :
70 0 : cForm = *pString;
71 :
72 0 : switch( cForm )
73 : {
74 : case '"': // rechtsbuendig
75 0 : pJustify = pAttrRight;
76 0 : pString++;
77 0 : break;
78 : case '\'': // linksbuendig
79 0 : pJustify = pAttrLeft;
80 0 : pString++;
81 0 : break;
82 : case '^': // zentriert
83 0 : pJustify = pAttrCenter;
84 0 : pString++;
85 0 : break;
86 : case '|': // printer command
87 0 : pString = NULL;
88 0 : break;
89 : case '\\': // Wiederholung
90 0 : pJustify = pAttrRepeat;
91 0 : pString++;
92 0 : break;
93 : default: // kenn' ich nicht!
94 0 : pJustify = pAttrStandard;
95 : }
96 :
97 0 : if (!pString)
98 0 : return;
99 :
100 0 : pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify );
101 0 : ScSetStringParam aParam;
102 0 : aParam.setTextInput();
103 0 : pDoc->SetString(ScAddress(nCol,nRow,nTab), OUString(pString, strlen(pString), pLotusRoot->eCharsetQ), &aParam);
104 : }
105 :
106 0 : void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt )
107 : {
108 : // PREC: nSt = Standard-Dezimalstellenanzahl
109 0 : pDoc->ApplyAttr( nCol, nRow, nTab, *( pValueFormCache->GetAttr( nFormat, nSt ) ) );
110 :
111 0 : ScProtectionAttr aAttr;
112 :
113 0 : aAttr.SetProtection( nFormat & 0x80 );
114 :
115 0 : pDoc->ApplyAttr( nCol, nRow, nTab, aAttr );
116 0 : }
117 :
118 0 : void InitPage( void )
119 : { // Seitenformat initialisieren, d.h. Default-Werte von SC holen
120 : //scGetPageFormat( 0, &aPage );
121 0 : }
122 :
123 0 : double SnumToDouble( sal_Int16 nVal )
124 : {
125 : const double pFacts[ 8 ] = {
126 : 5000.0,
127 : 500.0,
128 : 0.05,
129 : 0.005,
130 : 0.0005,
131 : 0.00005,
132 : 0.0625,
133 0 : 0.015625 };
134 :
135 : double fVal;
136 :
137 0 : if( nVal & 0x0001 )
138 : {
139 0 : fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
140 0 : fVal *= ( sal_Int16 ) ( nVal >> 4 );
141 : }
142 : else
143 0 : fVal = ( sal_Int16 ) ( nVal >> 1 );
144 :
145 0 : return fVal;
146 : }
147 :
148 0 : double Snum32ToDouble( sal_uInt32 nValue )
149 : {
150 : double fValue, temp;
151 :
152 0 : fValue = nValue >> 6;
153 0 : temp = nValue & 0x0f;
154 0 : if (temp)
155 : {
156 0 : if (nValue & 0x00000010)
157 0 : fValue /= pow((double)10, temp);
158 : else
159 0 : fValue *= pow((double)10, temp);
160 : }
161 :
162 0 : if ((nValue & 0x00000020))
163 0 : fValue = -fValue;
164 0 : return fValue;
165 : }
166 :
167 0 : FormCache::FormCache( ScDocument* pDoc1, sal_uInt8 nNewDefaultFormat )
168 0 : : nIndex(0)
169 : { // Default-Format ist 'Default'
170 0 : nDefaultFormat = nNewDefaultFormat;
171 0 : pFormTable = pDoc1->GetFormatTable();
172 0 : for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
173 0 : bValid[ nC ] = false;
174 0 : eLanguage = ScGlobal::eLnge;
175 0 : }
176 :
177 0 : FormCache::~FormCache()
178 : {
179 0 : for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
180 0 : delete aIdents[ nC ].GetAttr();
181 0 : }
182 :
183 0 : SfxUInt32Item* FormCache::NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt )
184 : {
185 : // neues Format erzeugen
186 : sal_uInt8 nL, nH; // Low-/High-Nibble
187 0 : sal_uInt8 nForm = nFormat;
188 0 : OUString aFormString;
189 0 : sal_Int16 eType = NUMBERFORMAT_ALL;
190 : sal_uInt32 nIndex1;
191 : sal_uInt32 nHandle;
192 0 : NfIndexTableOffset eIndexTableOffset = NF_NUMERIC_START;
193 0 : sal_Bool bDefault = false;
194 :
195 0 : if( nForm == 0xFF ) // Default-Format?
196 0 : nForm = nDefaultFormat;
197 :
198 : // Aufdroeseln in Low- und High-Nibble
199 0 : nL = nFormat & 0x0F;
200 0 : nH = ( nFormat & 0xF0 ) / 16;
201 :
202 0 : nH &= 0x07; // Bits 4-6 'rausziehen
203 0 : switch( nH )
204 : {
205 : case 0x00: // Festkommaformat (fixed)
206 : //fStandard;nL;
207 : nIndex1 = pFormTable->GetStandardFormat(
208 0 : NUMBERFORMAT_NUMBER, eLanguage );
209 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
210 0 : eLanguage, false, false, nL, 1);
211 0 : break;
212 : case 0x01: // Exponentdarstellung (scientific notation)
213 : //fExponent;nL;
214 : nIndex1 = pFormTable->GetStandardFormat(
215 0 : NUMBERFORMAT_SCIENTIFIC, eLanguage );
216 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
217 0 : eLanguage, false, false, nL, 1);
218 0 : break;
219 : case 0x02: // Waehrungsdarstellung (currency)
220 : //fMoney;nL;
221 : nIndex1 = pFormTable->GetStandardFormat(
222 0 : NUMBERFORMAT_CURRENCY, eLanguage );
223 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
224 0 : eLanguage, false, false, nL, 1);
225 0 : break;
226 : case 0x03: // Prozent
227 : //fPercent;nL;
228 : nIndex1 = pFormTable->GetStandardFormat(
229 0 : NUMBERFORMAT_PERCENT, eLanguage );
230 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
231 0 : eLanguage, false, false, nL, 1);
232 0 : break;
233 : case 0x04: // Komma
234 : //fStandard;nL;
235 : nIndex1 = pFormTable->GetStandardFormat(
236 0 : NUMBERFORMAT_NUMBER, eLanguage );
237 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
238 0 : eLanguage, true, false, nL, 1);
239 0 : break;
240 : case 0x05: // frei
241 : //fStandard;nL;
242 : nIndex1 = pFormTable->GetStandardFormat(
243 0 : NUMBERFORMAT_NUMBER, eLanguage );
244 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
245 0 : eLanguage, false, false, nL, 1);
246 0 : break;
247 : case 0x06: // frei
248 : //fStandard;nL;
249 : nIndex1 = pFormTable->GetStandardFormat(
250 0 : NUMBERFORMAT_NUMBER, eLanguage );
251 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
252 0 : eLanguage, false, false, nL, 1);
253 0 : nIndex1 = 0;
254 0 : break;
255 : case 0x07: // Spezialformat
256 0 : switch( nL )
257 : {
258 : case 0x00: // +/-
259 : //fStandard;nSt;
260 : nIndex1 = pFormTable->GetStandardFormat(
261 0 : NUMBERFORMAT_NUMBER, eLanguage );
262 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
263 0 : eLanguage, false, true, nSt, 1);
264 0 : break;
265 : case 0x01: // generelles Format
266 : //fStandard;nSt;
267 : nIndex1 = pFormTable->GetStandardFormat(
268 0 : NUMBERFORMAT_NUMBER, eLanguage );
269 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
270 0 : eLanguage, false, false, nSt, 1);
271 0 : break;
272 : case 0x02: // Datum: Tag, Monat, Jahr
273 : //fDate;dfDayMonthYearLong;
274 0 : eType = NUMBERFORMAT_DATE;
275 0 : eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
276 0 : break;
277 : case 0x03: // Datum: Tag, Monat
278 : //fDate;dfDayMonthLong;
279 0 : eType = NUMBERFORMAT_DATE;
280 0 : aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_DD);
281 0 : aFormString += pFormTable->GetDateSep(); // matches last eLanguage
282 0 : aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_MMMM);
283 0 : break;
284 : case 0x04: // Datum: Monat, Jahr
285 : //fDate;dfMonthYearLong;
286 0 : eType = NUMBERFORMAT_DATE;
287 0 : aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_MM);
288 0 : aFormString += pFormTable->GetDateSep(); // matches last eLanguage
289 0 : aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_YYYY);
290 0 : break;
291 : case 0x05: // Textformate
292 : //fString;nSt;
293 0 : eType = NUMBERFORMAT_TEXT;
294 0 : eIndexTableOffset = NF_TEXT;
295 0 : break;
296 : case 0x06: // versteckt
297 : //wFlag |= paHideAll;bSetFormat = sal_False;
298 0 : eType = NUMBERFORMAT_NUMBER;
299 0 : aFormString = "\"\"";
300 0 : break;
301 : case 0x07: // Time: hour, min, sec
302 : //fTime;tfHourMinSec24;
303 0 : eType = NUMBERFORMAT_TIME;
304 0 : eIndexTableOffset = NF_TIME_HHMMSS;
305 0 : break;
306 : case 0x08: // Time: hour, min
307 : //fTime;tfHourMin24;
308 0 : eType = NUMBERFORMAT_TIME;
309 0 : eIndexTableOffset = NF_TIME_HHMM;
310 0 : break;
311 : case 0x09: // Date, intern sal_Int32 1
312 : //fDate;dfDayMonthYearLong;
313 0 : eType = NUMBERFORMAT_DATE;
314 0 : eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
315 0 : break;
316 : case 0x0A: // Date, intern sal_Int32 2
317 : //fDate;dfDayMonthYearLong;
318 0 : eType = NUMBERFORMAT_DATE;
319 0 : eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
320 0 : break;
321 : case 0x0B: // Time, intern sal_Int32 1
322 : //fTime;tfHourMinSec24;
323 0 : eType = NUMBERFORMAT_TIME;
324 0 : eIndexTableOffset = NF_TIME_HHMMSS;
325 0 : break;
326 : case 0x0C: // Time, intern sal_Int32 2
327 : //fTime;tfHourMinSec24;
328 0 : eType = NUMBERFORMAT_TIME;
329 0 : eIndexTableOffset = NF_TIME_HHMMSS;
330 0 : break;
331 : case 0x0F: // Standardeinstellung
332 : //fStandard;nSt;
333 0 : bDefault = sal_True;
334 0 : break;
335 : default:
336 : //fStandard;nSt;
337 0 : bDefault = sal_True;
338 0 : break;
339 : }
340 0 : break;
341 : }
342 :
343 : // Format in Table schieben
344 0 : if( bDefault )
345 0 : nHandle = 0;
346 0 : else if (eIndexTableOffset != NF_NUMERIC_START)
347 0 : nHandle = pFormTable->GetFormatIndex( eIndexTableOffset, eLanguage);
348 : else
349 : {
350 : sal_Int32 nDummy;
351 0 : pFormTable->PutEntry( aFormString, nDummy, eType, nHandle, eLanguage );
352 : }
353 :
354 0 : return new SfxUInt32Item( ATTR_VALUE_FORMAT, ( sal_uInt32 ) nHandle );
355 : }
356 :
357 0 : void LotusRange::MakeHash( void )
358 : {
359 : // 33222222222211111111110000000000
360 : // 10987654321098765432109876543210
361 : // ******** nColS
362 : // ******** nColE
363 : // **************** nRowS
364 : // **************** nRowE
365 0 : nHash = static_cast<sal_uInt32>(nColStart);
366 0 : nHash += static_cast<sal_uInt32>(nColEnd) << 6;
367 0 : nHash += static_cast<sal_uInt32>(nRowStart) << 12;
368 0 : nHash += static_cast<sal_uInt32>(nRowEnd ) << 16;
369 0 : }
370 :
371 0 : LotusRange::LotusRange( SCCOL nCol, SCROW nRow )
372 : {
373 0 : nColStart = nColEnd = nCol;
374 0 : nRowStart = nRowEnd = nRow;
375 0 : nId = ID_FAIL;
376 0 : MakeHash();
377 0 : }
378 :
379 0 : LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
380 : {
381 0 : nColStart = nCS;
382 0 : nColEnd = nCE;
383 0 : nRowStart = nRS;
384 0 : nRowEnd = nRE;
385 0 : nId = ID_FAIL;
386 0 : MakeHash();
387 0 : }
388 :
389 0 : LotusRange::LotusRange( const LotusRange& rCpy )
390 : {
391 0 : Copy( rCpy );
392 0 : }
393 :
394 0 : LotusRangeList::LotusRangeList( void )
395 : {
396 0 : aComplRef.InitFlags();
397 :
398 : ScSingleRefData* pSingRef;
399 0 : nIdCnt = 1;
400 :
401 0 : pSingRef = &aComplRef.Ref1;
402 0 : pSingRef->SetRelTab(0);
403 0 : pSingRef->SetColRel( false );
404 0 : pSingRef->SetRowRel( false );
405 0 : pSingRef->SetFlag3D( false );
406 :
407 0 : pSingRef = &aComplRef.Ref2;
408 0 : pSingRef->SetRelTab(0);
409 0 : pSingRef->SetColRel( false );
410 0 : pSingRef->SetRowRel( false );
411 0 : pSingRef->SetFlag3D( false );
412 0 : }
413 :
414 0 : LotusRangeList::~LotusRangeList ()
415 : {
416 0 : std::vector<LotusRange*>::iterator pIter;
417 0 : for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter)
418 0 : delete (*pIter);
419 0 : }
420 :
421 0 : LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
422 : {
423 0 : std::vector<LotusRange*>::iterator pIter;
424 0 : for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter)
425 : {
426 0 : if (rRef == *(*pIter))
427 0 : return (*pIter)->nId;
428 : }
429 :
430 0 : return ID_FAIL;
431 : }
432 :
433 0 : void LotusRangeList::Append( LotusRange* pLR, const OUString& rName )
434 : {
435 : OSL_ENSURE( pLR, "*LotusRangeList::Append(): das wird nichts!" );
436 0 : maRanges.push_back(pLR);
437 :
438 0 : ScTokenArray aTokArray;
439 :
440 0 : ScSingleRefData* pSingRef = &aComplRef.Ref1;
441 :
442 0 : pSingRef->SetAbsCol(pLR->nColStart);
443 0 : pSingRef->SetAbsRow(pLR->nRowStart);
444 :
445 0 : if( pLR->IsSingle() )
446 0 : aTokArray.AddSingleReference( *pSingRef );
447 : else
448 : {
449 0 : pSingRef = &aComplRef.Ref2;
450 0 : pSingRef->SetAbsCol(pLR->nColEnd);
451 0 : pSingRef->SetAbsRow(pLR->nRowEnd);
452 0 : aTokArray.AddDoubleReference( aComplRef );
453 : }
454 :
455 : ScRangeData* pData = new ScRangeData(
456 0 : pLotusRoot->pDoc, rName, aTokArray );
457 :
458 0 : pLotusRoot->pScRangeName->insert( pData );
459 :
460 0 : pLR->SetId( nIdCnt );
461 :
462 0 : nIdCnt++;
463 0 : }
464 :
465 0 : RangeNameBufferWK3::RangeNameBufferWK3( void )
466 : {
467 0 : pScTokenArray = new ScTokenArray;
468 0 : nIntCount = 1;
469 0 : }
470 :
471 0 : RangeNameBufferWK3::~RangeNameBufferWK3()
472 : {
473 0 : delete pScTokenArray;
474 0 : }
475 :
476 0 : void RangeNameBufferWK3::Add( const OUString& rOrgName, const ScComplexRefData& rCRD )
477 : {
478 0 : OUString aScName = ScfTools::ConvertToScDefinedName(rOrgName);
479 :
480 0 : Entry aInsert( rOrgName, aScName, rCRD );
481 :
482 0 : pScTokenArray->Clear();
483 :
484 0 : const ScSingleRefData& rRef1 = rCRD.Ref1;
485 0 : const ScSingleRefData& rRef2 = rCRD.Ref2;
486 0 : ScAddress aAbs1 = rRef1.toAbs(ScAddress());
487 0 : ScAddress aAbs2 = rRef2.toAbs(ScAddress());
488 0 : if (aAbs1 == aAbs2)
489 : {
490 0 : pScTokenArray->AddSingleReference( rCRD.Ref1 );
491 0 : aInsert.bSingleRef = true;
492 : }
493 : else
494 : {
495 0 : pScTokenArray->AddDoubleReference( rCRD );
496 0 : aInsert.bSingleRef = false;
497 : }
498 :
499 0 : ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, aScName, *pScTokenArray );
500 :
501 0 : aInsert.nRelInd = nIntCount;
502 0 : pData->SetIndex( nIntCount );
503 0 : nIntCount++;
504 :
505 0 : maEntries.push_back( aInsert );
506 0 : pLotusRoot->pScRangeName->insert( pData );
507 0 : }
508 :
509 0 : bool RangeNameBufferWK3::FindRel( const OUString& rRef, sal_uInt16& rIndex )
510 : {
511 0 : StringHashEntry aRef( rRef );
512 :
513 0 : std::vector<Entry>::const_iterator itr;
514 0 : for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr )
515 : {
516 0 : if ( aRef == itr->aStrHashEntry )
517 : {
518 0 : rIndex = itr->nRelInd;
519 0 : return true;
520 : }
521 : }
522 :
523 0 : return false;
524 : }
525 :
526 0 : bool RangeNameBufferWK3::FindAbs( const OUString& rRef, sal_uInt16& rIndex )
527 : {
528 0 : OUString aTmp( rRef );
529 0 : aTmp = aTmp.copy(1);
530 0 : StringHashEntry aRef( aTmp ); // ohne '$' suchen!
531 :
532 0 : std::vector<Entry>::iterator itr;
533 0 : for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr )
534 : {
535 0 : if ( aRef == itr->aStrHashEntry )
536 : {
537 : // eventuell neuen Range Name aufbauen
538 0 : if( itr->nAbsInd )
539 0 : rIndex = itr->nAbsInd;
540 : else
541 : {
542 0 : ScSingleRefData* pRef = &itr->aScComplexRefDataRel.Ref1;
543 0 : pScTokenArray->Clear();
544 :
545 0 : pRef->SetColRel( false );
546 0 : pRef->SetRowRel( false );
547 0 : pRef->SetTabRel( true );
548 :
549 0 : if( itr->bSingleRef )
550 0 : pScTokenArray->AddSingleReference( *pRef );
551 : else
552 : {
553 0 : pRef = &itr->aScComplexRefDataRel.Ref2;
554 0 : pRef->SetColRel( false );
555 0 : pRef->SetRowRel( false );
556 0 : pRef->SetTabRel( true );
557 0 : pScTokenArray->AddDoubleReference( itr->aScComplexRefDataRel );
558 : }
559 :
560 0 : ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, itr->aScAbsName, *pScTokenArray );
561 :
562 0 : rIndex = itr->nAbsInd = nIntCount;
563 0 : pData->SetIndex( rIndex );
564 0 : nIntCount++;
565 :
566 0 : pLotusRoot->pScRangeName->insert( pData );
567 : }
568 :
569 0 : return true;
570 : }
571 : }
572 :
573 0 : return false;
574 : }
575 :
576 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|