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