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