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