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 0 : ExcelToSc8::ExternalTabInfo::ExternalTabInfo() :
78 0 : mnFileId(0), mbExternal(false)
79 : {
80 0 : }
81 :
82 0 : ExcelToSc8::ExcelToSc8( const XclImpRoot& rRoot ) :
83 : ExcelToSc( rRoot ),
84 0 : rLinkMan( rRoot.GetLinkManager() )
85 : {
86 0 : }
87 :
88 :
89 0 : ExcelToSc8::~ExcelToSc8()
90 : {
91 0 : }
92 :
93 0 : bool ExcelToSc8::GetExternalFileIdFromXti( sal_uInt16 nIxti, sal_uInt16& rFileId ) const
94 : {
95 0 : const OUString* pFileUrl = rLinkMan.GetSupbookUrl(nIxti);
96 0 : if (!pFileUrl || pFileUrl->isEmpty() || !GetDocShell())
97 0 : return false;
98 :
99 0 : OUString aFileUrl = ScGlobal::GetAbsDocName(*pFileUrl, GetDocShell());
100 0 : ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
101 0 : rFileId = pRefMgr->getExternalFileId(aFileUrl);
102 :
103 0 : return true;
104 : }
105 :
106 0 : bool ExcelToSc8::Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo )
107 : {
108 0 : rFirstTab = rLastTab = 0;
109 0 : rExtInfo.mbExternal = !rLinkMan.IsSelfRef(nIxti);
110 0 : bool bSuccess = rLinkMan.GetScTabRange(rFirstTab, rLastTab, nIxti);
111 0 : if (!bSuccess)
112 0 : return false;
113 :
114 0 : if (!rExtInfo.mbExternal)
115 : // This is internal reference. Stop here.
116 0 : return true;
117 :
118 0 : rExtInfo.maTabName = rLinkMan.GetSupbookTabName(nIxti, rFirstTab);
119 0 : return GetExternalFileIdFromXti(nIxti, rExtInfo.mnFileId);
120 : }
121 :
122 0 : bool ExcelToSc8::HandleOleLink(sal_uInt16 nXtiIndex, const XclImpExtName& rExtName, ExternalTabInfo& rExtInfo)
123 : {
124 0 : const OUString* pUrl = rLinkMan.GetSupbookUrl(nXtiIndex);
125 0 : if (!pUrl)
126 0 : return false;
127 :
128 0 : OUString aPath;
129 0 : if (!extractFilePath(*pUrl, aPath))
130 : // file path extraction failed.
131 0 : return false;
132 :
133 0 : OUString aFileUrl = ScGlobal::GetAbsDocName(aPath, GetDocShell());
134 0 : return rExtName.CreateOleData(GetDoc(), aFileUrl, rExtInfo.mnFileId, rExtInfo.maTabName, rExtInfo.maRange);
135 : }
136 :
137 : // if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
138 : // otherwise it will seek to the first byte past additional content after <nFormulaLen>
139 0 : ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
140 : {
141 : sal_uInt8 nOp, nLen, nByte;
142 : sal_uInt16 nUINT16;
143 : double fDouble;
144 0 : OUString aString;
145 0 : bool bError = false;
146 0 : sal_Bool bArrayFormula = false;
147 0 : TokenId nMerk0;
148 0 : const bool bCondFormat = eFT == FT_CondFormat;
149 0 : const bool bRangeName = eFT == FT_RangeName || bCondFormat;
150 0 : const bool bSharedFormula = eFT == FT_SharedFormula;
151 0 : const bool bRNorSF = bRangeName || bSharedFormula;
152 :
153 : ScSingleRefData aSRD;
154 : ScComplexRefData aCRD;
155 0 : ExtensionTypeVec aExtensions;
156 :
157 0 : if( eStatus != ConvOK )
158 : {
159 0 : aIn.Ignore( nFormulaLen );
160 0 : return eStatus;
161 : }
162 :
163 0 : if( nFormulaLen == 0 )
164 : {
165 0 : aPool.Store( OUString( "-/-" ) );
166 0 : aPool >> aStack;
167 0 : rpTokArray = aPool[ aStack.Get() ];
168 0 : return ConvOK;
169 : }
170 :
171 0 : sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
172 :
173 0 : while( (aIn.GetRecPos() < nEndPos) && !bError )
174 : {
175 0 : aIn >> nOp;
176 :
177 : // always reset flags
178 0 : aSRD.InitFlags();
179 0 : aCRD.InitFlags();
180 :
181 0 : switch( nOp ) // book page:
182 : { // SDK4 SDK5
183 : case 0x01: // Array Formula [325 ]
184 : // Array Formula or Shared Formula [ 277]
185 : case 0x02: // Data Table [325 277]
186 0 : aIn.Ignore( 4 );
187 :
188 0 : bArrayFormula = sal_True;
189 0 : break;
190 : case 0x03: // Addition [312 264]
191 0 : aStack >> nMerk0;
192 0 : aPool << aStack << ocAdd << nMerk0;
193 0 : aPool >> aStack;
194 0 : break;
195 : case 0x04: // Subtraction [313 264]
196 : // SECOND-TOP minus TOP
197 0 : aStack >> nMerk0;
198 0 : aPool << aStack << ocSub << nMerk0;
199 0 : aPool >> aStack;
200 0 : break;
201 : case 0x05: // Multiplication [313 264]
202 0 : aStack >> nMerk0;
203 0 : aPool << aStack << ocMul << nMerk0;
204 0 : aPool >> aStack;
205 0 : break;
206 : case 0x06: // Division [313 264]
207 : // divide TOP by SECOND-TOP
208 0 : aStack >> nMerk0;
209 0 : aPool << aStack << ocDiv << nMerk0;
210 0 : aPool >> aStack;
211 0 : break;
212 : case 0x07: // Exponentiation [313 265]
213 : // raise SECOND-TOP to power of TOP
214 0 : aStack >> nMerk0;
215 0 : aPool << aStack << ocPow << nMerk0;
216 0 : aPool >> aStack;
217 0 : break;
218 : case 0x08: // Concatenation [313 265]
219 : // append TOP to SECOND-TOP
220 0 : aStack >> nMerk0;
221 0 : aPool << aStack << ocAmpersand << nMerk0;
222 0 : aPool >> aStack;
223 0 : break;
224 : case 0x09: // Less Than [313 265]
225 : // SECOND-TOP < TOP
226 0 : aStack >> nMerk0;
227 0 : aPool << aStack << ocLess << nMerk0;
228 0 : aPool >> aStack;
229 0 : break;
230 : case 0x0A: // Less Than or Equal [313 265]
231 : // SECOND-TOP <= TOP
232 0 : aStack >> nMerk0;
233 0 : aPool << aStack << ocLessEqual << nMerk0;
234 0 : aPool >> aStack;
235 0 : break;
236 : case 0x0B: // Equal [313 265]
237 : // SECOND-TOP == TOP
238 0 : aStack >> nMerk0;
239 0 : aPool << aStack << ocEqual << nMerk0;
240 0 : aPool >> aStack;
241 0 : break;
242 : case 0x0C: // Greater Than or Equal [313 265]
243 : // SECOND-TOP >= TOP
244 0 : aStack >> nMerk0;
245 0 : aPool << aStack << ocGreaterEqual << nMerk0;
246 0 : aPool >> aStack;
247 0 : break;
248 : case 0x0D: // Greater Than [313 265]
249 : // SECOND-TOP > TOP
250 0 : aStack >> nMerk0;
251 0 : aPool << aStack << ocGreater << nMerk0;
252 0 : aPool >> aStack;
253 0 : break;
254 : case 0x0E: // Not Equal [313 265]
255 : // SECOND-TOP != TOP
256 0 : aStack >> nMerk0;
257 0 : aPool << aStack << ocNotEqual << nMerk0;
258 0 : aPool >> aStack;
259 0 : break;
260 : case 0x0F: // Intersection [314 265]
261 0 : aStack >> nMerk0;
262 0 : aPool << aStack << ocIntersect << nMerk0;
263 0 : aPool >> aStack;
264 0 : break;
265 : case 0x10: // Union [314 265]
266 : // ocSep instead of 'ocUnion'
267 0 : aStack >> nMerk0;
268 0 : aPool << aStack << ocSep << nMerk0;
269 : // doesn't fit exactly, but is more Excel-like
270 0 : aPool >> aStack;
271 0 : break;
272 : case 0x11: // Range [314 265]
273 0 : aStack >> nMerk0;
274 0 : aPool << aStack << ocRange << nMerk0;
275 0 : aPool >> aStack;
276 0 : break;
277 : case 0x12: // Unary Plus [312 264]
278 0 : aPool << ocAdd << aStack;
279 0 : aPool >> aStack;
280 0 : break;
281 : case 0x13: // Unary Minus [312 264]
282 0 : aPool << ocNegSub << aStack;
283 0 : aPool >> aStack;
284 0 : break;
285 : case 0x14: // Percent Sign [312 264]
286 0 : aPool << aStack << ocPercentSign;
287 0 : aPool >> aStack;
288 0 : break;
289 : case 0x15: // Parenthesis [326 278]
290 0 : aPool << ocOpen << aStack << ocClose;
291 0 : aPool >> aStack;
292 0 : break;
293 : case 0x16: // Missing Argument [314 266]
294 0 : aPool << ocMissing;
295 0 : aPool >> aStack;
296 0 : GetTracer().TraceFormulaMissingArg();
297 0 : break;
298 : case 0x17: // String Constant [314 266]
299 0 : aIn >> nLen; // und?
300 0 : aString = aIn.ReadUniString( nLen ); // reads Grbit even if nLen==0
301 :
302 0 : aStack << aPool.Store( aString );
303 0 : break;
304 : case 0x18: // natural language formula
305 : {
306 : sal_uInt8 nEptg;
307 : sal_uInt16 nCol, nRow;
308 0 : aIn >> nEptg;
309 0 : switch( nEptg )
310 : { // name size ext type
311 : case 0x01: // Lel 4 - err
312 0 : aIn.Ignore( 4 );
313 0 : aPool << ocBad;
314 0 : aPool >> aStack;
315 0 : break;
316 : case 0x02: // Rw 4 - ref
317 : case 0x03: // Col 4 - ref
318 : case 0x06: // RwV 4 - val
319 : case 0x07: // ColV 4 - val
320 : {
321 0 : aIn >> nRow >> nCol;
322 0 : ScAddress aAddr(static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab());
323 0 : aSRD.InitAddress(aAddr);
324 :
325 0 : if( nEptg == 0x02 || nEptg == 0x06 )
326 0 : aSRD.SetRowRel(true);
327 : else
328 0 : aSRD.SetColRel(true);
329 :
330 0 : aSRD.SetAddress(aAddr, aEingPos);
331 :
332 0 : aStack << aPool.StoreNlf( aSRD );
333 : }
334 0 : break;
335 : case 0x0A: // Radical 13 - ref
336 : {
337 0 : aIn >> nRow >> nCol;
338 0 : aIn.Ignore( 9 );
339 0 : ScAddress aAddr(static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab());
340 0 : aSRD.InitAddress(aAddr);
341 0 : aSRD.SetColRel(true);
342 0 : aSRD.SetAddress(aAddr, aEingPos);
343 :
344 0 : aStack << aPool.StoreNlf( aSRD );
345 : }
346 0 : break;
347 : case 0x0B: // RadicalS 13 x ref
348 0 : aIn.Ignore( 13 );
349 0 : aExtensions.push_back( EXTENSION_NLR );
350 0 : aPool << ocBad;
351 0 : aPool >> aStack;
352 0 : break;
353 : case 0x0C: // RwS 4 x ref
354 : case 0x0D: // ColS 4 x ref
355 : case 0x0E: // RwSV 4 x val
356 : case 0x0F: // ColSV 4 x val
357 0 : aIn.Ignore( 4 );
358 0 : aExtensions.push_back( EXTENSION_NLR );
359 0 : aPool << ocBad;
360 0 : aPool >> aStack;
361 0 : break;
362 : case 0x10: // RadicalLel 4 - err
363 : case 0x1D: // SxName 4 - val
364 0 : aIn.Ignore( 4 );
365 0 : aPool << ocBad;
366 0 : aPool >> aStack;
367 0 : break;
368 : default:
369 0 : aPool << ocBad;
370 0 : aPool >> aStack;
371 : }
372 : }
373 0 : break;
374 : case 0x19: // Special Attribute [327 279]
375 : {
376 : sal_uInt16 nData, nFakt;
377 : sal_uInt8 nOpt;
378 :
379 0 : aIn >> nOpt >> nData;
380 0 : nFakt = 2;
381 :
382 0 : if( nOpt & 0x04 )
383 : {// nFakt -> skip bytes or words AttrChoose
384 0 : nData++;
385 0 : aIn.Ignore( nData * nFakt );
386 : }
387 0 : else if( nOpt & 0x10 ) // AttrSum
388 0 : DoMulArgs( ocSum, 1 );
389 : }
390 0 : break;
391 : case 0x1C: // Error Value [314 266]
392 : {
393 0 : aIn >> nByte;
394 :
395 : DefTokenId eOc;
396 0 : 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 0 : case EXC_ERR_NUM: eOc = ocStop; break;
404 0 : case EXC_ERR_NA: eOc = ocNotAvail; break;
405 0 : default: eOc = ocNoName;
406 : }
407 0 : aPool << eOc;
408 0 : if( eOc != ocStop )
409 0 : aPool << ocOpen << ocClose;
410 0 : aPool >> aStack;
411 : }
412 0 : break;
413 : case 0x1D: // Boolean [315 266]
414 0 : aIn >> nByte;
415 0 : if( nByte == 0 )
416 0 : aPool << ocFalse << ocOpen << ocClose;
417 : else
418 0 : aPool << ocTrue << ocOpen << ocClose;
419 0 : aPool >> aStack;
420 0 : break;
421 : case 0x1E: // Integer [315 266]
422 0 : aIn >> nUINT16;
423 0 : aStack << aPool.Store( ( double ) nUINT16 );
424 0 : break;
425 : case 0x1F: // Number [315 266]
426 0 : aIn >> fDouble;
427 0 : aStack << aPool.Store( fDouble );
428 0 : break;
429 : case 0x40:
430 : case 0x60:
431 : case 0x20: // Array Constant [317 268]
432 0 : aIn >> nByte >> nUINT16;
433 0 : aIn.Ignore( 4 );
434 0 : if( bAllowArrays )
435 : {
436 0 : aStack << aPool.StoreMatrix();
437 0 : aExtensions.push_back( EXTENSION_ARRAY );
438 : }
439 : else
440 : {
441 0 : aPool << ocBad;
442 0 : aPool >> aStack;
443 : }
444 0 : break;
445 : case 0x41:
446 : case 0x61:
447 : case 0x21: // Function, Fixed Number of Arguments [333 282]
448 : {
449 : sal_uInt16 nXclFunc;
450 0 : aIn >> nXclFunc;
451 0 : if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
452 0 : DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount );
453 : else
454 0 : DoMulArgs( ocNoName, 0 );
455 : }
456 0 : 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 0 : aIn >> nParamCount >> nXclFunc;
464 0 : nParamCount &= 0x7F;
465 0 : if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
466 0 : DoMulArgs( pFuncInfo->meOpCode, nParamCount );
467 : else
468 0 : DoMulArgs( ocNoName, 0 );
469 : }
470 0 : break;
471 : case 0x43:
472 : case 0x63:
473 : case 0x23: // Name [318 269]
474 : {
475 0 : aIn >> nUINT16;
476 0 : aIn.Ignore( 2 );
477 0 : const XclImpName* pName = GetNameManager().GetName( nUINT16 );
478 0 : if (pName)
479 : {
480 0 : if (pName->IsMacro())
481 : // user-defined macro name.
482 0 : aStack << aPool.Store(ocMacro, pName->GetXclName());
483 : else
484 0 : aStack << aPool.StoreName(nUINT16, pName->IsGlobal());
485 : }
486 : }
487 0 : 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 0 : aIn >> nRow >> nCol;
498 :
499 0 : aSRD.SetRelTab(0);
500 0 : aSRD.SetFlag3D( bRangeName && !bCondFormat );
501 :
502 0 : ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
503 :
504 0 : 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 0 : aStack << aPool.Store( aSRD );
515 : }
516 0 : 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 0 : ScSingleRefData &rSRef1 = aCRD.Ref1;
527 0 : ScSingleRefData &rSRef2 = aCRD.Ref2;
528 :
529 0 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
530 :
531 0 : rSRef1.SetRelTab(0);
532 0 : rSRef2.SetRelTab(0);
533 0 : rSRef1.SetFlag3D( bRangeName && !bCondFormat );
534 0 : rSRef2.SetFlag3D( bRangeName && !bCondFormat );
535 :
536 0 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
537 0 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
538 :
539 0 : if( IsComplColRange( nColFirst, nColLast ) )
540 0 : SetComplCol( aCRD );
541 0 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
542 0 : SetComplRow( aCRD );
543 :
544 0 : 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 0 : aStack << aPool.Store( aCRD );
557 : }
558 0 : 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 0 : aIn.Ignore( 2 ); // There isn't any more
579 0 : 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 0 : aIn >> nRow >> nCol;
588 :
589 0 : aSRD.SetRelTab(0);
590 0 : aSRD.SetFlag3D( bRangeName );
591 :
592 0 : ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
593 :
594 0 : aStack << aPool.Store( aSRD );
595 : }
596 0 : 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 0 : aCRD.Ref1.SetRelTab(0);
605 0 : aCRD.Ref2.SetRelTab(0);
606 0 : aCRD.Ref1.SetFlag3D( bRangeName );
607 0 : aCRD.Ref2.SetFlag3D( bRangeName );
608 :
609 0 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
610 :
611 0 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
612 0 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
613 :
614 0 : if( IsComplColRange( nColFirst, nColLast ) )
615 0 : SetComplCol( aCRD );
616 0 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
617 0 : SetComplRow( aCRD );
618 :
619 0 : aStack << aPool.Store( aCRD );
620 : }
621 0 : 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 0 : aIn >> nIxti >> nRw >> nGrbitCol;
762 :
763 0 : ExternalTabInfo aExtInfo;
764 0 : if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
765 : {
766 0 : aPool << ocBad;
767 0 : aPool >> aStack;
768 0 : break;
769 : }
770 :
771 0 : aSRD.SetAbsTab(nTabFirst);
772 0 : aSRD.SetFlag3D(true);
773 :
774 0 : ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
775 :
776 0 : 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 0 : 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 0 : 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 0 : aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
802 : }
803 : else
804 : {
805 0 : if ( !ValidTab(nTabFirst))
806 0 : aSRD.SetTabDeleted( true );
807 :
808 0 : 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 0 : aStack << aPool.Store( aSRD );
817 0 : }
818 : }
819 0 : 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 0 : aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
830 :
831 0 : ExternalTabInfo aExtInfo;
832 0 : if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
833 : {
834 0 : aPool << ocBad;
835 0 : aPool >> aStack;
836 0 : break;
837 : }
838 0 : ScSingleRefData &rR1 = aCRD.Ref1;
839 0 : ScSingleRefData &rR2 = aCRD.Ref2;
840 :
841 :
842 0 : rR1.SetAbsTab(nTabFirst);
843 0 : rR2.SetAbsTab(nTabLast);
844 0 : rR1.SetFlag3D(true);
845 0 : rR2.SetFlag3D( nTabFirst != nTabLast );
846 :
847 0 : ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
848 0 : ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
849 :
850 0 : if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
851 0 : SetComplCol( aCRD );
852 0 : else if( IsComplRowRange( nRw1, nRw2 ) )
853 0 : SetComplRow( aCRD );
854 :
855 0 : switch ( nOp )
856 : {
857 : case 0x5D:
858 : case 0x7D:
859 : case 0x3D: // Deleted 3-D Area Reference [ 277]
860 : // no information which part is deleted, set all
861 0 : rR1.SetColDeleted( true );
862 0 : rR1.SetRowDeleted( true );
863 0 : rR2.SetColDeleted( true );
864 0 : rR2.SetRowDeleted( true );
865 : }
866 :
867 0 : if (aExtInfo.mbExternal)
868 : {
869 0 : aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
870 : }
871 : else
872 : {
873 0 : if ( !ValidTab(nTabFirst) )
874 0 : rR1.SetTabDeleted( true );
875 0 : if ( !ValidTab(nTabLast) )
876 0 : rR2.SetTabDeleted( true );
877 :
878 0 : aStack << aPool.Store( aCRD );
879 0 : }
880 : }
881 0 : break;
882 0 : default: bError = true;
883 : }
884 0 : bError |= !aIn.IsValid();
885 : }
886 :
887 : ConvErr eRet;
888 :
889 0 : if( bError )
890 : {
891 0 : aPool << ocBad;
892 0 : aPool >> aStack;
893 0 : rpTokArray = aPool[ aStack.Get() ];
894 0 : eRet = ConvErrNi;
895 : }
896 0 : else if( aIn.GetRecPos() != nEndPos )
897 : {
898 0 : aPool << ocBad;
899 0 : aPool >> aStack;
900 0 : rpTokArray = aPool[ aStack.Get() ];
901 0 : eRet = ConvErrCount;
902 : }
903 0 : else if( bArrayFormula )
904 : {
905 0 : rpTokArray = NULL;
906 0 : eRet = ConvOK;
907 : }
908 : else
909 : {
910 0 : rpTokArray = aPool[ aStack.Get() ];
911 0 : eRet = ConvOK;
912 : }
913 :
914 0 : aIn.Seek( nEndPos );
915 :
916 0 : if( eRet == ConvOK)
917 0 : ReadExtensions( aExtensions, aIn );
918 :
919 0 : return eRet;
920 : }
921 :
922 :
923 : // stream seeks to first byte after <nFormulaLen>
924 0 : ConvErr ExcelToSc8::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen,
925 : SCsTAB nTab, const FORMULA_TYPE eFT )
926 : {
927 : sal_uInt8 nOp, nLen;
928 0 : bool bError = false;
929 0 : const bool bCondFormat = eFT == FT_CondFormat;
930 0 : const bool bRangeName = eFT == FT_RangeName || bCondFormat;
931 0 : const bool bSharedFormula = eFT == FT_SharedFormula;
932 0 : const bool bRNorSF = bRangeName || bSharedFormula;
933 :
934 : ScSingleRefData aSRD;
935 : ScComplexRefData aCRD;
936 :
937 0 : bExternName = false;
938 :
939 0 : if( eStatus != ConvOK )
940 : {
941 0 : aIn.Ignore( nFormulaLen );
942 0 : return eStatus;
943 : }
944 :
945 0 : if( nFormulaLen == 0 )
946 0 : return ConvOK;
947 :
948 0 : sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
949 :
950 0 : while( (aIn.GetRecPos() < nEndPos) && !bError )
951 : {
952 0 : aIn >> nOp;
953 :
954 : // always reset flags
955 0 : aSRD.InitFlags();
956 0 : aCRD.InitFlags();
957 :
958 0 : switch( nOp ) // book page:
959 : { // SDK4 SDK5
960 : case 0x01: // Array Formula [325 ]
961 : // Array Formula or Shared Formula [ 277]
962 0 : aIn.Ignore( 4 );
963 0 : break;
964 : case 0x02: // Data Table [325 277]
965 0 : aIn.Ignore( 4 );
966 0 : break;
967 : case 0x03: // Addition [312 264]
968 : case 0x04: // Subtraction [313 264]
969 : case 0x05: // Multiplication [313 264]
970 : case 0x06: // Division [313 264]
971 : case 0x07: // Exponetiation [313 265]
972 : case 0x08: // Concatenation [313 265]
973 : case 0x09: // Less Than [313 265]
974 : case 0x0A: // Less Than or Equal [313 265]
975 : case 0x0B: // Equal [313 265]
976 : case 0x0C: // Greater Than or Equal [313 265]
977 : case 0x0D: // Greater Than [313 265]
978 : case 0x0E: // Not Equal [313 265]
979 : case 0x0F: // Intersection [314 265]
980 : case 0x10: // Union [314 265]
981 : case 0x11: // Range [314 265]
982 : case 0x12: // Unary Plus [312 264]
983 : case 0x13: // Unary Minus [312 264]
984 : case 0x14: // Percent Sign [312 264]
985 : case 0x15: // Parenthesis [326 278]
986 : case 0x16: // Missing Argument [314 266]
987 0 : break;
988 : case 0x17: // String Constant [314 266]
989 0 : aIn >> nLen; // und?
990 :
991 0 : aIn.IgnoreUniString( nLen ); // reads Grbit even if nLen==0
992 0 : break;
993 : case 0x19: // Special Attribute [327 279]
994 : {
995 : sal_uInt16 nData, nFakt;
996 : sal_uInt8 nOpt;
997 :
998 0 : aIn >> nOpt >> nData;
999 0 : nFakt = 2;
1000 :
1001 0 : if( nOpt & 0x04 )
1002 : {// nFakt -> skip bytes or words AttrChoose
1003 0 : nData++;
1004 0 : aIn.Ignore( nData * nFakt );
1005 : }
1006 : }
1007 0 : break;
1008 : case 0x1C: // Error Value [314 266]
1009 : case 0x1D: // Boolean [315 266]
1010 0 : aIn.Ignore( 1 );
1011 0 : break;
1012 : case 0x1E: // Integer [315 266]
1013 0 : aIn.Ignore( 2 );
1014 0 : break;
1015 : case 0x1F: // Number [315 266]
1016 0 : aIn.Ignore( 8 );
1017 0 : break;
1018 : case 0x40:
1019 : case 0x60:
1020 : case 0x20: // Array Constant [317 268]
1021 0 : aIn.Ignore( 7 );
1022 0 : break;
1023 : case 0x41:
1024 : case 0x61:
1025 : case 0x21: // Function, Fixed Number of Arguments [333 282]
1026 0 : aIn.Ignore( 2 );
1027 0 : break;
1028 : case 0x42:
1029 : case 0x62:
1030 : case 0x22: // Function, Variable Number of Arg. [333 283]
1031 0 : aIn.Ignore( 3 );
1032 0 : break;
1033 : case 0x43:
1034 : case 0x63:
1035 : case 0x23: // Name [318 269]
1036 0 : aIn.Ignore( 4 );
1037 0 : break;
1038 : case 0x44:
1039 : case 0x64:
1040 : case 0x24: // Cell Reference [319 270]
1041 : {
1042 : sal_uInt16 nCol, nRow;
1043 :
1044 0 : aIn >> nRow >> nCol;
1045 :
1046 0 : aSRD.SetRelTab(0);
1047 0 : aSRD.SetFlag3D( bRangeName && !bCondFormat );
1048 :
1049 0 : ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
1050 :
1051 0 : rRangeList.Append(aSRD.toAbs(aEingPos), nTab);
1052 : }
1053 0 : break;
1054 : case 0x45:
1055 : case 0x65:
1056 : case 0x25: // Area Reference [320 270]
1057 : {
1058 : sal_uInt16 nRowFirst, nRowLast;
1059 : sal_uInt16 nColFirst, nColLast;
1060 0 : ScSingleRefData &rSRef1 = aCRD.Ref1;
1061 0 : ScSingleRefData &rSRef2 = aCRD.Ref2;
1062 :
1063 0 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1064 :
1065 0 : rSRef1.SetRelTab(0);
1066 0 : rSRef2.SetRelTab(0);
1067 0 : rSRef1.SetFlag3D( bRangeName && !bCondFormat );
1068 0 : rSRef2.SetFlag3D( bRangeName && !bCondFormat );
1069 :
1070 0 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
1071 0 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
1072 :
1073 0 : if( IsComplColRange( nColFirst, nColLast ) )
1074 0 : SetComplCol( aCRD );
1075 0 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
1076 0 : SetComplRow( aCRD );
1077 :
1078 0 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1079 : }
1080 0 : break;
1081 : case 0x46:
1082 : case 0x66:
1083 : case 0x26: // Constant Reference Subexpression [321 271]
1084 : case 0x47:
1085 : case 0x67:
1086 : case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
1087 : case 0x48:
1088 : case 0x68:
1089 : case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1090 0 : aIn.Ignore( 6 ); // There isn't any more
1091 0 : break;
1092 : case 0x49:
1093 : case 0x69:
1094 : case 0x29: // Variable Reference Subexpression [331 281]
1095 0 : aIn.Ignore( 2 ); // There isn't any more
1096 0 : break;
1097 : case 0x4A:
1098 : case 0x6A:
1099 : case 0x2A: // Deleted Cell Reference [323 273]
1100 0 : aIn.Ignore( 3 );
1101 0 : break;
1102 : case 0x4B:
1103 : case 0x6B:
1104 : case 0x2B: // Deleted Area Refernce [323 273]
1105 0 : aIn.Ignore( 6 );
1106 0 : break;
1107 : case 0x4C:
1108 : case 0x6C:
1109 : case 0x2C: // Cell Reference Within a Name [323 ]
1110 : // Cell Reference Within a Shared Formula[ 273]
1111 : {
1112 : sal_uInt16 nRow, nCol;
1113 :
1114 0 : aIn >> nRow >> nCol;
1115 :
1116 0 : aSRD.SetRelTab(0);
1117 0 : aSRD.SetFlag3D( bRangeName );
1118 :
1119 0 : ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
1120 :
1121 0 : rRangeList.Append(aSRD.toAbs(aEingPos), nTab);
1122 : }
1123 0 : break;
1124 : case 0x4D:
1125 : case 0x6D:
1126 : case 0x2D: // Area Reference Within a Name [324 ]
1127 : { // Area Reference Within a Shared Formula[ 274]
1128 : sal_uInt16 nRowFirst, nRowLast;
1129 : sal_uInt16 nColFirst, nColLast;
1130 :
1131 0 : aCRD.Ref1.SetRelTab(0);
1132 0 : aCRD.Ref2.SetRelTab(0);
1133 0 : aCRD.Ref1.SetFlag3D( bRangeName );
1134 0 : aCRD.Ref2.SetFlag3D( bRangeName );
1135 :
1136 0 : aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1137 :
1138 0 : ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
1139 0 : ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
1140 :
1141 0 : if( IsComplColRange( nColFirst, nColLast ) )
1142 0 : SetComplCol( aCRD );
1143 0 : else if( IsComplRowRange( nRowFirst, nRowLast ) )
1144 0 : SetComplRow( aCRD );
1145 :
1146 0 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1147 : }
1148 0 : break;
1149 : case 0x4E:
1150 : case 0x6E:
1151 : case 0x2E: // Reference Subexpression Within a Name [332 282]
1152 : case 0x4F:
1153 : case 0x6F:
1154 : case 0x2F: // Incomplete Reference Subexpression... [332 282]
1155 : case 0x58:
1156 : case 0x78:
1157 : case 0x38: // Command-Equivalent Function [333 ]
1158 0 : aIn.Ignore( 2 );
1159 0 : break;
1160 : case 0x59:
1161 : case 0x79:
1162 : case 0x39: // Name or External Name [ 275]
1163 0 : aIn.Ignore( 24 );
1164 0 : break;
1165 : case 0x5A:
1166 : case 0x7A:
1167 : case 0x3A: // 3-D Cell Reference [ 275]
1168 : {
1169 : sal_uInt16 nIxti, nRw, nGrbitCol;
1170 :
1171 0 : aIn >> nIxti >> nRw >> nGrbitCol;
1172 :
1173 : SCTAB nFirstScTab, nLastScTab;
1174 0 : if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
1175 : {
1176 0 : aSRD.SetAbsTab(nFirstScTab);
1177 0 : aSRD.SetFlag3D(true);
1178 :
1179 0 : ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
1180 :
1181 0 : if( nFirstScTab != nLastScTab )
1182 : {
1183 0 : aCRD.Ref1 = aSRD;
1184 0 : aCRD.Ref2 = aSRD;
1185 0 : aCRD.Ref2.SetAbsTab(nLastScTab);
1186 0 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1187 : }
1188 : else
1189 0 : rRangeList.Append(aSRD.toAbs(aEingPos), nTab);
1190 : }
1191 : }
1192 0 : break;
1193 : case 0x5B:
1194 : case 0x7B:
1195 : case 0x3B: // 3-D Area Reference [ 276]
1196 : {
1197 : sal_uInt16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
1198 :
1199 0 : aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
1200 :
1201 : SCTAB nFirstScTab, nLastScTab;
1202 0 : if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
1203 : {
1204 0 : ScSingleRefData &rR1 = aCRD.Ref1;
1205 0 : ScSingleRefData &rR2 = aCRD.Ref2;
1206 :
1207 0 : rR1.SetAbsTab(nFirstScTab);
1208 0 : rR2.SetAbsTab(nLastScTab);
1209 0 : rR1.SetFlag3D(true);
1210 0 : rR2.SetFlag3D( nFirstScTab != nLastScTab );
1211 :
1212 0 : ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
1213 0 : ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
1214 :
1215 0 : if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
1216 0 : SetComplCol( aCRD );
1217 0 : else if( IsComplRowRange( nRw1, nRw2 ) )
1218 0 : SetComplRow( aCRD );
1219 :
1220 0 : rRangeList.Append(aCRD.toAbs(aEingPos), nTab);
1221 : }
1222 : }
1223 0 : break;
1224 : case 0x5C:
1225 : case 0x7C:
1226 : case 0x3C: // Deleted 3-D Cell Reference [ 277]
1227 0 : aIn.Ignore( 6 );
1228 0 : break;
1229 : case 0x5D:
1230 : case 0x7D:
1231 : case 0x3D: // Deleted 3-D Area Reference [ 277]
1232 0 : aIn.Ignore( 10 );
1233 0 : break;
1234 : default:
1235 0 : bError = true;
1236 : }
1237 0 : bError |= !aIn.IsValid();
1238 : }
1239 :
1240 : ConvErr eRet;
1241 :
1242 0 : if( bError )
1243 0 : eRet = ConvErrNi;
1244 0 : else if( aIn.GetRecPos() != nEndPos )
1245 0 : eRet = ConvErrCount;
1246 0 : else if( bExternName )
1247 0 : eRet = ConvErrExternal;
1248 : else
1249 0 : eRet = ConvOK;
1250 :
1251 0 : aIn.Seek( nEndPos );
1252 0 : return eRet;
1253 : }
1254 :
1255 0 : ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
1256 : const OUString& rUrl, const vector<OUString>& rTabNames )
1257 : {
1258 0 : if( !GetDocShell() )
1259 0 : return ConvErrNi;
1260 :
1261 0 : OUString aFileUrl = ScGlobal::GetAbsDocName(rUrl, GetDocShell());
1262 :
1263 : sal_uInt8 nOp, nByte;
1264 0 : bool bError = false;
1265 :
1266 : ScSingleRefData aSRD;
1267 : ScComplexRefData aCRD;
1268 :
1269 0 : if (eStatus != ConvOK)
1270 : {
1271 0 : rStrm.Ignore(nFormulaLen);
1272 0 : return eStatus;
1273 : }
1274 :
1275 0 : if (nFormulaLen == 0)
1276 : {
1277 0 : aPool.Store(OUString("-/-"));
1278 0 : aPool >> aStack;
1279 0 : rpArray = aPool[aStack.Get()];
1280 0 : return ConvOK;
1281 : }
1282 :
1283 0 : ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1284 0 : sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFileUrl);
1285 0 : sal_uInt16 nTabCount = static_cast< sal_uInt16 >( rTabNames.size() );
1286 :
1287 0 : sal_Size nEndPos = rStrm.GetRecPos() + nFormulaLen;
1288 :
1289 0 : while( (rStrm.GetRecPos() < nEndPos) && !bError )
1290 : {
1291 0 : rStrm >> nOp;
1292 :
1293 : // always reset flags
1294 0 : aSRD.InitFlags();
1295 0 : aCRD.InitFlags();
1296 :
1297 0 : switch( nOp )
1298 : {
1299 : case 0x1C: // Error Value
1300 : {
1301 0 : rStrm >> nByte;
1302 : DefTokenId eOc;
1303 0 : switch( nByte )
1304 : {
1305 : case EXC_ERR_NULL:
1306 : case EXC_ERR_DIV0:
1307 : case EXC_ERR_VALUE:
1308 : case EXC_ERR_REF:
1309 : case EXC_ERR_NAME:
1310 0 : case EXC_ERR_NUM: eOc = ocStop; break;
1311 0 : case EXC_ERR_NA: eOc = ocNotAvail; break;
1312 0 : default: eOc = ocNoName;
1313 : }
1314 0 : aPool << eOc;
1315 0 : if( eOc != ocStop )
1316 0 : aPool << ocOpen << ocClose;
1317 0 : aPool >> aStack;
1318 : }
1319 0 : break;
1320 : case 0x3A:
1321 : {
1322 : // cell reference in external range name
1323 : sal_uInt16 nExtTab1, nExtTab2, nRow, nGrbitCol;
1324 0 : rStrm >> nExtTab1 >> nExtTab2 >> nRow >> nGrbitCol;
1325 0 : if (nExtTab1 >= nTabCount || nExtTab2 >= nTabCount)
1326 : {
1327 0 : bError = true;
1328 0 : break;
1329 : }
1330 :
1331 0 : aSRD.SetAbsTab(nExtTab1);
1332 0 : aSRD.SetFlag3D(true);
1333 0 : ExcRelToScRel8(nRow, nGrbitCol, aSRD, true);
1334 0 : aCRD.Ref1 = aCRD.Ref2 = aSRD;
1335 0 : OUString aTabName = rTabNames[nExtTab1];
1336 :
1337 0 : if (nExtTab1 == nExtTab2)
1338 : {
1339 : // single cell reference
1340 0 : aStack << aPool.StoreExtRef(nFileId, aTabName, aSRD);
1341 : }
1342 : else
1343 : {
1344 : // area reference
1345 0 : aCRD.Ref2.SetAbsTab(nExtTab2);
1346 0 : aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
1347 0 : }
1348 : }
1349 0 : break;
1350 : case 0x3B:
1351 : {
1352 : // area reference
1353 : sal_uInt16 nExtTab1, nExtTab2, nRow1, nRow2, nGrbitCol1, nGrbitCol2;
1354 0 : rStrm >> nExtTab1 >> nExtTab2 >> nRow1 >> nRow2 >> nGrbitCol1 >> nGrbitCol2;
1355 0 : ScSingleRefData& rR1 = aCRD.Ref1;
1356 0 : ScSingleRefData& rR2 = aCRD.Ref2;
1357 :
1358 0 : rR1.SetAbsTab(nExtTab1);
1359 0 : rR1.SetFlag3D(true);
1360 0 : ExcRelToScRel8(nRow1, nGrbitCol1, rR1, true);
1361 :
1362 0 : rR2.SetAbsTab(nExtTab2);
1363 0 : rR2.SetFlag3D(true);
1364 0 : ExcRelToScRel8(nRow2, nGrbitCol2, rR2, true);
1365 :
1366 0 : OUString aTabName = rTabNames[nExtTab1];
1367 0 : aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
1368 : }
1369 0 : break;
1370 : default:
1371 0 : bError = true;
1372 : }
1373 0 : bError |= !rStrm.IsValid();
1374 : }
1375 :
1376 : ConvErr eRet;
1377 :
1378 0 : if( bError )
1379 : {
1380 0 : aPool << ocBad;
1381 0 : aPool >> aStack;
1382 0 : rpArray = aPool[ aStack.Get() ];
1383 0 : eRet = ConvErrNi;
1384 : }
1385 0 : else if( rStrm.GetRecPos() != nEndPos )
1386 : {
1387 0 : aPool << ocBad;
1388 0 : aPool >> aStack;
1389 0 : rpArray = aPool[ aStack.Get() ];
1390 0 : eRet = ConvErrCount;
1391 : }
1392 : else
1393 : {
1394 0 : rpArray = aPool[ aStack.Get() ];
1395 0 : eRet = ConvOK;
1396 : }
1397 :
1398 0 : rStrm.Seek(nEndPos);
1399 0 : return eRet;
1400 : }
1401 :
1402 0 : void ExcelToSc8::ExcRelToScRel8( sal_uInt16 nRow, sal_uInt16 nC, ScSingleRefData &rSRD, const bool bName )
1403 : {
1404 0 : const bool bColRel = ( nC & 0x4000 ) != 0;
1405 0 : const bool bRowRel = ( nC & 0x8000 ) != 0;
1406 0 : const sal_uInt8 nCol = static_cast<sal_uInt8>(nC);
1407 :
1408 0 : if( bName )
1409 : {
1410 : // C O L
1411 0 : if( bColRel )
1412 0 : rSRD.SetRelCol(static_cast<SCCOL>(static_cast<sal_Int8>(nC)));
1413 : else
1414 0 : rSRD.SetAbsCol(static_cast<SCCOL>(nCol));
1415 :
1416 : // R O W
1417 0 : if( bRowRel )
1418 0 : rSRD.SetRelRow(static_cast<sal_Int16>(nRow));
1419 : else
1420 0 : rSRD.SetAbsRow(std::min( static_cast<SCROW>(nRow), MAXROW));
1421 : }
1422 : else
1423 : {
1424 : // C O L
1425 0 : if ( bColRel )
1426 0 : rSRD.SetRelCol(static_cast<SCCOL>(nCol) - aEingPos.Col());
1427 : else
1428 0 : rSRD.SetAbsCol(nCol);
1429 :
1430 : // R O W
1431 0 : if ( bRowRel )
1432 0 : rSRD.SetRelRow(static_cast<SCROW>(nRow) - aEingPos.Row());
1433 : else
1434 0 : rSRD.SetAbsRow(nRow);
1435 : }
1436 0 : }
1437 :
1438 :
1439 : // stream seeks to first byte after <nLen>
1440 0 : bool ExcelToSc8::GetAbsRefs( ScRangeList& r, XclImpStream& aIn, sal_Size nLen )
1441 : {
1442 : sal_uInt8 nOp;
1443 : sal_uInt16 nRow1, nRow2, nCol1, nCol2;
1444 : SCTAB nTab1, nTab2;
1445 : sal_uInt16 nIxti;
1446 :
1447 : sal_Size nSeek;
1448 :
1449 0 : sal_Size nEndPos = aIn.GetRecPos() + nLen;
1450 :
1451 0 : while( aIn.IsValid() && (aIn.GetRecPos() < nEndPos) )
1452 : {
1453 0 : aIn >> nOp;
1454 0 : nSeek = 0;
1455 :
1456 0 : switch( nOp )
1457 : {
1458 : case 0x44:
1459 : case 0x64:
1460 : case 0x24: // Cell Reference [319 270]
1461 : case 0x4C:
1462 : case 0x6C:
1463 : case 0x2C: // Cell Reference Within a Name [323 ]
1464 : // Cell Reference Within a Shared Formula[ 273]
1465 0 : aIn >> nRow1 >> nCol1;
1466 :
1467 0 : nRow2 = nRow1;
1468 0 : nCol2 = nCol1;
1469 0 : nTab1 = nTab2 = GetCurrScTab();
1470 0 : goto _common;
1471 : case 0x45:
1472 : case 0x65:
1473 : case 0x25: // Area Reference [320 270]
1474 : case 0x4D:
1475 : case 0x6D:
1476 : case 0x2D: // Area Reference Within a Name [324 ]
1477 : // Area Reference Within a Shared Formula[ 274]
1478 0 : aIn >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1479 :
1480 0 : nTab1 = nTab2 = GetCurrScTab();
1481 0 : goto _common;
1482 : case 0x5A:
1483 : case 0x7A:
1484 : case 0x3A: // 3-D Cell Reference [ 275]
1485 0 : aIn >> nIxti >> nRow1 >> nCol1;
1486 :
1487 0 : nRow2 = nRow1;
1488 0 : nCol2 = nCol1;
1489 :
1490 0 : goto _3d_common;
1491 : case 0x5B:
1492 : case 0x7B:
1493 : case 0x3B: // 3-D Area Reference [ 276]
1494 0 : aIn >> nIxti >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1495 :
1496 : _3d_common:
1497 : // skip references to deleted sheets
1498 0 : if( !rLinkMan.GetScTabRange( nTab1, nTab2, nIxti ) || !ValidTab( nTab1 ) || !ValidTab( nTab2 ) )
1499 0 : break;
1500 :
1501 0 : goto _common;
1502 : _common:
1503 : // do not check abs/rel flags, linked controls have set them!
1504 : {
1505 0 : ScRange aScRange;
1506 0 : nCol1 &= 0x3FFF;
1507 0 : nCol2 &= 0x3FFF;
1508 0 : if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
1509 0 : r.Append( aScRange );
1510 : }
1511 0 : break;
1512 : case 0x1C: // Error Value [314 266]
1513 : case 0x1D: // Boolean [315 266]
1514 0 : nSeek = 1;
1515 0 : break;
1516 : case 0x1E: // Integer [315 266]
1517 : case 0x41:
1518 : case 0x61:
1519 : case 0x21: // Function, Fixed Number of Arguments [333 282]
1520 : case 0x49:
1521 : case 0x69:
1522 : case 0x29: // Variable Reference Subexpression [331 281]
1523 : case 0x4E:
1524 : case 0x6E:
1525 : case 0x2E: // Reference Subexpression Within a Name [332 282]
1526 : case 0x4F:
1527 : case 0x6F:
1528 : case 0x2F: // Incomplete Reference Subexpression... [332 282]
1529 : case 0x58:
1530 : case 0x78:
1531 : case 0x38: // Command-Equivalent Function [333 ]
1532 0 : nSeek = 2;
1533 0 : break;
1534 : case 0x42:
1535 : case 0x62:
1536 : case 0x22: // Function, Variable Number of Arg. [333 283]
1537 0 : nSeek = 3;
1538 0 : break;
1539 : case 0x01: // Array Formula [325 ]
1540 : case 0x02: // Data Table [325 277]
1541 : case 0x43:
1542 : case 0x63:
1543 : case 0x23: // Name [318 269]
1544 : case 0x4A:
1545 : case 0x6A:
1546 : case 0x2A: // Deleted Cell Reference [323 273]
1547 0 : nSeek = 4;
1548 0 : break;
1549 : case 0x46:
1550 : case 0x66:
1551 : case 0x26: // Constant Reference Subexpression [321 271]
1552 : case 0x47:
1553 : case 0x67:
1554 : case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
1555 : case 0x48:
1556 : case 0x68:
1557 : case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1558 : case 0x5C:
1559 : case 0x7C:
1560 : case 0x3C: // Deleted 3-D Cell Reference [ 277]
1561 : case 0x59:
1562 : case 0x79:
1563 : case 0x39: // Name or External Name [ 275]
1564 0 : nSeek = 6;
1565 0 : break;
1566 : case 0x40:
1567 : case 0x60:
1568 : case 0x20: // Array Constant [317 268]
1569 0 : nSeek = 7;
1570 0 : break;
1571 : case 0x1F: // Number [315 266]
1572 : case 0x4B:
1573 : case 0x6B:
1574 : case 0x2B: // Deleted Area Refernce [323 273]
1575 0 : nSeek = 8;
1576 0 : break;
1577 : case 0x5D:
1578 : case 0x7D:
1579 : case 0x3D: // Deleted 3-D Area Reference [ 277]
1580 0 : nSeek = 10;
1581 0 : break;
1582 : case 0x17: // String Constant [314 266]
1583 : {
1584 : sal_uInt8 nStrLen;
1585 0 : aIn >> nStrLen;
1586 0 : aIn.IgnoreUniString( nStrLen ); // reads Grbit even if nLen==0
1587 0 : nSeek = 0;
1588 : }
1589 0 : break;
1590 : case 0x19: // Special Attribute [327 279]
1591 : {
1592 : sal_uInt16 nData;
1593 : sal_uInt8 nOpt;
1594 0 : aIn >> nOpt >> nData;
1595 0 : if( nOpt & 0x04 )
1596 : {// nFakt -> skip bytes or words AttrChoose
1597 0 : nData++;
1598 0 : nSeek = nData * 2;
1599 : }
1600 : }
1601 0 : break;
1602 : }
1603 :
1604 0 : aIn.Ignore( nSeek );
1605 : }
1606 0 : aIn.Seek( nEndPos );
1607 :
1608 0 : return !r.empty();
1609 : }
1610 :
1611 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|