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 "excform.hxx"
21 :
22 : #include "formulacell.hxx"
23 : #include "document.hxx"
24 : #include "rangenam.hxx"
25 : #include "xltracer.hxx"
26 : #include "xistream.hxx"
27 : #include "xihelper.hxx"
28 : #include "xilink.hxx"
29 : #include "xiname.hxx"
30 :
31 : #include "externalrefmgr.hxx"
32 :
33 : #include <vector>
34 : #include <cstring>
35 :
36 : using ::std::vector;
37 :
38 : namespace {
39 :
40 : /**
41 : * Extract a file path from OLE link path. An OLE link path is expected to
42 : * be in the following format:
43 : *
44 : * Excel.Sheet.8 \3 [file path]
45 : */
46 0 : bool extractFilePath(const OUString& rUrl, OUString& rPath)
47 : {
48 0 : const char* prefix = "Excel.Sheet.8\3";
49 0 : size_t nPrefixLen = ::std::strlen(prefix);
50 :
51 0 : sal_Int32 n = rUrl.getLength();
52 0 : if (n <= static_cast<sal_Int32>(nPrefixLen))
53 : // needs to have the specified prefix.
54 0 : return false;
55 :
56 0 : OUStringBuffer aBuf;
57 0 : const sal_Unicode* p = rUrl.getStr();
58 0 : for (size_t i = 0; i < static_cast<size_t>(n); ++i, ++p)
59 : {
60 0 : if (i < nPrefixLen)
61 : {
62 0 : sal_Unicode pc = static_cast<sal_Unicode>(*prefix++);
63 0 : if (pc != *p)
64 0 : return false;
65 :
66 0 : continue;
67 : }
68 0 : aBuf.append(*p);
69 : }
70 :
71 0 : rPath = aBuf.makeStringAndClear();
72 0 : return true;
73 : }
74 :
75 : }
76 :
77 2318 : ExcelToSc8::ExternalTabInfo::ExternalTabInfo() :
78 2318 : mnFileId(0), mbExternal(false)
79 : {
80 2318 : }
81 :
82 146 : ExcelToSc8::ExcelToSc8( XclImpRoot& rRoot ) :
83 : ExcelToSc( rRoot ),
84 146 : rLinkMan( rRoot.GetLinkManager() )
85 : {
86 146 : }
87 :
88 288 : ExcelToSc8::~ExcelToSc8()
89 : {
90 288 : }
91 :
92 4 : bool ExcelToSc8::GetExternalFileIdFromXti( sal_uInt16 nIxti, sal_uInt16& rFileId ) const
93 : {
94 4 : const OUString* pFileUrl = rLinkMan.GetSupbookUrl(nIxti);
95 4 : if (!pFileUrl || pFileUrl->isEmpty() || !GetDocShell())
96 0 : return false;
97 :
98 4 : OUString aFileUrl = ScGlobal::GetAbsDocName(*pFileUrl, GetDocShell());
99 4 : ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
100 4 : rFileId = pRefMgr->getExternalFileId(aFileUrl);
101 :
102 4 : return true;
103 : }
104 :
105 2318 : bool ExcelToSc8::Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo )
106 : {
107 2318 : rFirstTab = rLastTab = 0;
108 2318 : rExtInfo.mbExternal = !rLinkMan.IsSelfRef(nIxti);
109 2318 : bool bSuccess = rLinkMan.GetScTabRange(rFirstTab, rLastTab, nIxti);
110 2318 : if (!bSuccess)
111 0 : return false;
112 :
113 2318 : if (!rExtInfo.mbExternal)
114 : // This is internal reference. Stop here.
115 2314 : return true;
116 :
117 4 : rExtInfo.maTabName = rLinkMan.GetSupbookTabName(nIxti, rFirstTab);
118 4 : return GetExternalFileIdFromXti(nIxti, rExtInfo.mnFileId);
119 : }
120 :
121 0 : bool ExcelToSc8::HandleOleLink(sal_uInt16 nXtiIndex, const XclImpExtName& rExtName, ExternalTabInfo& rExtInfo)
122 : {
123 0 : const OUString* pUrl = rLinkMan.GetSupbookUrl(nXtiIndex);
124 0 : if (!pUrl)
125 0 : return false;
126 :
127 0 : OUString aPath;
128 0 : if (!extractFilePath(*pUrl, aPath))
129 : // file path extraction failed.
130 0 : return false;
131 :
132 0 : OUString aFileUrl = ScGlobal::GetAbsDocName(aPath, GetDocShell());
133 0 : return rExtName.CreateOleData(GetDoc(), aFileUrl, rExtInfo.mnFileId, rExtInfo.maTabName, rExtInfo.maRange);
134 : }
135 :
136 : // if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
137 : // otherwise it will seek to the first byte past additional content after <nFormulaLen>
138 6000 : ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
139 : {
140 : sal_uInt8 nOp, nLen, nByte;
141 : sal_uInt16 nUINT16;
142 : double fDouble;
143 6000 : OUString aString;
144 6000 : bool bError = false;
145 6000 : bool bArrayFormula = false;
146 6000 : TokenId nMerk0;
147 6000 : const bool bCondFormat = eFT == FT_CondFormat;
148 6000 : const bool bRangeName = eFT == FT_RangeName || bCondFormat;
149 6000 : const bool bSharedFormula = eFT == FT_SharedFormula;
150 6000 : const bool bRNorSF = bRangeName || bSharedFormula;
151 :
152 : ScSingleRefData aSRD;
153 : ScComplexRefData aCRD;
154 12000 : ExtensionTypeVec aExtensions;
155 :
156 6000 : if( eStatus != ConvOK )
157 : {
158 0 : aIn.Ignore( nFormulaLen );
159 0 : return eStatus;
160 : }
161 :
162 6000 : if( nFormulaLen == 0 )
163 : {
164 0 : aPool.Store( OUString( "-/-" ) );
165 0 : aPool >> aStack;
166 0 : rpTokArray = aPool[ aStack.Get() ];
167 0 : return ConvOK;
168 : }
169 :
170 6000 : sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
171 :
172 54142 : while( (aIn.GetRecPos() < nEndPos) && !bError )
173 : {
174 42142 : aIn >> nOp;
175 :
176 : // always reset flags
177 42142 : aSRD.InitFlags();
178 42142 : aCRD.InitFlags();
179 :
180 42142 : switch( nOp ) // book page:
181 : { // SDK4 SDK5
182 : case 0x01: // Array Formula [325 ]
183 : // Array Formula or Shared Formula [ 277]
184 : case 0x02: // Data Table [325 277]
185 114 : aIn.Ignore( 4 );
186 :
187 114 : bArrayFormula = true;
188 114 : break;
189 : case 0x03: // Addition [312 264]
190 5388 : aStack >> nMerk0;
191 5388 : aPool << aStack << ocAdd << nMerk0;
192 5388 : aPool >> aStack;
193 5388 : break;
194 : case 0x04: // Subtraction [313 264]
195 : // SECOND-TOP minus TOP
196 1418 : aStack >> nMerk0;
197 1418 : aPool << aStack << ocSub << nMerk0;
198 1418 : aPool >> aStack;
199 1418 : break;
200 : case 0x05: // Multiplication [313 264]
201 1168 : aStack >> nMerk0;
202 1168 : aPool << aStack << ocMul << nMerk0;
203 1168 : aPool >> aStack;
204 1168 : break;
205 : case 0x06: // Division [313 264]
206 : // divide TOP by SECOND-TOP
207 2104 : aStack >> nMerk0;
208 2104 : aPool << aStack << ocDiv << nMerk0;
209 2104 : aPool >> aStack;
210 2104 : break;
211 : case 0x07: // Exponentiation [313 265]
212 : // raise SECOND-TOP to power of TOP
213 0 : aStack >> nMerk0;
214 0 : aPool << aStack << ocPow << nMerk0;
215 0 : aPool >> aStack;
216 0 : break;
217 : case 0x08: // Concatenation [313 265]
218 : // append TOP to SECOND-TOP
219 0 : aStack >> nMerk0;
220 0 : aPool << aStack << ocAmpersand << nMerk0;
221 0 : aPool >> aStack;
222 0 : break;
223 : case 0x09: // Less Than [313 265]
224 : // SECOND-TOP < TOP
225 0 : aStack >> nMerk0;
226 0 : aPool << aStack << ocLess << nMerk0;
227 0 : aPool >> aStack;
228 0 : break;
229 : case 0x0A: // Less Than or Equal [313 265]
230 : // SECOND-TOP <= TOP
231 0 : aStack >> nMerk0;
232 0 : aPool << aStack << ocLessEqual << nMerk0;
233 0 : aPool >> aStack;
234 0 : break;
235 : case 0x0B: // Equal [313 265]
236 : // SECOND-TOP == TOP
237 50 : aStack >> nMerk0;
238 50 : aPool << aStack << ocEqual << nMerk0;
239 50 : aPool >> aStack;
240 50 : break;
241 : case 0x0C: // Greater Than or Equal [313 265]
242 : // SECOND-TOP >= TOP
243 0 : aStack >> nMerk0;
244 0 : aPool << aStack << ocGreaterEqual << nMerk0;
245 0 : aPool >> aStack;
246 0 : break;
247 : case 0x0D: // Greater Than [313 265]
248 : // SECOND-TOP > TOP
249 0 : aStack >> nMerk0;
250 0 : aPool << aStack << ocGreater << nMerk0;
251 0 : aPool >> aStack;
252 0 : break;
253 : case 0x0E: // Not Equal [313 265]
254 : // SECOND-TOP != TOP
255 0 : aStack >> nMerk0;
256 0 : aPool << aStack << ocNotEqual << nMerk0;
257 0 : aPool >> aStack;
258 0 : break;
259 : case 0x0F: // Intersection [314 265]
260 0 : aStack >> nMerk0;
261 0 : aPool << aStack << ocIntersect << nMerk0;
262 0 : aPool >> aStack;
263 0 : break;
264 : case 0x10: // Union [314 265]
265 : // ocSep instead of 'ocUnion'
266 18 : aStack >> nMerk0;
267 18 : aPool << aStack << ocSep << nMerk0;
268 : // doesn't fit exactly, but is more Excel-like
269 18 : aPool >> aStack;
270 18 : break;
271 : case 0x11: // Range [314 265]
272 0 : aStack >> nMerk0;
273 0 : aPool << aStack << ocRange << nMerk0;
274 0 : aPool >> aStack;
275 0 : break;
276 : case 0x12: // Unary Plus [312 264]
277 0 : aPool << ocAdd << aStack;
278 0 : aPool >> aStack;
279 0 : break;
280 : case 0x13: // Unary Minus [312 264]
281 6 : aPool << ocNegSub << aStack;
282 6 : aPool >> aStack;
283 6 : break;
284 : case 0x14: // Percent Sign [312 264]
285 0 : aPool << aStack << ocPercentSign;
286 0 : aPool >> aStack;
287 0 : break;
288 : case 0x15: // Parenthesis [326 278]
289 1856 : aPool << ocOpen << aStack << ocClose;
290 1856 : aPool >> aStack;
291 1856 : break;
292 : case 0x16: // Missing Argument [314 266]
293 2 : aPool << ocMissing;
294 2 : aPool >> aStack;
295 2 : GetTracer().TraceFormulaMissingArg();
296 2 : break;
297 : case 0x17: // String Constant [314 266]
298 5472 : aIn >> nLen; // und?
299 5472 : aString = aIn.ReadUniString( nLen ); // reads Grbit even if nLen==0
300 :
301 5472 : aStack << aPool.Store( aString );
302 5472 : break;
303 : case 0x18: // natural language formula
304 : {
305 : sal_uInt8 nEptg;
306 : sal_uInt16 nCol, nRow;
307 0 : aIn >> nEptg;
308 0 : switch( nEptg )
309 : { // name size ext type
310 : case 0x01: // Lel 4 - err
311 0 : aIn.Ignore( 4 );
312 0 : aPool << ocBad;
313 0 : aPool >> aStack;
314 0 : break;
315 : case 0x02: // Rw 4 - ref
316 : case 0x03: // Col 4 - ref
317 : case 0x06: // RwV 4 - val
318 : case 0x07: // ColV 4 - val
319 : {
320 0 : aIn >> nRow >> nCol;
321 0 : ScAddress aAddr(static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab());
322 0 : aSRD.InitAddress(aAddr);
323 :
324 0 : if( nEptg == 0x02 || nEptg == 0x06 )
325 0 : aSRD.SetRowRel(true);
326 : else
327 0 : aSRD.SetColRel(true);
328 :
329 0 : aSRD.SetAddress(aAddr, aEingPos);
330 :
331 0 : aStack << aPool.StoreNlf( aSRD );
332 : }
333 0 : break;
334 : case 0x0A: // Radical 13 - ref
335 : {
336 0 : aIn >> nRow >> nCol;
337 0 : aIn.Ignore( 9 );
338 0 : ScAddress aAddr(static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab());
339 0 : aSRD.InitAddress(aAddr);
340 0 : aSRD.SetColRel(true);
341 0 : aSRD.SetAddress(aAddr, aEingPos);
342 :
343 0 : aStack << aPool.StoreNlf( aSRD );
344 : }
345 0 : break;
346 : case 0x0B: // RadicalS 13 x ref
347 0 : aIn.Ignore( 13 );
348 0 : aExtensions.push_back( EXTENSION_NLR );
349 0 : aPool << ocBad;
350 0 : aPool >> aStack;
351 0 : break;
352 : case 0x0C: // RwS 4 x ref
353 : case 0x0D: // ColS 4 x ref
354 : case 0x0E: // RwSV 4 x val
355 : case 0x0F: // ColSV 4 x val
356 0 : aIn.Ignore( 4 );
357 0 : aExtensions.push_back( EXTENSION_NLR );
358 0 : aPool << ocBad;
359 0 : aPool >> aStack;
360 0 : break;
361 : case 0x10: // RadicalLel 4 - err
362 : case 0x1D: // SxName 4 - val
363 0 : aIn.Ignore( 4 );
364 0 : aPool << ocBad;
365 0 : aPool >> aStack;
366 0 : break;
367 : default:
368 0 : aPool << ocBad;
369 0 : aPool >> aStack;
370 : }
371 : }
372 0 : break;
373 : case 0x19: // Special Attribute [327 279]
374 : {
375 968 : sal_uInt16 nData(0), nFakt(0);
376 968 : sal_uInt8 nOpt(0);
377 :
378 968 : aIn >> nOpt >> nData;
379 968 : nFakt = 2;
380 :
381 968 : if( nOpt & 0x04 )
382 : {
383 : // nFakt -> skip bytes or words AttrChoose
384 0 : nData++;
385 0 : aIn.Ignore(static_cast<sal_Size>(nData) * nFakt);
386 : }
387 968 : else if( nOpt & 0x10 ) // AttrSum
388 756 : DoMulArgs( ocSum, 1 );
389 : }
390 968 : break;
391 : case 0x1C: // Error Value [314 266]
392 : {
393 126 : aIn >> nByte;
394 :
395 : DefTokenId eOc;
396 126 : switch( nByte )
397 : {
398 : case EXC_ERR_NULL:
399 : case EXC_ERR_DIV0:
400 : case EXC_ERR_VALUE:
401 : case EXC_ERR_REF:
402 : case EXC_ERR_NAME:
403 122 : case EXC_ERR_NUM: eOc = ocStop; break;
404 4 : case EXC_ERR_NA: eOc = ocNotAvail; break;
405 0 : default: eOc = ocNoName;
406 : }
407 126 : aPool << eOc;
408 126 : if( eOc != ocStop )
409 4 : aPool << ocOpen << ocClose;
410 126 : aPool >> aStack;
411 : }
412 126 : break;
413 : case 0x1D: // Boolean [315 266]
414 2 : aIn >> nByte;
415 2 : if( nByte == 0 )
416 0 : aPool << ocFalse << ocOpen << ocClose;
417 : else
418 2 : aPool << ocTrue << ocOpen << ocClose;
419 2 : aPool >> aStack;
420 2 : break;
421 : case 0x1E: // Integer [315 266]
422 1224 : aIn >> nUINT16;
423 1224 : aStack << aPool.Store( ( double ) nUINT16 );
424 1224 : break;
425 : case 0x1F: // Number [315 266]
426 1218 : aIn >> fDouble;
427 1218 : aStack << aPool.Store( fDouble );
428 1218 : break;
429 : case 0x40:
430 : case 0x60:
431 : case 0x20: // Array Constant [317 268]
432 14 : aIn >> nByte >> nUINT16;
433 14 : aIn.Ignore( 4 );
434 14 : if( bAllowArrays )
435 : {
436 14 : aStack << aPool.StoreMatrix();
437 14 : aExtensions.push_back( EXTENSION_ARRAY );
438 : }
439 : else
440 : {
441 0 : aPool << ocBad;
442 0 : aPool >> aStack;
443 : }
444 14 : break;
445 : case 0x41:
446 : case 0x61:
447 : case 0x21: // Function, Fixed Number of Arguments [333 282]
448 : {
449 : sal_uInt16 nXclFunc;
450 5522 : aIn >> nXclFunc;
451 5522 : if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
452 5522 : DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount );
453 : else
454 0 : DoMulArgs( ocNoName, 0 );
455 : }
456 5522 : break;
457 : case 0x42:
458 : case 0x62:
459 : case 0x22: // Function, Variable Number of Arg. [333 283]
460 : {
461 : sal_uInt16 nXclFunc;
462 : sal_uInt8 nParamCount;
463 494 : aIn >> nParamCount >> nXclFunc;
464 494 : nParamCount &= 0x7F;
465 494 : if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
466 494 : DoMulArgs( pFuncInfo->meOpCode, nParamCount );
467 : else
468 0 : DoMulArgs( ocNoName, 0 );
469 : }
470 494 : break;
471 : case 0x43:
472 : case 0x63:
473 : case 0x23: // Name [318 269]
474 : {
475 384 : aIn >> nUINT16;
476 384 : aIn.Ignore( 2 );
477 384 : const XclImpName* pName = GetNameManager().GetName( nUINT16 );
478 384 : if (pName)
479 : {
480 382 : if (pName->IsMacro())
481 : // user-defined macro name.
482 354 : aStack << aPool.Store(ocMacro, pName->GetXclName());
483 : else
484 28 : aStack << aPool.StoreName(nUINT16, pName->IsGlobal());
485 : }
486 : }
487 384 : break;
488 : case 0x44:
489 : case 0x64:
490 : case 0x24: // Cell Reference [319 270]
491 : case 0x4A:
492 : case 0x6A:
493 : case 0x2A: // Deleted Cell Reference [323 273]
494 : {
495 : sal_uInt16 nCol, nRow;
496 :
497 9308 : aIn >> nRow >> nCol;
498 :
499 9308 : aSRD.SetRelTab(0);
500 9308 : aSRD.SetFlag3D( bRangeName && !bCondFormat );
501 :
502 9308 : ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
503 :
504 9308 : switch ( nOp )
505 : {
506 : case 0x4A:
507 : case 0x6A:
508 : case 0x2A: // Deleted Cell Reference [323 273]
509 : // no information which part is deleted, set both
510 0 : aSRD.SetColDeleted( true );
511 0 : aSRD.SetRowDeleted( true );
512 : }
513 :
514 9308 : aStack << aPool.Store( aSRD );
515 : }
516 9308 : break;
517 : case 0x45:
518 : case 0x65:
519 : case 0x25: // Area Reference [320 270]
520 : case 0x4B:
521 : case 0x6B:
522 : case 0x2B: // Deleted Area Refernce [323 273]
523 : {
524 : sal_uInt16 nRowFirst, nRowLast;
525 : sal_uInt16 nColFirst, nColLast;
526 2622 : ScSingleRefData &rSRef1 = aCRD.Ref1;
527 2622 : ScSingleRefData &rSRef2 = aCRD.Ref2;
528 :
529 2622 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
530 :
531 2622 : rSRef1.SetRelTab(0);
532 2622 : rSRef2.SetRelTab(0);
533 2622 : rSRef1.SetFlag3D( bRangeName && !bCondFormat );
534 2622 : rSRef2.SetFlag3D( bRangeName && !bCondFormat );
535 :
536 2622 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
537 2622 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
538 :
539 2622 : if( IsComplColRange( nColFirst, nColLast ) )
540 0 : SetComplCol( aCRD );
541 2622 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
542 0 : SetComplRow( aCRD );
543 :
544 2622 : switch ( nOp )
545 : {
546 : case 0x4B:
547 : case 0x6B:
548 : case 0x2B: // Deleted Area Refernce [323 273]
549 : // no information which part is deleted, set all
550 0 : rSRef1.SetColDeleted( true );
551 0 : rSRef1.SetRowDeleted( true );
552 0 : rSRef2.SetColDeleted( true );
553 0 : rSRef2.SetRowDeleted( true );
554 : }
555 :
556 2622 : aStack << aPool.Store( aCRD );
557 : }
558 2622 : break;
559 : case 0x46:
560 : case 0x66:
561 : case 0x26: // Constant Reference Subexpression [321 271]
562 0 : aExtensions.push_back( EXTENSION_MEMAREA );
563 0 : aIn.Ignore( 6 ); // There isn't any more
564 0 : break;
565 : case 0x47:
566 : case 0x67:
567 : case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
568 0 : aIn.Ignore( 6 ); // There isn't any more
569 0 : break;
570 : case 0x48:
571 : case 0x68:
572 : case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
573 0 : aIn.Ignore( 6 ); // There isn't any more
574 0 : break;
575 : case 0x49:
576 : case 0x69:
577 : case 0x29: // Variable Reference Subexpression [331 281]
578 16 : aIn.Ignore( 2 ); // There isn't any more
579 16 : break;
580 : case 0x4C:
581 : case 0x6C:
582 : case 0x2C: // Cell Reference Within a Name [323 ]
583 : // Cell Reference Within a Shared Formula[ 273]
584 : {
585 : sal_uInt16 nRow, nCol;
586 :
587 318 : aIn >> nRow >> nCol;
588 :
589 318 : aSRD.SetRelTab(0);
590 318 : aSRD.SetFlag3D( bRangeName );
591 :
592 318 : ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
593 :
594 318 : aStack << aPool.Store( aSRD );
595 : }
596 318 : break;
597 : case 0x4D:
598 : case 0x6D:
599 : case 0x2D: // Area Reference Within a Name [324 ]
600 : { // Area Reference Within a Shared Formula[ 274]
601 : sal_uInt16 nRowFirst, nRowLast;
602 : sal_uInt16 nColFirst, nColLast;
603 :
604 10 : aCRD.Ref1.SetRelTab(0);
605 10 : aCRD.Ref2.SetRelTab(0);
606 10 : aCRD.Ref1.SetFlag3D( bRangeName );
607 10 : aCRD.Ref2.SetFlag3D( bRangeName );
608 :
609 10 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
610 :
611 10 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
612 10 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
613 :
614 10 : if( IsComplColRange( nColFirst, nColLast ) )
615 0 : SetComplCol( aCRD );
616 10 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
617 0 : SetComplRow( aCRD );
618 :
619 10 : aStack << aPool.Store( aCRD );
620 : }
621 10 : break;
622 : case 0x4E:
623 : case 0x6E:
624 : case 0x2E: // Reference Subexpression Within a Name [332 282]
625 0 : aIn.Ignore( 2 ); // There isn't any more
626 0 : break;
627 : case 0x4F:
628 : case 0x6F:
629 : case 0x2F: // Incomplete Reference Subexpression... [332 282]
630 0 : aIn.Ignore( 2 ); // There isn't any more
631 0 : break;
632 : case 0x58:
633 : case 0x78:
634 : case 0x38: // Command-Equivalent Function [333 ]
635 0 : aString = "COMM_EQU_FUNC";
636 0 : aIn >> nByte;
637 0 : aString += OUString::number( nByte );
638 0 : aIn >> nByte;
639 0 : aStack << aPool.Store( aString );
640 0 : DoMulArgs( ocPush, nByte + 1 );
641 0 : break;
642 : case 0x59:
643 : case 0x79:
644 : case 0x39: // Name or External Name [ 275]
645 : {
646 : sal_uInt16 nXtiIndex, nNameIdx;
647 0 : aIn >> nXtiIndex >> nNameIdx;
648 0 : aIn.Ignore( 2 );
649 :
650 0 : if( rLinkMan.IsSelfRef( nXtiIndex ) )
651 : {
652 : // internal defined name with explicit sheet, i.e.: =Sheet1!AnyName
653 0 : const XclImpName* pName = GetNameManager().GetName( nNameIdx );
654 0 : if (pName)
655 : {
656 0 : if (pName->GetScRangeData())
657 0 : aStack << aPool.StoreName( nNameIdx, pName->IsGlobal());
658 : else
659 0 : aStack << aPool.Store(ocMacro, pName->GetXclName());
660 : }
661 : }
662 0 : else if( const XclImpExtName* pExtName = rLinkMan.GetExternName( nXtiIndex, nNameIdx ) )
663 : {
664 0 : switch( pExtName->GetType() )
665 : {
666 : case xlExtName:
667 : {
668 : /* FIXME: enable this code for #i4385# once
669 : * external name reference can be stored in ODF,
670 : * which remains to be done for #i3740#. Until then
671 : * create a #NAME? token. */
672 : #if 1
673 : sal_uInt16 nFileId;
674 0 : if (!GetExternalFileIdFromXti(nXtiIndex, nFileId) || !pExtName->HasFormulaTokens())
675 : {
676 0 : aStack << aPool.Store(ocNoName, pExtName->GetName());
677 0 : break;
678 : }
679 :
680 0 : aStack << aPool.StoreExtName(nFileId, pExtName->GetName());
681 0 : pExtName->CreateExtNameData(GetDoc(), nFileId);
682 : #else
683 : aStack << aPool.Store( ocNoName, pExtName->GetName() );
684 : #endif
685 : }
686 0 : break;
687 :
688 : case xlExtAddIn:
689 : {
690 0 : aStack << aPool.Store( ocExternal, pExtName->GetName() );
691 : }
692 0 : break;
693 :
694 : case xlExtDDE:
695 : {
696 0 : OUString aApplic, aTopic;
697 0 : if( rLinkMan.GetLinkData( aApplic, aTopic, nXtiIndex ) )
698 : {
699 0 : TokenId nPar1 = aPool.Store( aApplic );
700 0 : TokenId nPar2 = aPool.Store( aTopic );
701 0 : nMerk0 = aPool.Store( pExtName->GetName() );
702 0 : aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
703 0 : << nMerk0 << ocClose;
704 0 : aPool >> aStack;
705 0 : pExtName->CreateDdeData( GetDoc(), aApplic, aTopic );
706 0 : }
707 : }
708 0 : break;
709 :
710 : case xlExtEuroConvert:
711 : {
712 0 : aStack << aPool.Store( ocEuroConvert, OUString() );
713 : }
714 0 : break;
715 : case xlExtOLE:
716 : {
717 0 : ExternalTabInfo aExtInfo;
718 0 : if (HandleOleLink(nXtiIndex, *pExtName, aExtInfo))
719 : {
720 0 : if (aExtInfo.maRange.aStart == aExtInfo.maRange.aEnd)
721 : {
722 : // single cell
723 0 : aSRD.InitAddress(aExtInfo.maRange.aStart);
724 0 : aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
725 : }
726 : else
727 : {
728 : // range
729 0 : aCRD.InitRange(aExtInfo.maRange);
730 0 : aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
731 : }
732 : }
733 : else
734 0 : aStack << aPool.Store(ocNoName, pExtName->GetName());
735 : }
736 0 : break;
737 : default:
738 : {
739 0 : aPool << ocBad;
740 0 : aPool >> aStack;
741 : }
742 : }
743 : }
744 : else
745 : {
746 0 : aPool << ocBad;
747 0 : aPool >> aStack;
748 : }
749 : }
750 0 : break;
751 : case 0x5A:
752 : case 0x7A:
753 : case 0x3A: // 3-D Cell Reference [ 275]
754 : case 0x5C:
755 : case 0x7C:
756 : case 0x3C: // Deleted 3-D Cell Reference [ 277]
757 : {
758 : sal_uInt16 nIxti, nRw, nGrbitCol;
759 : SCTAB nTabFirst, nTabLast;
760 :
761 256 : aIn >> nIxti >> nRw >> nGrbitCol;
762 :
763 256 : ExternalTabInfo aExtInfo;
764 256 : if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
765 : {
766 0 : aPool << ocBad;
767 0 : aPool >> aStack;
768 0 : break;
769 : }
770 :
771 256 : aSRD.SetAbsTab(nTabFirst);
772 256 : aSRD.SetFlag3D(true);
773 :
774 256 : ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
775 :
776 256 : switch ( nOp )
777 : {
778 : case 0x5C:
779 : case 0x7C:
780 : case 0x3C: // Deleted 3-D Cell Reference [ 277]
781 : // no information which part is deleted, set both
782 0 : aSRD.SetColDeleted( true );
783 0 : aSRD.SetRowDeleted( true );
784 : }
785 :
786 256 : if (aExtInfo.mbExternal)
787 : {
788 : // nTabFirst and nTabLast are the indices of the refernced
789 : // sheets in the SUPBOOK record, hence do not represent
790 : // the actual indices of the original sheets since the
791 : // SUPBOOK record only stores referenced sheets and skips
792 : // the ones that are not referenced.
793 :
794 4 : if (nTabLast != nTabFirst)
795 : {
796 0 : aCRD.Ref1 = aCRD.Ref2 = aSRD;
797 0 : aCRD.Ref2.SetAbsTab(nTabLast);
798 0 : aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
799 : }
800 : else
801 4 : aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
802 : }
803 : else
804 : {
805 252 : if ( !ValidTab(nTabFirst))
806 0 : aSRD.SetTabDeleted( true );
807 :
808 252 : if( nTabLast != nTabFirst )
809 : {
810 0 : aCRD.Ref1 = aCRD.Ref2 = aSRD;
811 0 : aCRD.Ref2.SetAbsTab(nTabLast);
812 0 : aCRD.Ref2.SetTabDeleted( !ValidTab(nTabLast) );
813 0 : aStack << aPool.Store( aCRD );
814 : }
815 : else
816 252 : aStack << aPool.Store( aSRD );
817 256 : }
818 : }
819 256 : break;
820 : case 0x5B:
821 : case 0x7B:
822 : case 0x3B: // 3-D Area Reference [ 276]
823 : case 0x5D:
824 : case 0x7D:
825 : case 0x3D: // Deleted 3-D Area Reference [ 277]
826 : {
827 : sal_uInt16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
828 : SCTAB nTabFirst, nTabLast;
829 2062 : aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
830 :
831 2062 : ExternalTabInfo aExtInfo;
832 2062 : if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
833 : {
834 0 : aPool << ocBad;
835 0 : aPool >> aStack;
836 0 : break;
837 : }
838 2062 : ScSingleRefData &rR1 = aCRD.Ref1;
839 2062 : ScSingleRefData &rR2 = aCRD.Ref2;
840 :
841 2062 : rR1.SetAbsTab(nTabFirst);
842 2062 : rR2.SetAbsTab(nTabLast);
843 2062 : rR1.SetFlag3D(true);
844 2062 : rR2.SetFlag3D( nTabFirst != nTabLast );
845 :
846 2062 : ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
847 2062 : ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
848 :
849 2062 : if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
850 0 : SetComplCol( aCRD );
851 2062 : else if( IsComplRowRange( nRw1, nRw2 ) )
852 0 : SetComplRow( aCRD );
853 :
854 2062 : switch ( nOp )
855 : {
856 : case 0x5D:
857 : case 0x7D:
858 : case 0x3D: // Deleted 3-D Area Reference [ 277]
859 : // no information which part is deleted, set all
860 4 : rR1.SetColDeleted( true );
861 4 : rR1.SetRowDeleted( true );
862 4 : rR2.SetColDeleted( true );
863 4 : rR2.SetRowDeleted( true );
864 : }
865 :
866 2062 : if (aExtInfo.mbExternal)
867 : {
868 0 : aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
869 : }
870 : else
871 : {
872 2062 : if ( !ValidTab(nTabFirst) )
873 0 : rR1.SetTabDeleted( true );
874 2062 : if ( !ValidTab(nTabLast) )
875 0 : rR2.SetTabDeleted( true );
876 :
877 2062 : aStack << aPool.Store( aCRD );
878 2062 : }
879 : }
880 2062 : break;
881 2 : default: bError = true;
882 : }
883 42142 : bError |= !aIn.IsValid();
884 : }
885 :
886 : ConvErr eRet;
887 :
888 6000 : if( bError )
889 : {
890 2 : aPool << ocBad;
891 2 : aPool >> aStack;
892 2 : rpTokArray = aPool[ aStack.Get() ];
893 2 : eRet = ConvErrNi;
894 : }
895 5998 : else if( aIn.GetRecPos() != nEndPos )
896 : {
897 0 : aPool << ocBad;
898 0 : aPool >> aStack;
899 0 : rpTokArray = aPool[ aStack.Get() ];
900 0 : eRet = ConvErrCount;
901 : }
902 5998 : else if( bArrayFormula )
903 : {
904 114 : rpTokArray = NULL;
905 114 : eRet = ConvOK;
906 : }
907 : else
908 : {
909 5884 : rpTokArray = aPool[ aStack.Get() ];
910 5884 : eRet = ConvOK;
911 : }
912 :
913 6000 : aIn.Seek( nEndPos );
914 :
915 6000 : if( eRet == ConvOK)
916 5998 : ReadExtensions( aExtensions, aIn );
917 :
918 12000 : return eRet;
919 : }
920 :
921 : // stream seeks to first byte after <nFormulaLen>
922 10 : ConvErr ExcelToSc8::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen,
923 : SCsTAB nTab, const FORMULA_TYPE eFT )
924 : {
925 : sal_uInt8 nOp, nLen;
926 10 : bool bError = false;
927 10 : const bool bCondFormat = eFT == FT_CondFormat;
928 10 : const bool bRangeName = eFT == FT_RangeName || bCondFormat;
929 10 : const bool bSharedFormula = eFT == FT_SharedFormula;
930 10 : const bool bRNorSF = bRangeName || bSharedFormula;
931 :
932 : ScSingleRefData aSRD;
933 : ScComplexRefData aCRD;
934 :
935 10 : bExternName = false;
936 :
937 10 : if( eStatus != ConvOK )
938 : {
939 0 : aIn.Ignore( nFormulaLen );
940 0 : return eStatus;
941 : }
942 :
943 10 : if( nFormulaLen == 0 )
944 0 : return ConvOK;
945 :
946 10 : sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
947 :
948 48 : while( (aIn.GetRecPos() < nEndPos) && !bError )
949 : {
950 28 : aIn >> nOp;
951 :
952 : // always reset flags
953 28 : aSRD.InitFlags();
954 28 : aCRD.InitFlags();
955 :
956 28 : switch( nOp ) // book page:
957 : { // SDK4 SDK5
958 : case 0x01: // Array Formula [325 ]
959 : // Array Formula or Shared Formula [ 277]
960 0 : aIn.Ignore( 4 );
961 0 : break;
962 : case 0x02: // Data Table [325 277]
963 0 : aIn.Ignore( 4 );
964 0 : break;
965 : case 0x03: // Addition [312 264]
966 : case 0x04: // Subtraction [313 264]
967 : case 0x05: // Multiplication [313 264]
968 : case 0x06: // Division [313 264]
969 : case 0x07: // Exponetiation [313 265]
970 : case 0x08: // Concatenation [313 265]
971 : case 0x09: // Less Than [313 265]
972 : case 0x0A: // Less Than or Equal [313 265]
973 : case 0x0B: // Equal [313 265]
974 : case 0x0C: // Greater Than or Equal [313 265]
975 : case 0x0D: // Greater Than [313 265]
976 : case 0x0E: // Not Equal [313 265]
977 : case 0x0F: // Intersection [314 265]
978 : case 0x10: // Union [314 265]
979 : case 0x11: // Range [314 265]
980 : case 0x12: // Unary Plus [312 264]
981 : case 0x13: // Unary Minus [312 264]
982 : case 0x14: // Percent Sign [312 264]
983 : case 0x15: // Parenthesis [326 278]
984 : case 0x16: // Missing Argument [314 266]
985 6 : break;
986 : case 0x17: // String Constant [314 266]
987 0 : aIn >> nLen; // und?
988 :
989 0 : aIn.IgnoreUniString( nLen ); // reads Grbit even if nLen==0
990 0 : break;
991 : case 0x19: // Special Attribute [327 279]
992 : {
993 0 : sal_uInt16 nData(0), nFakt(0);
994 0 : sal_uInt8 nOpt(0);
995 :
996 0 : aIn >> nOpt >> nData;
997 0 : nFakt = 2;
998 :
999 0 : if( nOpt & 0x04 )
1000 : {
1001 : // nFakt -> skip bytes or words AttrChoose
1002 0 : ++nData;
1003 0 : aIn.Ignore(static_cast<sal_Size>(nData) * nFakt);
1004 : }
1005 : }
1006 0 : break;
1007 : case 0x1C: // Error Value [314 266]
1008 : case 0x1D: // Boolean [315 266]
1009 0 : aIn.Ignore( 1 );
1010 0 : break;
1011 : case 0x1E: // Integer [315 266]
1012 0 : aIn.Ignore( 2 );
1013 0 : break;
1014 : case 0x1F: // Number [315 266]
1015 0 : aIn.Ignore( 8 );
1016 0 : break;
1017 : case 0x40:
1018 : case 0x60:
1019 : case 0x20: // Array Constant [317 268]
1020 0 : aIn.Ignore( 7 );
1021 0 : break;
1022 : case 0x41:
1023 : case 0x61:
1024 : case 0x21: // Function, Fixed Number of Arguments [333 282]
1025 0 : aIn.Ignore( 2 );
1026 0 : break;
1027 : case 0x42:
1028 : case 0x62:
1029 : case 0x22: // Function, Variable Number of Arg. [333 283]
1030 0 : aIn.Ignore( 3 );
1031 0 : break;
1032 : case 0x43:
1033 : case 0x63:
1034 : case 0x23: // Name [318 269]
1035 0 : aIn.Ignore( 4 );
1036 0 : break;
1037 : case 0x44:
1038 : case 0x64:
1039 : case 0x24: // Cell Reference [319 270]
1040 : {
1041 : sal_uInt16 nCol, nRow;
1042 :
1043 0 : aIn >> nRow >> nCol;
1044 :
1045 0 : aSRD.SetRelTab(0);
1046 0 : aSRD.SetFlag3D( bRangeName && !bCondFormat );
1047 :
1048 0 : ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
1049 :
1050 0 : rRangeList.Append(aSRD.toAbs(aEingPos), nTab);
1051 : }
1052 0 : break;
1053 : case 0x45:
1054 : case 0x65:
1055 : case 0x25: // Area Reference [320 270]
1056 : {
1057 : sal_uInt16 nRowFirst, nRowLast;
1058 : sal_uInt16 nColFirst, nColLast;
1059 0 : ScSingleRefData &rSRef1 = aCRD.Ref1;
1060 0 : ScSingleRefData &rSRef2 = aCRD.Ref2;
1061 :
1062 0 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1063 :
1064 0 : rSRef1.SetRelTab(0);
1065 0 : rSRef2.SetRelTab(0);
1066 0 : rSRef1.SetFlag3D( bRangeName && !bCondFormat );
1067 0 : rSRef2.SetFlag3D( bRangeName && !bCondFormat );
1068 :
1069 0 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
1070 0 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
1071 :
1072 0 : if( IsComplColRange( nColFirst, nColLast ) )
1073 0 : SetComplCol( aCRD );
1074 0 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
1075 0 : SetComplRow( aCRD );
1076 :
1077 0 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1078 : }
1079 0 : break;
1080 : case 0x46:
1081 : case 0x66:
1082 : case 0x26: // Constant Reference Subexpression [321 271]
1083 : case 0x47:
1084 : case 0x67:
1085 : case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
1086 : case 0x48:
1087 : case 0x68:
1088 : case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1089 0 : aIn.Ignore( 6 ); // There isn't any more
1090 0 : break;
1091 : case 0x49:
1092 : case 0x69:
1093 : case 0x29: // Variable Reference Subexpression [331 281]
1094 6 : aIn.Ignore( 2 ); // There isn't any more
1095 6 : break;
1096 : case 0x4A:
1097 : case 0x6A:
1098 : case 0x2A: // Deleted Cell Reference [323 273]
1099 0 : aIn.Ignore( 3 );
1100 0 : break;
1101 : case 0x4B:
1102 : case 0x6B:
1103 : case 0x2B: // Deleted Area Refernce [323 273]
1104 0 : aIn.Ignore( 6 );
1105 0 : break;
1106 : case 0x4C:
1107 : case 0x6C:
1108 : case 0x2C: // Cell Reference Within a Name [323 ]
1109 : // Cell Reference Within a Shared Formula[ 273]
1110 : {
1111 : sal_uInt16 nRow, nCol;
1112 :
1113 0 : aIn >> nRow >> nCol;
1114 :
1115 0 : aSRD.SetRelTab(0);
1116 0 : aSRD.SetFlag3D( bRangeName );
1117 :
1118 0 : ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
1119 :
1120 0 : rRangeList.Append(aSRD.toAbs(aEingPos), nTab);
1121 : }
1122 0 : break;
1123 : case 0x4D:
1124 : case 0x6D:
1125 : case 0x2D: // Area Reference Within a Name [324 ]
1126 : { // Area Reference Within a Shared Formula[ 274]
1127 : sal_uInt16 nRowFirst, nRowLast;
1128 : sal_uInt16 nColFirst, nColLast;
1129 :
1130 0 : aCRD.Ref1.SetRelTab(0);
1131 0 : aCRD.Ref2.SetRelTab(0);
1132 0 : aCRD.Ref1.SetFlag3D( bRangeName );
1133 0 : aCRD.Ref2.SetFlag3D( bRangeName );
1134 :
1135 0 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1136 :
1137 0 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
1138 0 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
1139 :
1140 0 : if( IsComplColRange( nColFirst, nColLast ) )
1141 0 : SetComplCol( aCRD );
1142 0 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
1143 0 : SetComplRow( aCRD );
1144 :
1145 0 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1146 : }
1147 0 : break;
1148 : case 0x4E:
1149 : case 0x6E:
1150 : case 0x2E: // Reference Subexpression Within a Name [332 282]
1151 : case 0x4F:
1152 : case 0x6F:
1153 : case 0x2F: // Incomplete Reference Subexpression... [332 282]
1154 : case 0x58:
1155 : case 0x78:
1156 : case 0x38: // Command-Equivalent Function [333 ]
1157 0 : aIn.Ignore( 2 );
1158 0 : break;
1159 : case 0x59:
1160 : case 0x79:
1161 : case 0x39: // Name or External Name [ 275]
1162 0 : aIn.Ignore( 24 );
1163 0 : break;
1164 : case 0x5A:
1165 : case 0x7A:
1166 : case 0x3A: // 3-D Cell Reference [ 275]
1167 : {
1168 : sal_uInt16 nIxti, nRw, nGrbitCol;
1169 :
1170 0 : aIn >> nIxti >> nRw >> nGrbitCol;
1171 :
1172 : SCTAB nFirstScTab, nLastScTab;
1173 0 : if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
1174 : {
1175 0 : aSRD.SetAbsTab(nFirstScTab);
1176 0 : aSRD.SetFlag3D(true);
1177 :
1178 0 : ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
1179 :
1180 0 : if( nFirstScTab != nLastScTab )
1181 : {
1182 0 : aCRD.Ref1 = aSRD;
1183 0 : aCRD.Ref2 = aSRD;
1184 0 : aCRD.Ref2.SetAbsTab(nLastScTab);
1185 0 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1186 : }
1187 : else
1188 0 : rRangeList.Append(aSRD.toAbs(aEingPos), nTab);
1189 : }
1190 : }
1191 0 : break;
1192 : case 0x5B:
1193 : case 0x7B:
1194 : case 0x3B: // 3-D Area Reference [ 276]
1195 : {
1196 : sal_uInt16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
1197 :
1198 16 : aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
1199 :
1200 : SCTAB nFirstScTab, nLastScTab;
1201 16 : if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
1202 : {
1203 16 : ScSingleRefData &rR1 = aCRD.Ref1;
1204 16 : ScSingleRefData &rR2 = aCRD.Ref2;
1205 :
1206 16 : rR1.SetAbsTab(nFirstScTab);
1207 16 : rR2.SetAbsTab(nLastScTab);
1208 16 : rR1.SetFlag3D(true);
1209 16 : rR2.SetFlag3D( nFirstScTab != nLastScTab );
1210 :
1211 16 : ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
1212 16 : ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
1213 :
1214 16 : if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
1215 0 : SetComplCol( aCRD );
1216 16 : else if( IsComplRowRange( nRw1, nRw2 ) )
1217 0 : SetComplRow( aCRD );
1218 :
1219 16 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1220 : }
1221 : }
1222 16 : break;
1223 : case 0x5C:
1224 : case 0x7C:
1225 : case 0x3C: // Deleted 3-D Cell Reference [ 277]
1226 0 : aIn.Ignore( 6 );
1227 0 : break;
1228 : case 0x5D:
1229 : case 0x7D:
1230 : case 0x3D: // Deleted 3-D Area Reference [ 277]
1231 0 : aIn.Ignore( 10 );
1232 0 : break;
1233 : default:
1234 0 : bError = true;
1235 : }
1236 28 : bError |= !aIn.IsValid();
1237 : }
1238 :
1239 : ConvErr eRet;
1240 :
1241 10 : if( bError )
1242 0 : eRet = ConvErrNi;
1243 10 : else if( aIn.GetRecPos() != nEndPos )
1244 0 : eRet = ConvErrCount;
1245 10 : else if( bExternName )
1246 0 : eRet = ConvErrExternal;
1247 : else
1248 10 : eRet = ConvOK;
1249 :
1250 10 : aIn.Seek( nEndPos );
1251 10 : return eRet;
1252 : }
1253 :
1254 0 : ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
1255 : const OUString& rUrl, const vector<OUString>& rTabNames )
1256 : {
1257 0 : if( !GetDocShell() )
1258 0 : return ConvErrNi;
1259 :
1260 0 : OUString aFileUrl = ScGlobal::GetAbsDocName(rUrl, GetDocShell());
1261 :
1262 : sal_uInt8 nOp, nByte;
1263 0 : bool bError = false;
1264 :
1265 : ScSingleRefData aSRD;
1266 : ScComplexRefData aCRD;
1267 :
1268 0 : if (eStatus != ConvOK)
1269 : {
1270 0 : rStrm.Ignore(nFormulaLen);
1271 0 : return eStatus;
1272 : }
1273 :
1274 0 : if (nFormulaLen == 0)
1275 : {
1276 0 : aPool.Store(OUString("-/-"));
1277 0 : aPool >> aStack;
1278 0 : rpArray = aPool[aStack.Get()];
1279 0 : return ConvOK;
1280 : }
1281 :
1282 0 : ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1283 0 : sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFileUrl);
1284 0 : sal_uInt16 nTabCount = static_cast< sal_uInt16 >( rTabNames.size() );
1285 :
1286 0 : sal_Size nEndPos = rStrm.GetRecPos() + nFormulaLen;
1287 :
1288 0 : while( (rStrm.GetRecPos() < nEndPos) && !bError )
1289 : {
1290 0 : rStrm >> nOp;
1291 :
1292 : // always reset flags
1293 0 : aSRD.InitFlags();
1294 0 : aCRD.InitFlags();
1295 :
1296 0 : switch( nOp )
1297 : {
1298 : case 0x1C: // Error Value
1299 : {
1300 0 : rStrm >> nByte;
1301 : DefTokenId eOc;
1302 0 : switch( nByte )
1303 : {
1304 : case EXC_ERR_NULL:
1305 : case EXC_ERR_DIV0:
1306 : case EXC_ERR_VALUE:
1307 : case EXC_ERR_REF:
1308 : case EXC_ERR_NAME:
1309 0 : case EXC_ERR_NUM: eOc = ocStop; break;
1310 0 : case EXC_ERR_NA: eOc = ocNotAvail; break;
1311 0 : default: eOc = ocNoName;
1312 : }
1313 0 : aPool << eOc;
1314 0 : if( eOc != ocStop )
1315 0 : aPool << ocOpen << ocClose;
1316 0 : aPool >> aStack;
1317 : }
1318 0 : break;
1319 : case 0x3A:
1320 : {
1321 : // cell reference in external range name
1322 : sal_uInt16 nExtTab1, nExtTab2, nRow, nGrbitCol;
1323 0 : rStrm >> nExtTab1 >> nExtTab2 >> nRow >> nGrbitCol;
1324 0 : if (nExtTab1 >= nTabCount || nExtTab2 >= nTabCount)
1325 : {
1326 0 : bError = true;
1327 0 : break;
1328 : }
1329 :
1330 0 : aSRD.SetAbsTab(nExtTab1);
1331 0 : aSRD.SetFlag3D(true);
1332 0 : ExcRelToScRel8(nRow, nGrbitCol, aSRD, true);
1333 0 : aCRD.Ref1 = aCRD.Ref2 = aSRD;
1334 0 : OUString aTabName = rTabNames[nExtTab1];
1335 :
1336 0 : if (nExtTab1 == nExtTab2)
1337 : {
1338 : // single cell reference
1339 0 : aStack << aPool.StoreExtRef(nFileId, aTabName, aSRD);
1340 : }
1341 : else
1342 : {
1343 : // area reference
1344 0 : aCRD.Ref2.SetAbsTab(nExtTab2);
1345 0 : aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
1346 0 : }
1347 : }
1348 0 : break;
1349 : case 0x3B:
1350 : {
1351 : // area reference
1352 : sal_uInt16 nExtTab1, nExtTab2, nRow1, nRow2, nGrbitCol1, nGrbitCol2;
1353 0 : rStrm >> nExtTab1 >> nExtTab2 >> nRow1 >> nRow2 >> nGrbitCol1 >> nGrbitCol2;
1354 0 : ScSingleRefData& rR1 = aCRD.Ref1;
1355 0 : ScSingleRefData& rR2 = aCRD.Ref2;
1356 :
1357 0 : rR1.SetAbsTab(nExtTab1);
1358 0 : rR1.SetFlag3D(true);
1359 0 : ExcRelToScRel8(nRow1, nGrbitCol1, rR1, true);
1360 :
1361 0 : rR2.SetAbsTab(nExtTab2);
1362 0 : rR2.SetFlag3D(true);
1363 0 : ExcRelToScRel8(nRow2, nGrbitCol2, rR2, true);
1364 :
1365 0 : OUString aTabName = rTabNames[nExtTab1];
1366 0 : aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
1367 : }
1368 0 : break;
1369 : default:
1370 0 : bError = true;
1371 : }
1372 0 : bError |= !rStrm.IsValid();
1373 : }
1374 :
1375 : ConvErr eRet;
1376 :
1377 0 : if( bError )
1378 : {
1379 0 : aPool << ocBad;
1380 0 : aPool >> aStack;
1381 0 : rpArray = aPool[ aStack.Get() ];
1382 0 : eRet = ConvErrNi;
1383 : }
1384 0 : else if( rStrm.GetRecPos() != nEndPos )
1385 : {
1386 0 : aPool << ocBad;
1387 0 : aPool >> aStack;
1388 0 : rpArray = aPool[ aStack.Get() ];
1389 0 : eRet = ConvErrCount;
1390 : }
1391 : else
1392 : {
1393 0 : rpArray = aPool[ aStack.Get() ];
1394 0 : eRet = ConvOK;
1395 : }
1396 :
1397 0 : rStrm.Seek(nEndPos);
1398 0 : return eRet;
1399 : }
1400 :
1401 19302 : void ExcelToSc8::ExcRelToScRel8( sal_uInt16 nRow, sal_uInt16 nC, ScSingleRefData &rSRD, const bool bName )
1402 : {
1403 19302 : const bool bColRel = ( nC & 0x4000 ) != 0;
1404 19302 : const bool bRowRel = ( nC & 0x8000 ) != 0;
1405 19302 : const sal_uInt8 nCol = static_cast<sal_uInt8>(nC);
1406 :
1407 19302 : if( bName )
1408 : {
1409 : // C O L
1410 692 : if( bColRel )
1411 254 : rSRD.SetRelCol(static_cast<SCCOL>(static_cast<sal_Int8>(nC)));
1412 : else
1413 438 : rSRD.SetAbsCol(static_cast<SCCOL>(nCol));
1414 :
1415 : // R O W
1416 692 : if( bRowRel )
1417 254 : rSRD.SetRelRow(static_cast<sal_Int16>(nRow));
1418 : else
1419 438 : rSRD.SetAbsRow(std::min( static_cast<SCROW>(nRow), MAXROW));
1420 : }
1421 : else
1422 : {
1423 : // C O L
1424 18610 : if ( bColRel )
1425 17758 : rSRD.SetRelCol(static_cast<SCCOL>(nCol) - aEingPos.Col());
1426 : else
1427 852 : rSRD.SetAbsCol(nCol);
1428 :
1429 : // R O W
1430 18610 : if ( bRowRel )
1431 17662 : rSRD.SetRelRow(static_cast<SCROW>(nRow) - aEingPos.Row());
1432 : else
1433 948 : rSRD.SetAbsRow(nRow);
1434 : }
1435 19302 : }
1436 :
1437 : // stream seeks to first byte after <nLen>
1438 4 : bool ExcelToSc8::GetAbsRefs( ScRangeList& r, XclImpStream& aIn, sal_Size nLen )
1439 : {
1440 : sal_uInt8 nOp;
1441 : sal_uInt16 nRow1, nRow2, nCol1, nCol2;
1442 : SCTAB nTab1, nTab2;
1443 : sal_uInt16 nIxti;
1444 :
1445 : sal_Size nSeek;
1446 :
1447 4 : sal_Size nEndPos = aIn.GetRecPos() + nLen;
1448 :
1449 12 : while( aIn.IsValid() && (aIn.GetRecPos() < nEndPos) )
1450 : {
1451 4 : aIn >> nOp;
1452 4 : nSeek = 0;
1453 :
1454 4 : switch( nOp )
1455 : {
1456 : case 0x44:
1457 : case 0x64:
1458 : case 0x24: // Cell Reference [319 270]
1459 : case 0x4C:
1460 : case 0x6C:
1461 : case 0x2C: // Cell Reference Within a Name [323 ]
1462 : // Cell Reference Within a Shared Formula[ 273]
1463 2 : aIn >> nRow1 >> nCol1;
1464 :
1465 2 : nRow2 = nRow1;
1466 2 : nCol2 = nCol1;
1467 2 : nTab1 = nTab2 = GetCurrScTab();
1468 2 : goto _common;
1469 : case 0x45:
1470 : case 0x65:
1471 : case 0x25: // Area Reference [320 270]
1472 : case 0x4D:
1473 : case 0x6D:
1474 : case 0x2D: // Area Reference Within a Name [324 ]
1475 : // Area Reference Within a Shared Formula[ 274]
1476 2 : aIn >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1477 :
1478 2 : nTab1 = nTab2 = GetCurrScTab();
1479 2 : goto _common;
1480 : case 0x5A:
1481 : case 0x7A:
1482 : case 0x3A: // 3-D Cell Reference [ 275]
1483 0 : aIn >> nIxti >> nRow1 >> nCol1;
1484 :
1485 0 : nRow2 = nRow1;
1486 0 : nCol2 = nCol1;
1487 :
1488 0 : goto _3d_common;
1489 : case 0x5B:
1490 : case 0x7B:
1491 : case 0x3B: // 3-D Area Reference [ 276]
1492 0 : aIn >> nIxti >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1493 :
1494 : _3d_common:
1495 : // skip references to deleted sheets
1496 0 : if( !rLinkMan.GetScTabRange( nTab1, nTab2, nIxti ) || !ValidTab( nTab1 ) || !ValidTab( nTab2 ) )
1497 0 : break;
1498 :
1499 0 : goto _common;
1500 : _common:
1501 : // do not check abs/rel flags, linked controls have set them!
1502 : {
1503 4 : ScRange aScRange;
1504 4 : nCol1 &= 0x3FFF;
1505 4 : nCol2 &= 0x3FFF;
1506 4 : if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
1507 4 : r.Append( aScRange );
1508 : }
1509 4 : break;
1510 : case 0x1C: // Error Value [314 266]
1511 : case 0x1D: // Boolean [315 266]
1512 0 : nSeek = 1;
1513 0 : break;
1514 : case 0x1E: // Integer [315 266]
1515 : case 0x41:
1516 : case 0x61:
1517 : case 0x21: // Function, Fixed Number of Arguments [333 282]
1518 : case 0x49:
1519 : case 0x69:
1520 : case 0x29: // Variable Reference Subexpression [331 281]
1521 : case 0x4E:
1522 : case 0x6E:
1523 : case 0x2E: // Reference Subexpression Within a Name [332 282]
1524 : case 0x4F:
1525 : case 0x6F:
1526 : case 0x2F: // Incomplete Reference Subexpression... [332 282]
1527 : case 0x58:
1528 : case 0x78:
1529 : case 0x38: // Command-Equivalent Function [333 ]
1530 0 : nSeek = 2;
1531 0 : break;
1532 : case 0x42:
1533 : case 0x62:
1534 : case 0x22: // Function, Variable Number of Arg. [333 283]
1535 0 : nSeek = 3;
1536 0 : break;
1537 : case 0x01: // Array Formula [325 ]
1538 : case 0x02: // Data Table [325 277]
1539 : case 0x43:
1540 : case 0x63:
1541 : case 0x23: // Name [318 269]
1542 : case 0x4A:
1543 : case 0x6A:
1544 : case 0x2A: // Deleted Cell Reference [323 273]
1545 0 : nSeek = 4;
1546 0 : break;
1547 : case 0x46:
1548 : case 0x66:
1549 : case 0x26: // Constant Reference Subexpression [321 271]
1550 : case 0x47:
1551 : case 0x67:
1552 : case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
1553 : case 0x48:
1554 : case 0x68:
1555 : case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1556 : case 0x5C:
1557 : case 0x7C:
1558 : case 0x3C: // Deleted 3-D Cell Reference [ 277]
1559 : case 0x59:
1560 : case 0x79:
1561 : case 0x39: // Name or External Name [ 275]
1562 0 : nSeek = 6;
1563 0 : break;
1564 : case 0x40:
1565 : case 0x60:
1566 : case 0x20: // Array Constant [317 268]
1567 0 : nSeek = 7;
1568 0 : break;
1569 : case 0x1F: // Number [315 266]
1570 : case 0x4B:
1571 : case 0x6B:
1572 : case 0x2B: // Deleted Area Refernce [323 273]
1573 0 : nSeek = 8;
1574 0 : break;
1575 : case 0x5D:
1576 : case 0x7D:
1577 : case 0x3D: // Deleted 3-D Area Reference [ 277]
1578 0 : nSeek = 10;
1579 0 : break;
1580 : case 0x17: // String Constant [314 266]
1581 : {
1582 : sal_uInt8 nStrLen;
1583 0 : aIn >> nStrLen;
1584 0 : aIn.IgnoreUniString( nStrLen ); // reads Grbit even if nLen==0
1585 0 : nSeek = 0;
1586 : }
1587 0 : break;
1588 : case 0x19: // Special Attribute [327 279]
1589 : {
1590 : sal_uInt16 nData;
1591 : sal_uInt8 nOpt;
1592 0 : aIn >> nOpt >> nData;
1593 0 : if( nOpt & 0x04 )
1594 : {// nFakt -> skip bytes or words AttrChoose
1595 0 : nData++;
1596 0 : nSeek = nData * 2;
1597 : }
1598 : }
1599 0 : break;
1600 : }
1601 :
1602 4 : aIn.Ignore( nSeek );
1603 : }
1604 4 : aIn.Seek( nEndPos );
1605 :
1606 4 : return !r.empty();
1607 48 : }
1608 :
1609 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|