1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28
29 //------------------------------------------------------------------------
30
31 #include "scitems.hxx"
32 #include <svx/algitem.hxx>
33 #include <svl/zforlist.hxx>
34 #include <tools/solar.h>
35
36 #include "cell.hxx"
37 #include "rangenam.hxx"
38 #include "compiler.hxx"
39
40 #include "tool.h"
41 #include "decl.h"
42 #include "root.hxx"
43 #include "lotrange.hxx"
44 #include "namebuff.hxx"
45 #include "ftools.hxx"
46
47 #include <math.h>
48
49 #ifdef _MSC_VER
50 #pragma optimize("",off)
51 #endif
52
53 //--------------------------------------------------------- EXTERNE VARIABLEN -
54 extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
55 extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
56
57 //--------------------------------------------------------- GLOBALE VARIABLEN -
58 sal_uInt8 nDefaultFormat; // -> op.cpp, Standard-Zellenformat
59
60 extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
61 extern ScProtectionAttr* pAttrUnprot;
62 extern SfxUInt32Item** pAttrValForms;
63
64 SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
65 // -> in memory.cxx initialisiert
66 ScProtectionAttr* pAttrUnprot; // -> " memory.cxx "
67
68 extern FormCache* pValueFormCache; // -> in memory.cxx initialisiert
69 FormCache* pValueFormCache;
70
71 SCCOL LotusRangeList::nEingCol;
72 SCROW LotusRangeList::nEingRow;
73
74
75
76
PutFormString(SCCOL nCol,SCROW nRow,SCTAB nTab,sal_Char * pString)77 void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char* pString )
78 {
79 // Label-Format-Auswertung
80 DBG_ASSERT( pString != NULL, "PutFormString(): pString == NULL" );
81 if (!pString)
82 return;
83
84 sal_Char cForm;
85 SvxHorJustifyItem* pJustify = NULL;
86
87 cForm = *pString;
88
89 switch( cForm )
90 {
91 case '"': // rechtsbuendig
92 pJustify = pAttrRight;
93 pString++;
94 break;
95 case '\'': // linksbuendig
96 pJustify = pAttrLeft;
97 pString++;
98 break;
99 case '^': // zentriert
100 pJustify = pAttrCenter;
101 pString++;
102 break;
103 case '|': // printer command
104 pString = NULL;
105 break;
106 case '\\': // Wiederholung
107 pJustify = pAttrRepeat;
108 pString++;
109 break;
110 default: // kenn' ich nicht!
111 pJustify = pAttrStandard;
112 }
113
114 pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify );
115 ScStringCell* pZelle = new ScStringCell( String( pString, pLotusRoot->eCharsetQ ) );
116 pDoc->PutCell( nCol, nRow, nTab, pZelle, ( sal_Bool ) sal_True );
117 }
118
119
120
121
SetFormat(SCCOL nCol,SCROW nRow,SCTAB nTab,sal_uInt8 nFormat,sal_uInt8 nSt)122 void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt )
123 {
124 // PREC: nSt = Standard-Dezimalstellenanzahl
125 pDoc->ApplyAttr( nCol, nRow, nTab, *( pValueFormCache->GetAttr( nFormat, nSt ) ) );
126
127 ScProtectionAttr aAttr;
128
129 aAttr.SetProtection( nFormat & 0x80 );
130
131 pDoc->ApplyAttr( nCol, nRow, nTab, aAttr );
132 }
133
InitPage(void)134 void InitPage( void )
135 { // Seitenformat initialisieren, d.h. Default-Werte von SC holen
136 //scGetPageFormat( 0, &aPage );
137 }
138
139
SnumToDouble(sal_Int16 nVal)140 double SnumToDouble( sal_Int16 nVal )
141 {
142 const double pFacts[ 8 ] = {
143 5000.0,
144 500.0,
145 0.05,
146 0.005,
147 0.0005,
148 0.00005,
149 0.0625,
150 0.015625 };
151
152 double fVal;
153
154 if( nVal & 0x0001 )
155 {
156 fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
157 fVal *= ( sal_Int16 ) ( nVal >> 4 );
158 }
159 else
160 fVal = ( sal_Int16 ) ( nVal >> 1 );
161
162 return fVal;
163 }
164
Snum32ToDouble(sal_uInt32 nValue)165 double Snum32ToDouble( sal_uInt32 nValue )
166 {
167 double fValue, temp;
168
169 fValue = nValue >> 6;
170 temp = nValue & 0x0f;
171 if (temp)
172 {
173 if (nValue & 0x00000010)
174 fValue /= pow((double)10, temp);
175 else
176 fValue *= pow((double)10, temp);
177 }
178
179 if ((nValue & 0x00000020))
180 fValue = -fValue;
181 return fValue;
182 }
183
184
FormCache(ScDocument * pDoc1,sal_uInt8 nNewDefaultFormat)185 FormCache::FormCache( ScDocument* pDoc1, sal_uInt8 nNewDefaultFormat )
186 { // Default-Format ist 'Default'
187 nDefaultFormat = nNewDefaultFormat;
188 pFormTable = pDoc1->GetFormatTable();
189 for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
190 bValid[ nC ] = sal_False;
191 eLanguage = ScGlobal::eLnge;
192 }
193
194
~FormCache()195 FormCache::~FormCache()
196 {
197 for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
198 delete aIdents[ nC ].GetAttr();
199 }
200
201
NewAttr(sal_uInt8 nFormat,sal_uInt8 nSt)202 SfxUInt32Item* FormCache::NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt )
203 {
204 // neues Format erzeugen
205 sal_uInt8 nL, nH; // Low-/High-Nibble
206 sal_uInt8 nForm = nFormat;
207 String aFormString;
208 const sal_Char* pFormString = 0;
209 sal_Int16 eType = NUMBERFORMAT_ALL;
210 sal_uInt32 nIndex1;
211 sal_uInt32 nHandle;
212 sal_Bool bDefault = sal_False;
213 //void GenerateFormat( aFormString, eType, COUNTRY_SYSTEM, LANGUAGE_SYSTEM,
214 // sal_Bool bThousand, sal_Bool IsRed, sal_uInt16 nPrecision, sal_uInt16 nAnzLeading );
215
216 if( nForm == 0xFF ) // Default-Format?
217 nForm = nDefaultFormat;
218
219 // Aufdroeseln in Low- und High-Nibble
220 nL = nFormat & 0x0F;
221 nH = ( nFormat & 0xF0 ) / 16;
222
223 nH &= 0x07; // Bits 4-6 'rausziehen
224 switch( nH )
225 {
226 case 0x00: // Festkommaformat (fixed)
227 //fStandard;nL;
228 nIndex1 = pFormTable->GetStandardFormat(
229 NUMBERFORMAT_NUMBER, eLanguage );
230 pFormTable->GenerateFormat( aFormString, nIndex1,
231 eLanguage, sal_False, sal_False, nL, 1 );
232 break;
233 case 0x01: // Exponentdarstellung (scientific notation)
234 //fExponent;nL;
235 nIndex1 = pFormTable->GetStandardFormat(
236 NUMBERFORMAT_SCIENTIFIC, eLanguage );
237 pFormTable->GenerateFormat( aFormString, nIndex1,
238 eLanguage, sal_False, sal_False, nL, 1 );
239 break;
240 case 0x02: // Waehrungsdarstellung (currency)
241 //fMoney;nL;
242 nIndex1 = pFormTable->GetStandardFormat(
243 NUMBERFORMAT_CURRENCY, eLanguage );
244 pFormTable->GenerateFormat( aFormString, nIndex1,
245 eLanguage, sal_False, sal_False, nL, 1 );
246 break;
247 case 0x03: // Prozent
248 //fPercent;nL;
249 nIndex1 = pFormTable->GetStandardFormat(
250 NUMBERFORMAT_PERCENT, eLanguage );
251 pFormTable->GenerateFormat( aFormString, nIndex1,
252 eLanguage, sal_False, sal_False, nL, 1 );
253 break;
254 case 0x04: // Komma
255 //fStandard;nL;
256 nIndex1 = pFormTable->GetStandardFormat(
257 NUMBERFORMAT_NUMBER, eLanguage );
258 pFormTable->GenerateFormat( aFormString, nIndex1,
259 eLanguage, sal_True, sal_False, nL, 1 );
260 break;
261 case 0x05: // frei
262 //fStandard;nL;
263 nIndex1 = pFormTable->GetStandardFormat(
264 NUMBERFORMAT_NUMBER, eLanguage );
265 pFormTable->GenerateFormat( aFormString, nIndex1,
266 eLanguage, sal_False, sal_False, nL, 1 );
267 break;
268 case 0x06: // frei
269 //fStandard;nL;
270 nIndex1 = pFormTable->GetStandardFormat(
271 NUMBERFORMAT_NUMBER, eLanguage );
272 pFormTable->GenerateFormat( aFormString, nIndex1,
273 eLanguage, sal_False, sal_False, nL, 1 );
274 nIndex1 = 0;
275 break;
276 case 0x07: // Spezialformat
277 switch( nL )
278 {
279 case 0x00: // +/-
280 //fStandard;nSt;
281 nIndex1 = pFormTable->GetStandardFormat(
282 NUMBERFORMAT_NUMBER, eLanguage );
283 pFormTable->GenerateFormat( aFormString, nIndex1,
284 eLanguage, sal_False, sal_True, nSt, 1 );
285 break;
286 case 0x01: // generelles Format
287 //fStandard;nSt;
288 nIndex1 = pFormTable->GetStandardFormat(
289 NUMBERFORMAT_NUMBER, eLanguage );
290 pFormTable->GenerateFormat( aFormString, nIndex1,
291 eLanguage, sal_False, sal_False, nSt, 1 );
292 break;
293 case 0x02: // Datum: Tag, Monat, Jahr
294 //fDate;dfDayMonthYearLong;
295 eType = NUMBERFORMAT_DATE;
296 pFormString = "TT.MM.JJJJ";
297 break;
298 case 0x03: // Datum: Tag, Monat
299 //fDate;dfDayMonthLong;
300 eType = NUMBERFORMAT_DATE;
301 pFormString = "TT.MMMM";
302 break;
303 case 0x04: // Datum: Monat, Jahr
304 //fDate;dfMonthYearLong;
305 eType = NUMBERFORMAT_DATE;
306 pFormString = "MM.JJJJ";
307 break;
308 case 0x05: // Textformate
309 //fString;nSt;
310 eType = NUMBERFORMAT_TEXT;
311 pFormString = "@";
312 break;
313 case 0x06: // versteckt
314 //wFlag |= paHideAll;bSetFormat = sal_False;
315 eType = NUMBERFORMAT_NUMBER;
316 pFormString = "";
317 break;
318 case 0x07: // Time: hour, min, sec
319 //fTime;tfHourMinSec24;
320 eType = NUMBERFORMAT_TIME;
321 pFormString = "HH:MM:SS";
322 break;
323 case 0x08: // Time: hour, min
324 //fTime;tfHourMin24;
325 eType = NUMBERFORMAT_TIME;
326 pFormString = "HH:MM";
327 break;
328 case 0x09: // Date, intern sal_Int32 1
329 //fDate;dfDayMonthYearLong;
330 eType = NUMBERFORMAT_DATE;
331 pFormString = "TT.MM.JJJJ";
332 break;
333 case 0x0A: // Date, intern sal_Int32 2
334 //fDate;dfDayMonthYearLong;
335 eType = NUMBERFORMAT_DATE;
336 pFormString = "TT.MM.JJJJ";
337 break;
338 case 0x0B: // Time, intern sal_Int32 1
339 //fTime;tfHourMinSec24;
340 eType = NUMBERFORMAT_TIME;
341 pFormString = "HH:MM:SS";
342 break;
343 case 0x0C: // Time, intern sal_Int32 2
344 //fTime;tfHourMinSec24;
345 eType = NUMBERFORMAT_TIME;
346 pFormString = "HH:MM:SS";
347 break;
348 case 0x0F: // Standardeinstellung
349 //fStandard;nSt;
350 bDefault = sal_True;
351 break;
352 default:
353 //fStandard;nSt;
354 bDefault = sal_True;
355 break;
356 }
357 break;
358 default:
359 //fStandard;nL;
360 nIndex1 = pFormTable->GetStandardFormat(
361 NUMBERFORMAT_NUMBER, eLanguage );
362 pFormTable->GenerateFormat( aFormString, nIndex1,
363 eLanguage, sal_False, sal_False, nL, 1 );
364 nIndex1 = 0;
365 break;
366 }
367
368 // Format in Table schieben
369 if( bDefault )
370 nHandle = 0;
371 else
372 {
373 if( pFormString )
374 aFormString.AssignAscii( pFormString );
375
376 xub_StrLen nDummy;
377 pFormTable->PutEntry( aFormString, nDummy, eType, nHandle, eLanguage );
378 }
379
380 return new SfxUInt32Item( ATTR_VALUE_FORMAT, ( sal_uInt32 ) nHandle );
381 }
382
383
384
385
MakeHash(void)386 void LotusRange::MakeHash( void )
387 {
388 // 33222222222211111111110000000000
389 // 10987654321098765432109876543210
390 // ******** nColS
391 // ******** nColE
392 // **************** nRowS
393 // **************** nRowE
394 nHash = static_cast<sal_uInt32>(nColStart);
395 nHash += static_cast<sal_uInt32>(nColEnd) << 6;
396 nHash += static_cast<sal_uInt32>(nRowStart) << 12;
397 nHash += static_cast<sal_uInt32>(nRowEnd ) << 16;
398 }
399
400
LotusRange(SCCOL nCol,SCROW nRow)401 LotusRange::LotusRange( SCCOL nCol, SCROW nRow )
402 {
403 nColStart = nColEnd = nCol;
404 nRowStart = nRowEnd = nRow;
405 nId = ID_FAIL;
406 MakeHash();
407 }
408
409
LotusRange(SCCOL nCS,SCROW nRS,SCCOL nCE,SCROW nRE)410 LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
411 {
412 nColStart = nCS;
413 nColEnd = nCE;
414 nRowStart = nRS;
415 nRowEnd = nRE;
416 nId = ID_FAIL;
417 MakeHash();
418 }
419
420
LotusRange(const LotusRange & rCpy)421 LotusRange::LotusRange( const LotusRange& rCpy )
422 {
423 Copy( rCpy );
424 }
425
426
427
428
429
LotusRangeList(void)430 LotusRangeList::LotusRangeList( void )
431 {
432 aComplRef.InitFlags();
433
434 ScSingleRefData* pSingRef;
435 nIdCnt = 1;
436
437 pSingRef = &aComplRef.Ref1;
438 pSingRef->nTab = pSingRef->nRelTab = 0;
439 pSingRef->SetColRel( sal_False );
440 pSingRef->SetRowRel( sal_False );
441 pSingRef->SetTabRel( sal_True );
442 pSingRef->SetFlag3D( sal_False );
443
444 pSingRef = &aComplRef.Ref2;
445 pSingRef->nTab = pSingRef->nRelTab = 0;
446 pSingRef->SetColRel( sal_False );
447 pSingRef->SetRowRel( sal_False );
448 pSingRef->SetTabRel( sal_True );
449 pSingRef->SetFlag3D( sal_False );
450 }
451
452
~LotusRangeList(void)453 LotusRangeList::~LotusRangeList( void )
454 {
455 LotusRange *pDel = ( LotusRange * ) List::First();
456
457 while( pDel )
458 {
459 delete pDel;
460 pDel = ( LotusRange * ) List::Next();
461 }
462 }
463
464
GetIndex(const LotusRange & rRef)465 LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
466 {
467 LotusRange* pComp = ( LotusRange* ) List::First();
468
469 while( pComp )
470 {
471 if( *pComp == rRef )
472 return pComp->nId;
473 pComp = ( LotusRange* ) List::Next();
474 }
475
476 return ID_FAIL;
477 }
478
479
Append(LotusRange * pLR,const String & rName)480 void LotusRangeList::Append( LotusRange* pLR, const String& rName )
481 {
482 DBG_ASSERT( pLR, "*LotusRangeList::Append(): das wird nichts!" );
483 List::Insert( pLR, CONTAINER_APPEND );
484
485 ScTokenArray aTokArray;
486
487 ScSingleRefData* pSingRef = &aComplRef.Ref1;
488
489 pSingRef->nCol = pLR->nColStart;
490 pSingRef->nRow = pLR->nRowStart;
491
492 if( pLR->IsSingle() )
493 aTokArray.AddSingleReference( *pSingRef );
494 else
495 {
496 pSingRef = &aComplRef.Ref2;
497 pSingRef->nCol = pLR->nColEnd;
498 pSingRef->nRow = pLR->nRowEnd;
499 aTokArray.AddDoubleReference( aComplRef );
500 }
501
502 ScRangeData* pData = new ScRangeData(
503 pLotusRoot->pDoc, rName, aTokArray );
504
505 pLotusRoot->pScRangeName->Insert( pData );
506
507 pLR->SetId( nIdCnt );
508
509 nIdCnt++;
510 }
511
512
513
514
RangeNameBufferWK3(void)515 RangeNameBufferWK3::RangeNameBufferWK3( void )
516 {
517 pScTokenArray = new ScTokenArray;
518 nIntCount = 1;
519 }
520
521
~RangeNameBufferWK3()522 RangeNameBufferWK3::~RangeNameBufferWK3()
523 {
524 ENTRY* pDel = ( ENTRY* ) List::First();
525
526 while( pDel )
527 {
528 delete pDel;
529 pDel = ( ENTRY* ) List::Next();
530 }
531
532 delete pScTokenArray;
533 }
534
535
Add(const String & rOrgName,const ScComplexRefData & rCRD)536 void RangeNameBufferWK3::Add( const String& rOrgName, const ScComplexRefData& rCRD )
537 {
538 String aScName( rOrgName );
539 ScfTools::ConvertToScDefinedName( aScName );
540
541 register ENTRY* pInsert = new ENTRY( rOrgName, aScName, rCRD );
542
543 List::Insert( pInsert, CONTAINER_APPEND );
544
545 pScTokenArray->Clear();
546
547 register const ScSingleRefData& rRef1 = rCRD.Ref1;
548 register const ScSingleRefData& rRef2 = rCRD.Ref2;
549
550 if( rRef1.nCol == rRef2.nCol && rRef1.nRow == rRef2.nRow && rRef1.nTab == rRef2.nTab )
551 {
552 pScTokenArray->AddSingleReference( rCRD.Ref1 );
553 pInsert->bSingleRef = sal_True;
554 }
555 else
556 {
557 pScTokenArray->AddDoubleReference( rCRD );
558 pInsert->bSingleRef = sal_False;
559 }
560
561 ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, aScName, *pScTokenArray );
562
563 pInsert->nRelInd = nIntCount;
564 pData->SetIndex( nIntCount );
565 nIntCount++;
566
567 pLotusRoot->pScRangeName->Insert( pData );
568 }
569
570
FindRel(const String & rRef,sal_uInt16 & rIndex)571 sal_Bool RangeNameBufferWK3::FindRel( const String& rRef, sal_uInt16& rIndex )
572 {
573 StringHashEntry aRef( rRef );
574
575 ENTRY* pFind = ( ENTRY* ) List::First();
576
577 while( pFind )
578 {
579 if( aRef == pFind->aStrHashEntry )
580 {
581 rIndex = pFind->nRelInd;
582 return sal_True;
583 }
584 pFind = ( ENTRY* ) List::Next();
585 }
586
587 return sal_False;
588 }
589
590
FindAbs(const String & rRef,sal_uInt16 & rIndex)591 sal_Bool RangeNameBufferWK3::FindAbs( const String& rRef, sal_uInt16& rIndex )
592 {
593 String aTmp( rRef );
594 StringHashEntry aRef( aTmp.Erase( 0, 1 ) ); // ohne '$' suchen!
595
596 ENTRY* pFind = ( ENTRY* ) List::First();
597
598 while( pFind )
599 {
600 if( aRef == pFind->aStrHashEntry )
601 {
602 // eventuell neuen Range Name aufbauen
603 if( pFind->nAbsInd )
604 rIndex = pFind->nAbsInd;
605 else
606 {
607 ScSingleRefData* pRef = &pFind->aScComplexRefDataRel.Ref1;
608 pScTokenArray->Clear();
609
610 pRef->SetColRel( sal_False );
611 pRef->SetRowRel( sal_False );
612 pRef->SetTabRel( sal_True );
613
614 if( pFind->bSingleRef )
615 pScTokenArray->AddSingleReference( *pRef );
616 else
617 {
618 pRef = &pFind->aScComplexRefDataRel.Ref2;
619 pRef->SetColRel( sal_False );
620 pRef->SetRowRel( sal_False );
621 pRef->SetTabRel( sal_True );
622 pScTokenArray->AddDoubleReference( pFind->aScComplexRefDataRel );
623 }
624
625 ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, pFind->aScAbsName, *pScTokenArray );
626
627 rIndex = pFind->nAbsInd = nIntCount;
628 pData->SetIndex( rIndex );
629 nIntCount++;
630
631 pLotusRoot->pScRangeName->Insert( pData );
632 }
633
634 return sal_True;
635 }
636 pFind = ( ENTRY* ) List::Next();
637 }
638
639 return sal_False;
640 }
641
642
643