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 : #include "lotfilter.hxx"
37 :
38 : #include <math.h>
39 :
40 6 : void PutFormString(LotusContext& rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char* pString)
41 : {
42 : // evaluate Label-Format
43 : OSL_ENSURE( pString != NULL, "PutFormString(): pString == NULL" );
44 6 : if (!pString)
45 0 : return;
46 :
47 : sal_Char cForm;
48 6 : SvxHorJustifyItem* pJustify = NULL;
49 :
50 6 : cForm = *pString;
51 :
52 6 : switch( cForm )
53 : {
54 : case '"': // align-right
55 4 : pJustify = rContext.pAttrRight;
56 4 : pString++;
57 4 : break;
58 : case '\'': // align-left
59 2 : pJustify = rContext.pAttrLeft;
60 2 : pString++;
61 2 : break;
62 : case '^': // centered
63 0 : pJustify = rContext.pAttrCenter;
64 0 : pString++;
65 0 : break;
66 : case '|': // printer command
67 0 : pString = NULL;
68 0 : break;
69 : case '\\': // repetition
70 0 : pJustify = rContext.pAttrRepeat;
71 0 : pString++;
72 0 : break;
73 : default: // undefined case!
74 0 : pJustify = rContext.pAttrStandard;
75 : }
76 :
77 6 : if (!pString)
78 0 : return;
79 :
80 6 : nCol = SanitizeCol(nCol);
81 6 : nRow = SanitizeRow(nRow);
82 6 : nTab = SanitizeTab(nTab);
83 :
84 6 : rContext.pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify );
85 6 : ScSetStringParam aParam;
86 6 : aParam.setTextInput();
87 6 : rContext.pDoc->SetString(ScAddress(nCol,nRow,nTab), OUString(pString, strlen(pString), rContext.pLotusRoot->eCharsetQ), &aParam);
88 : }
89 :
90 7 : void SetFormat(LotusContext& rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt)
91 : {
92 7 : nCol = SanitizeCol(nCol);
93 7 : nRow = SanitizeRow(nRow);
94 7 : nTab = SanitizeTab(nTab);
95 :
96 : // PREC: nSt = default number of decimal places
97 7 : rContext.pDoc->ApplyAttr(nCol, nRow, nTab, *(rContext.pValueFormCache->GetAttr(nFormat, nSt)));
98 :
99 7 : ScProtectionAttr aAttr;
100 :
101 7 : aAttr.SetProtection( nFormat & 0x80 );
102 :
103 7 : rContext.pDoc->ApplyAttr( nCol, nRow, nTab, aAttr );
104 7 : }
105 :
106 0 : double SnumToDouble( sal_Int16 nVal )
107 : {
108 : const double pFacts[ 8 ] = {
109 : 5000.0,
110 : 500.0,
111 : 0.05,
112 : 0.005,
113 : 0.0005,
114 : 0.00005,
115 : 0.0625,
116 0 : 0.015625 };
117 :
118 : double fVal;
119 :
120 0 : if( nVal & 0x0001 )
121 : {
122 0 : fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
123 0 : fVal *= ( sal_Int16 ) ( nVal >> 4 );
124 : }
125 : else
126 0 : fVal = ( sal_Int16 ) ( nVal >> 1 );
127 :
128 0 : return fVal;
129 : }
130 :
131 222 : double Snum32ToDouble( sal_uInt32 nValue )
132 : {
133 : double fValue, temp;
134 :
135 222 : fValue = nValue >> 6;
136 222 : temp = nValue & 0x0f;
137 222 : if (temp)
138 : {
139 214 : if (nValue & 0x00000010)
140 107 : fValue /= pow((double)10, temp);
141 : else
142 107 : fValue *= pow((double)10, temp);
143 : }
144 :
145 222 : if ((nValue & 0x00000020))
146 0 : fValue = -fValue;
147 222 : return fValue;
148 : }
149 :
150 4 : FormCache::FormCache( ScDocument* pDoc1, sal_uInt8 nNewDefaultFormat )
151 4 : : nIndex(0)
152 : { // Default format is 'Default'
153 4 : nDefaultFormat = nNewDefaultFormat;
154 4 : pFormTable = pDoc1->GetFormatTable();
155 8196 : for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
156 8192 : bValid[ nC ] = false;
157 4 : eLanguage = ScGlobal::eLnge;
158 4 : }
159 :
160 3 : FormCache::~FormCache()
161 : {
162 6147 : for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
163 6144 : delete aIdents[ nC ].GetAttr();
164 3 : }
165 :
166 1 : SfxUInt32Item* FormCache::NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt )
167 : {
168 : // setup new Format
169 : sal_uInt8 nL, nH; // Low-/High-Nibble
170 1 : sal_uInt8 nForm = nFormat;
171 1 : OUString aFormString;
172 1 : sal_Int16 eType = css::util::NumberFormat::ALL;
173 : sal_uInt32 nIndex1;
174 : sal_uInt32 nHandle;
175 1 : NfIndexTableOffset eIndexTableOffset = NF_NUMERIC_START;
176 1 : bool bDefault = false;
177 :
178 1 : if( nForm == 0xFF ) // Default-Format?
179 0 : nForm = nDefaultFormat;
180 :
181 : // split into Low and High byte
182 1 : nL = nFormat & 0x0F;
183 1 : nH = ( nFormat & 0xF0 ) / 16;
184 :
185 1 : nH &= 0x07; // extract bits 4-6
186 1 : switch( nH )
187 : {
188 : case 0x00: // fixed-point number
189 : //fStandard;nL;
190 : nIndex1 = pFormTable->GetStandardFormat(
191 0 : css::util::NumberFormat::NUMBER, eLanguage );
192 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
193 0 : eLanguage, false, false, nL, 1);
194 0 : break;
195 : case 0x01: // scientific notation
196 : //fExponent;nL;
197 : nIndex1 = pFormTable->GetStandardFormat(
198 0 : css::util::NumberFormat::SCIENTIFIC, eLanguage );
199 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
200 0 : eLanguage, false, false, nL, 1);
201 0 : break;
202 : case 0x02: // currency
203 : //fMoney;nL;
204 : nIndex1 = pFormTable->GetStandardFormat(
205 0 : css::util::NumberFormat::CURRENCY, eLanguage );
206 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
207 0 : eLanguage, false, false, nL, 1);
208 0 : break;
209 : case 0x03: // percentage
210 : //fPercent;nL;
211 : nIndex1 = pFormTable->GetStandardFormat(
212 0 : css::util::NumberFormat::PERCENT, eLanguage );
213 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
214 0 : eLanguage, false, false, nL, 1);
215 0 : break;
216 : case 0x04: // Decimal
217 : //fStandard;nL;
218 : nIndex1 = pFormTable->GetStandardFormat(
219 0 : css::util::NumberFormat::NUMBER, eLanguage );
220 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
221 0 : eLanguage, true, false, nL, 1);
222 0 : break;
223 : case 0x05: // unspecified
224 : //fStandard;nL;
225 : nIndex1 = pFormTable->GetStandardFormat(
226 0 : css::util::NumberFormat::NUMBER, eLanguage );
227 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
228 0 : eLanguage, false, false, nL, 1);
229 0 : break;
230 : case 0x06: // unspecified
231 : //fStandard;nL;
232 : nIndex1 = pFormTable->GetStandardFormat(
233 0 : css::util::NumberFormat::NUMBER, eLanguage );
234 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
235 0 : eLanguage, false, false, nL, 1);
236 0 : nIndex1 = 0;
237 0 : break;
238 : case 0x07: // Special format
239 1 : switch( nL )
240 : {
241 : case 0x00: // +/-
242 : //fStandard;nSt;
243 : nIndex1 = pFormTable->GetStandardFormat(
244 0 : css::util::NumberFormat::NUMBER, eLanguage );
245 0 : aFormString = pFormTable->GenerateFormat(nIndex1,
246 0 : eLanguage, false, true, nSt, 1);
247 0 : break;
248 : case 0x01: // general Format
249 : //fStandard;nSt;
250 : nIndex1 = pFormTable->GetStandardFormat(
251 1 : css::util::NumberFormat::NUMBER, eLanguage );
252 2 : aFormString = pFormTable->GenerateFormat(nIndex1,
253 1 : eLanguage, false, false, nSt, 1);
254 1 : break;
255 : case 0x02: // Date: Day, Month, Year
256 : //fDate;dfDayMonthYearLong;
257 0 : eType = css::util::NumberFormat::DATE;
258 0 : eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
259 0 : break;
260 : case 0x03: // Date: Day, Month
261 : //fDate;dfDayMonthLong;
262 0 : eType = css::util::NumberFormat::DATE;
263 0 : aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_DD);
264 0 : aFormString += pFormTable->GetDateSep(); // matches last eLanguage
265 0 : aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_MMMM);
266 0 : break;
267 : case 0x04: // Date: Month, Year
268 : //fDate;dfMonthYearLong;
269 0 : eType = css::util::NumberFormat::DATE;
270 0 : aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_MM);
271 0 : aFormString += pFormTable->GetDateSep(); // matches last eLanguage
272 0 : aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_YYYY);
273 0 : break;
274 : case 0x05: // Text formats
275 : //fString;nSt;
276 0 : eType = css::util::NumberFormat::TEXT;
277 0 : eIndexTableOffset = NF_TEXT;
278 0 : break;
279 : case 0x06: // hidden
280 : //wFlag |= paHideAll;bSetFormat = sal_False;
281 0 : eType = css::util::NumberFormat::NUMBER;
282 0 : aFormString = "\"\"";
283 0 : break;
284 : case 0x07: // Time: hour, min, sec
285 : //fTime;tfHourMinSec24;
286 0 : eType = css::util::NumberFormat::TIME;
287 0 : eIndexTableOffset = NF_TIME_HHMMSS;
288 0 : break;
289 : case 0x08: // Time: hour, min
290 : //fTime;tfHourMin24;
291 0 : eType = css::util::NumberFormat::TIME;
292 0 : eIndexTableOffset = NF_TIME_HHMM;
293 0 : break;
294 : case 0x09: // Date, intern sal_Int32 1
295 : //fDate;dfDayMonthYearLong;
296 0 : eType = css::util::NumberFormat::DATE;
297 0 : eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
298 0 : break;
299 : case 0x0A: // Date, intern sal_Int32 2
300 : //fDate;dfDayMonthYearLong;
301 0 : eType = css::util::NumberFormat::DATE;
302 0 : eIndexTableOffset = NF_DATE_SYS_DDMMYYYY;
303 0 : break;
304 : case 0x0B: // Time, intern sal_Int32 1
305 : //fTime;tfHourMinSec24;
306 0 : eType = css::util::NumberFormat::TIME;
307 0 : eIndexTableOffset = NF_TIME_HHMMSS;
308 0 : break;
309 : case 0x0C: // Time, intern sal_Int32 2
310 : //fTime;tfHourMinSec24;
311 0 : eType = css::util::NumberFormat::TIME;
312 0 : eIndexTableOffset = NF_TIME_HHMMSS;
313 0 : break;
314 : case 0x0F: // Default
315 : //fStandard;nSt;
316 0 : bDefault = true;
317 0 : break;
318 : default:
319 : //fStandard;nSt;
320 0 : bDefault = true;
321 0 : break;
322 : }
323 1 : break;
324 : }
325 :
326 : // push Format into table
327 1 : if( bDefault )
328 0 : nHandle = 0;
329 1 : else if (eIndexTableOffset != NF_NUMERIC_START)
330 0 : nHandle = pFormTable->GetFormatIndex( eIndexTableOffset, eLanguage);
331 : else
332 : {
333 : sal_Int32 nDummy;
334 1 : pFormTable->PutEntry( aFormString, nDummy, eType, nHandle, eLanguage );
335 : }
336 :
337 1 : return new SfxUInt32Item( ATTR_VALUE_FORMAT, ( sal_uInt32 ) nHandle );
338 : }
339 :
340 5 : void LotusRange::MakeHash()
341 : {
342 : // 33222222222211111111110000000000
343 : // 10987654321098765432109876543210
344 : // ******** nColS
345 : // ******** nColE
346 : // **************** nRowS
347 : // **************** nRowE
348 5 : nHash = static_cast<sal_uInt32>(nColStart);
349 5 : nHash += static_cast<sal_uInt32>(nColEnd) << 6;
350 5 : nHash += static_cast<sal_uInt32>(nRowStart) << 12;
351 5 : nHash += static_cast<sal_uInt32>(nRowEnd ) << 16;
352 5 : }
353 :
354 3 : LotusRange::LotusRange( SCCOL nCol, SCROW nRow )
355 : {
356 3 : nColStart = nColEnd = nCol;
357 3 : nRowStart = nRowEnd = nRow;
358 3 : nId = ID_FAIL;
359 3 : MakeHash();
360 3 : }
361 :
362 2 : LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
363 : {
364 2 : nColStart = nCS;
365 2 : nColEnd = nCE;
366 2 : nRowStart = nRS;
367 2 : nRowEnd = nRE;
368 2 : nId = ID_FAIL;
369 2 : MakeHash();
370 2 : }
371 :
372 0 : LotusRange::LotusRange( const LotusRange& rCpy )
373 : {
374 0 : Copy( rCpy );
375 0 : }
376 :
377 4 : LotusRangeList::LotusRangeList(LOTUS_ROOT* pLotRoot)
378 4 : : m_pLotRoot(pLotRoot)
379 : {
380 4 : aComplRef.InitFlags();
381 :
382 : ScSingleRefData* pSingRef;
383 4 : nIdCnt = 1;
384 :
385 4 : pSingRef = &aComplRef.Ref1;
386 4 : pSingRef->SetRelTab(0);
387 4 : pSingRef->SetColRel( false );
388 4 : pSingRef->SetRowRel( false );
389 4 : pSingRef->SetFlag3D( false );
390 :
391 4 : pSingRef = &aComplRef.Ref2;
392 4 : pSingRef->SetRelTab(0);
393 4 : pSingRef->SetColRel( false );
394 4 : pSingRef->SetRowRel( false );
395 4 : pSingRef->SetFlag3D( false );
396 4 : }
397 :
398 : SCCOL LotusRangeList::nEingCol;
399 : SCROW LotusRangeList::nEingRow;
400 :
401 8 : LotusRangeList::~LotusRangeList ()
402 : {
403 4 : std::vector<LotusRange*>::iterator pIter;
404 4 : for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter)
405 0 : delete (*pIter);
406 4 : }
407 :
408 5 : LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
409 : {
410 5 : std::vector<LotusRange*>::iterator pIter;
411 5 : for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter)
412 : {
413 0 : if (rRef == *(*pIter))
414 0 : return (*pIter)->nId;
415 : }
416 :
417 5 : return ID_FAIL;
418 : }
419 :
420 0 : void LotusRangeList::Append( LotusRange* pLR, const OUString& rName )
421 : {
422 : OSL_ENSURE( pLR, "*LotusRangeList::Append(): no pointer!" );
423 0 : maRanges.push_back(pLR);
424 :
425 0 : ScTokenArray aTokArray;
426 :
427 0 : ScSingleRefData* pSingRef = &aComplRef.Ref1;
428 :
429 0 : pSingRef->SetAbsCol(pLR->nColStart);
430 0 : pSingRef->SetAbsRow(pLR->nRowStart);
431 :
432 0 : if( pLR->IsSingle() )
433 0 : aTokArray.AddSingleReference( *pSingRef );
434 : else
435 : {
436 0 : pSingRef = &aComplRef.Ref2;
437 0 : pSingRef->SetAbsCol(pLR->nColEnd);
438 0 : pSingRef->SetAbsRow(pLR->nRowEnd);
439 0 : aTokArray.AddDoubleReference( aComplRef );
440 : }
441 :
442 : ScRangeData* pData = new ScRangeData(
443 0 : m_pLotRoot->pDoc, rName, aTokArray );
444 :
445 0 : m_pLotRoot->pScRangeName->insert( pData );
446 :
447 0 : pLR->SetId( nIdCnt );
448 :
449 0 : nIdCnt++;
450 0 : }
451 :
452 4 : RangeNameBufferWK3::RangeNameBufferWK3(LOTUS_ROOT* pLotRoot)
453 4 : : m_pLotRoot(pLotRoot)
454 : {
455 4 : pScTokenArray = new ScTokenArray;
456 4 : nIntCount = 1;
457 4 : }
458 :
459 12 : RangeNameBufferWK3::~RangeNameBufferWK3()
460 : {
461 4 : delete pScTokenArray;
462 8 : }
463 :
464 0 : void RangeNameBufferWK3::Add( const OUString& rOrgName, const ScComplexRefData& rCRD )
465 : {
466 0 : OUString aScName = ScfTools::ConvertToScDefinedName(rOrgName);
467 :
468 0 : Entry aInsert( rOrgName, aScName, rCRD );
469 :
470 0 : pScTokenArray->Clear();
471 :
472 0 : const ScSingleRefData& rRef1 = rCRD.Ref1;
473 0 : const ScSingleRefData& rRef2 = rCRD.Ref2;
474 0 : ScAddress aAbs1 = rRef1.toAbs(ScAddress());
475 0 : ScAddress aAbs2 = rRef2.toAbs(ScAddress());
476 0 : if (aAbs1 == aAbs2)
477 : {
478 0 : pScTokenArray->AddSingleReference( rCRD.Ref1 );
479 0 : aInsert.bSingleRef = true;
480 : }
481 : else
482 : {
483 0 : pScTokenArray->AddDoubleReference( rCRD );
484 0 : aInsert.bSingleRef = false;
485 : }
486 :
487 0 : ScRangeData* pData = new ScRangeData( m_pLotRoot->pDoc, aScName, *pScTokenArray );
488 :
489 0 : aInsert.nRelInd = nIntCount;
490 0 : pData->SetIndex( nIntCount );
491 0 : nIntCount++;
492 :
493 0 : maEntries.push_back( aInsert );
494 0 : m_pLotRoot->pScRangeName->insert( pData );
495 0 : }
496 :
497 0 : bool RangeNameBufferWK3::FindRel( const OUString& rRef, sal_uInt16& rIndex )
498 : {
499 0 : StringHashEntry aRef( rRef );
500 :
501 0 : std::vector<Entry>::const_iterator itr;
502 0 : for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr )
503 : {
504 0 : if ( aRef == itr->aStrHashEntry )
505 : {
506 0 : rIndex = itr->nRelInd;
507 0 : return true;
508 : }
509 : }
510 :
511 0 : return false;
512 : }
513 :
514 0 : bool RangeNameBufferWK3::FindAbs( const OUString& rRef, sal_uInt16& rIndex )
515 : {
516 0 : OUString aTmp( rRef );
517 0 : aTmp = aTmp.copy(1);
518 0 : StringHashEntry aRef( aTmp ); // search w/o '$'!
519 :
520 0 : std::vector<Entry>::iterator itr;
521 0 : for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr )
522 : {
523 0 : if ( aRef == itr->aStrHashEntry )
524 : {
525 : // setup new range if needed
526 0 : if( itr->nAbsInd )
527 0 : rIndex = itr->nAbsInd;
528 : else
529 : {
530 0 : ScSingleRefData* pRef = &itr->aScComplexRefDataRel.Ref1;
531 0 : pScTokenArray->Clear();
532 :
533 0 : pRef->SetColRel( false );
534 0 : pRef->SetRowRel( false );
535 0 : pRef->SetTabRel( true );
536 :
537 0 : if( itr->bSingleRef )
538 0 : pScTokenArray->AddSingleReference( *pRef );
539 : else
540 : {
541 0 : pRef = &itr->aScComplexRefDataRel.Ref2;
542 0 : pRef->SetColRel( false );
543 0 : pRef->SetRowRel( false );
544 0 : pRef->SetTabRel( true );
545 0 : pScTokenArray->AddDoubleReference( itr->aScComplexRefDataRel );
546 : }
547 :
548 0 : ScRangeData* pData = new ScRangeData( m_pLotRoot->pDoc, itr->aScAbsName, *pScTokenArray );
549 :
550 0 : rIndex = itr->nAbsInd = nIntCount;
551 0 : pData->SetIndex( rIndex );
552 0 : nIntCount++;
553 :
554 0 : m_pLotRoot->pScRangeName->insert( pData );
555 : }
556 :
557 0 : return true;
558 : }
559 : }
560 :
561 0 : return false;
562 30 : }
563 :
564 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|