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 "imp_op.hxx"
21 :
22 : #include <filter/msfilter/countryid.hxx>
23 :
24 : #include "scitems.hxx"
25 : #include <editeng/eeitem.hxx>
26 :
27 : #include <editeng/editdata.hxx>
28 : #include <editeng/editeng.hxx>
29 : #include <editeng/editobj.hxx>
30 : #include <editeng/editstat.hxx>
31 : #include <editeng/flditem.hxx>
32 : #include <svx/pageitem.hxx>
33 : #include <editeng/colritem.hxx>
34 : #include <sfx2/printer.hxx>
35 : #include <sfx2/docfile.hxx>
36 : #include <svl/zforlist.hxx>
37 :
38 : #include <sfx2/objsh.hxx>
39 : #include <tools/urlobj.hxx>
40 : #include "docuno.hxx"
41 :
42 : #include "formulacell.hxx"
43 : #include "document.hxx"
44 : #include "rangenam.hxx"
45 : #include "compiler.hxx"
46 : #include "patattr.hxx"
47 : #include "attrib.hxx"
48 : #include "globstr.hrc"
49 : #include "global.hxx"
50 : #include "markdata.hxx"
51 : #include "olinetab.hxx"
52 : #include "stlsheet.hxx"
53 : #include "stlpool.hxx"
54 : #include "viewopti.hxx"
55 : #include "docoptio.hxx"
56 : #include "scextopt.hxx"
57 : #include "editutil.hxx"
58 : #include "filtopt.hxx"
59 : #include "scerrors.hxx"
60 : #include "unonames.hxx"
61 : #include "paramisc.hxx"
62 : #include "postit.hxx"
63 :
64 : #include "fapihelper.hxx"
65 : #include "xltools.hxx"
66 : #include "xltable.hxx"
67 : #include "xlview.hxx"
68 : #include "xltracer.hxx"
69 : #include "xihelper.hxx"
70 : #include "xipage.hxx"
71 : #include "xiview.hxx"
72 : #include "xilink.hxx"
73 : #include "xiescher.hxx"
74 : #include "xicontent.hxx"
75 :
76 : #include "excimp8.hxx"
77 : #include "excform.hxx"
78 : #include "documentimport.hxx"
79 :
80 : #if defined( WNT )
81 : #include <math.h>
82 : #else
83 : #include <stdlib.h>
84 : #endif
85 :
86 : using namespace ::com::sun::star;
87 :
88 : const double ImportExcel::fExcToTwips =
89 : ( double ) TWIPS_PER_CHAR / 256.0;
90 :
91 88 : ImportTyp::ImportTyp( ScDocument* pDoc, rtl_TextEncoding eQ )
92 : {
93 88 : eQuellChar = eQ;
94 88 : pD = pDoc;
95 88 : }
96 :
97 88 : ImportTyp::~ImportTyp()
98 : {
99 88 : }
100 :
101 0 : FltError ImportTyp::Read()
102 : {
103 0 : return eERR_INTERN;
104 : }
105 :
106 84 : ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ):
107 : ImportTyp( &rImpData.mrDoc, rImpData.meTextEnc ),
108 : XclImpRoot( rImpData ),
109 84 : maStrm( rStrm, GetRoot() ),
110 : aIn( maStrm ),
111 : maScOleSize( ScAddress::INITIALIZE_INVALID ),
112 : pColOutlineBuff(NULL),
113 : pRowOutlineBuff(NULL),
114 : pColRowBuff(NULL),
115 : mpLastFormula(NULL),
116 : mnLastRefIdx( 0 ),
117 : mnIxfeIndex( 0 ),
118 : mnLastRecId(0),
119 : mbBiff2HasXfs(false),
120 168 : mbBiff2HasXfsValid(false)
121 : {
122 84 : nBdshtTab = 0;
123 :
124 : // fill in root data - after new's without root as parameter
125 84 : pExcRoot = &GetOldRoot();
126 84 : pExcRoot->pIR = this; // ExcRoot -> XclImpRoot
127 84 : pExcRoot->eDateiTyp = BiffX;
128 84 : pExcRoot->pExtSheetBuff = new ExtSheetBuffer( pExcRoot ); //&aExtSheetBuff;
129 84 : pExcRoot->pShrfmlaBuff = new SharedFormulaBuffer( pExcRoot ); //&aShrfrmlaBuff;
130 84 : pExcRoot->pExtNameBuff = new ExtNameBuff ( *this );
131 :
132 84 : pExtNameBuff = new NameBuffer( pExcRoot ); //prevent empty rootdata
133 84 : pExtNameBuff->SetBase( 1 );
134 :
135 84 : pOutlineListBuffer = new XclImpOutlineListBuffer( );
136 :
137 : // ab Biff8
138 84 : pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc( GetRoot() );
139 :
140 84 : bTabTruncated = false;
141 :
142 : // Excel document per Default on 31.12.1899, accords to Excel settings with 1.1.1900
143 84 : ScDocOptions aOpt = pD->GetDocOptions();
144 84 : aOpt.SetDate( 30, 12, 1899 );
145 84 : pD->SetDocOptions( aOpt );
146 84 : pD->GetFormatTable()->ChangeNullDate( 30, 12, 1899 );
147 :
148 168 : ScDocOptions aDocOpt( pD->GetDocOptions() );
149 84 : aDocOpt.SetIgnoreCase( true ); // always in Excel
150 84 : aDocOpt.SetFormulaRegexEnabled( false ); // regular expressions? what's that?
151 84 : aDocOpt.SetLookUpColRowNames( false ); // default: no natural language refs
152 168 : pD->SetDocOptions( aDocOpt );
153 84 : }
154 :
155 171 : ImportExcel::~ImportExcel()
156 : {
157 84 : GetDoc().SetSrcCharSet( GetTextEncoding() );
158 :
159 84 : delete pExtNameBuff;
160 :
161 84 : delete pOutlineListBuffer;
162 :
163 84 : delete pFormConv;
164 87 : }
165 :
166 3573 : void ImportExcel::SetLastFormula( SCCOL nCol, SCROW nRow, double fVal, sal_uInt16 nXF, ScFormulaCell* pCell )
167 : {
168 3573 : LastFormulaMapType::iterator it = maLastFormulaCells.find(nCol);
169 3573 : if (it == maLastFormulaCells.end())
170 : {
171 : std::pair<LastFormulaMapType::iterator, bool> r =
172 : maLastFormulaCells.insert(
173 260 : LastFormulaMapType::value_type(nCol, LastFormula()));
174 260 : it = r.first;
175 : }
176 :
177 3573 : it->second.mnCol = nCol;
178 3573 : it->second.mnRow = nRow;
179 3573 : it->second.mpCell = pCell;
180 3573 : it->second.mfValue = fVal;
181 3573 : it->second.mnXF = nXF;
182 :
183 3573 : mpLastFormula = &it->second;
184 3573 : }
185 :
186 0 : void ImportExcel::ReadFileSharing()
187 : {
188 : sal_uInt16 nRecommendReadOnly, nPasswordHash;
189 0 : nRecommendReadOnly = maStrm.ReaduInt16();
190 0 : nPasswordHash = maStrm.ReaduInt16();
191 :
192 0 : if( (nRecommendReadOnly != 0) || (nPasswordHash != 0) )
193 : {
194 0 : if( SfxItemSet* pItemSet = GetMedium().GetItemSet() )
195 0 : pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
196 :
197 0 : if( SfxObjectShell* pShell = GetDocShell() )
198 : {
199 0 : if( nRecommendReadOnly != 0 )
200 0 : pShell->SetLoadReadonly( true );
201 0 : if( nPasswordHash != 0 )
202 0 : pShell->SetModifyPasswordHash( nPasswordHash );
203 : }
204 : }
205 0 : }
206 :
207 201619 : sal_uInt16 ImportExcel::ReadXFIndex( const ScAddress& rScPos, bool bBiff2 )
208 : {
209 201619 : sal_uInt16 nXFIdx = 0;
210 201619 : if( bBiff2 )
211 : {
212 : /* #i71453# On first call, check if the file contains XF records (by
213 : trying to access the first XF with index 0). If there are no XFs,
214 : the explicit formatting information contained in each cell record
215 : will be used instead. */
216 0 : if( !mbBiff2HasXfsValid )
217 : {
218 0 : mbBiff2HasXfsValid = true;
219 0 : mbBiff2HasXfs = GetXFBuffer().GetXF( 0 ) != 0;
220 : }
221 : // read formatting information (includes the XF identifier)
222 : sal_uInt8 nFlags1, nFlags2, nFlags3;
223 0 : nFlags1 = maStrm.ReaduInt8();
224 0 : nFlags2 = maStrm.ReaduInt8();
225 0 : nFlags3 = maStrm.ReaduInt8();
226 : /* If the file contains XFs, extract and set the XF identifier,
227 : otherwise get the explicit formatting. */
228 0 : if( mbBiff2HasXfs )
229 : {
230 0 : nXFIdx = ::extract_value< sal_uInt16 >( nFlags1, 0, 6 );
231 : /* If the identifier is equal to 63, then the real identifier is
232 : contained in the preceding IXFE record (stored in mnBiff2XfId). */
233 0 : if( nXFIdx == 63 )
234 0 : nXFIdx = mnIxfeIndex;
235 : }
236 : else
237 : {
238 : /* Let the XclImpXF class do the conversion of the imported
239 : formatting. The XF buffer is empty, therefore will not do any
240 : conversion based on the XF index later on. */
241 0 : XclImpXF::ApplyPatternForBiff2CellFormat( GetRoot(), rScPos, nFlags1, nFlags2, nFlags3 );
242 : }
243 : }
244 : else
245 201619 : nXFIdx = aIn.ReaduInt16();
246 201619 : return nXFIdx;
247 : }
248 :
249 224 : void ImportExcel::ReadDimensions()
250 : {
251 224 : XclRange aXclUsedArea( ScAddress::UNINITIALIZED );
252 224 : if( (maStrm.GetRecId() == EXC_ID2_DIMENSIONS) || (GetBiff() <= EXC_BIFF5) )
253 : {
254 7 : maStrm >> aXclUsedArea;
255 7 : if( (aXclUsedArea.GetColCount() > 1) && (aXclUsedArea.GetRowCount() > 1) )
256 : {
257 : // Excel stores first unused row/column index
258 4 : --aXclUsedArea.maLast.mnCol;
259 4 : --aXclUsedArea.maLast.mnRow;
260 : // create the Calc range
261 4 : SCTAB nScTab = GetCurrScTab();
262 4 : ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
263 4 : GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
264 : // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
265 : }
266 : }
267 : else
268 : {
269 : sal_uInt32 nXclRow1, nXclRow2;
270 217 : nXclRow1 = maStrm.ReaduInt32();
271 217 : nXclRow2 = maStrm.ReaduInt32();
272 217 : aXclUsedArea.maFirst.mnCol = maStrm.ReaduInt16();
273 217 : aXclUsedArea.maLast.mnCol = maStrm.ReaduInt16();
274 351 : if( (nXclRow1 < nXclRow2) && (aXclUsedArea.GetColCount() > 1) &&
275 134 : (nXclRow1 <= static_cast< sal_uInt32 >( GetScMaxPos().Row() )) )
276 : {
277 : // Excel stores first unused row/column index
278 134 : --nXclRow2;
279 134 : --aXclUsedArea.maLast.mnCol;
280 : // convert row indexes to 16-bit values
281 134 : aXclUsedArea.maFirst.mnRow = static_cast< sal_uInt16 >( nXclRow1 );
282 134 : aXclUsedArea.maLast.mnRow = limit_cast< sal_uInt16 >( nXclRow2, aXclUsedArea.maFirst.mnRow, SAL_MAX_UINT16 );
283 : // create the Calc range
284 134 : SCTAB nScTab = GetCurrScTab();
285 134 : ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
286 134 : GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
287 : // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
288 : }
289 : }
290 224 : }
291 :
292 196561 : void ImportExcel::ReadBlank()
293 : {
294 196561 : XclAddress aXclPos;
295 196561 : aIn >> aXclPos;
296 :
297 196561 : ScAddress aScPos( ScAddress::UNINITIALIZED );
298 196561 : if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
299 : {
300 196561 : sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_BLANK );
301 :
302 196561 : GetXFRangeBuffer().SetBlankXF( aScPos, nXFIdx );
303 : }
304 196561 : }
305 :
306 0 : void ImportExcel::ReadInteger()
307 : {
308 0 : XclAddress aXclPos;
309 0 : maStrm >> aXclPos;
310 :
311 0 : ScAddress aScPos( ScAddress::UNINITIALIZED );
312 0 : if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
313 : {
314 0 : sal_uInt16 nXFIdx = ReadXFIndex( aScPos, true );
315 : sal_uInt16 nValue;
316 0 : nValue = maStrm.ReaduInt16();
317 :
318 0 : GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
319 0 : GetDocImport().setNumericCell(aScPos, nValue);
320 : }
321 0 : }
322 :
323 2017 : void ImportExcel::ReadNumber()
324 : {
325 2017 : XclAddress aXclPos;
326 2017 : maStrm >> aXclPos;
327 :
328 2017 : ScAddress aScPos( ScAddress::UNINITIALIZED );
329 2017 : if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
330 : {
331 2017 : sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_NUMBER );
332 : double fValue;
333 2017 : fValue = maStrm.ReadDouble();
334 :
335 2017 : GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
336 2017 : GetDocImport().setNumericCell(aScPos, fValue);
337 : }
338 2017 : }
339 :
340 750 : void ImportExcel::ReadLabel()
341 : {
342 750 : XclAddress aXclPos;
343 750 : maStrm >> aXclPos;
344 :
345 750 : ScAddress aScPos( ScAddress::UNINITIALIZED );
346 750 : if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
347 : {
348 : /* Record ID BIFF XF type String type
349 : 0x0004 2-7 3 byte 8-bit length, byte string
350 : 0x0004 8 3 byte 16-bit length, unicode string
351 : 0x0204 2-7 2 byte 16-bit length, byte string
352 : 0x0204 8 2 byte 16-bit length, unicode string */
353 750 : bool bBiff2 = maStrm.GetRecId() == EXC_ID2_LABEL;
354 750 : sal_uInt16 nXFIdx = ReadXFIndex( aScPos, bBiff2 );
355 750 : XclStrFlags nFlags = (bBiff2 && (GetBiff() <= EXC_BIFF5)) ? EXC_STR_8BITLENGTH : EXC_STR_DEFAULT;
356 750 : XclImpString aString;
357 :
358 : // #i63105# use text encoding from FONT record
359 750 : rtl_TextEncoding eOldTextEnc = GetTextEncoding();
360 750 : if( const XclImpFont* pFont = GetXFBuffer().GetFont( nXFIdx ) )
361 750 : SetTextEncoding( pFont->GetFontEncoding() );
362 750 : aString.Read( maStrm, nFlags );
363 750 : SetTextEncoding( eOldTextEnc );
364 :
365 750 : GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
366 750 : XclImpStringHelper::SetToDocument(GetDocImport(), aScPos, GetRoot(), aString, nXFIdx);
367 : }
368 750 : }
369 :
370 1 : void ImportExcel::ReadBoolErr()
371 : {
372 1 : XclAddress aXclPos;
373 1 : maStrm >> aXclPos;
374 :
375 1 : ScAddress aScPos( ScAddress::UNINITIALIZED );
376 1 : if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
377 : {
378 1 : sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_BOOLERR );
379 : sal_uInt8 nValue, nType;
380 1 : nValue = maStrm.ReaduInt8();
381 1 : nType = maStrm.ReaduInt8();
382 :
383 1 : if( nType == EXC_BOOLERR_BOOL )
384 1 : GetXFRangeBuffer().SetBoolXF( aScPos, nXFIdx );
385 : else
386 0 : GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
387 :
388 : double fValue;
389 1 : const ScTokenArray* pScTokArr = ErrorToFormula( nType, nValue, fValue );
390 1 : ScFormulaCell* pCell = pScTokArr ? new ScFormulaCell(pD, aScPos, *pScTokArr) : new ScFormulaCell(pD, aScPos);
391 1 : pCell->SetHybridDouble( fValue );
392 1 : GetDocImport().setFormulaCell(aScPos, pCell);
393 : }
394 1 : }
395 :
396 2290 : void ImportExcel::ReadRk()
397 : {
398 2290 : XclAddress aXclPos;
399 2290 : maStrm >> aXclPos;
400 :
401 2290 : ScAddress aScPos( ScAddress::UNINITIALIZED );
402 2290 : if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
403 : {
404 2290 : sal_uInt16 nXFIdx = ReadXFIndex( aScPos, false );
405 : sal_Int32 nRk;
406 2290 : nRk = maStrm.ReadInt32();
407 :
408 2290 : GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
409 2290 : GetDocImport().setNumericCell(aScPos, XclTools::GetDoubleFromRK(nRk));
410 : }
411 2290 : }
412 :
413 82 : void ImportExcel::Window1()
414 : {
415 82 : GetDocViewSettings().ReadWindow1( maStrm );
416 82 : }
417 :
418 0 : void ImportExcel::Row25()
419 : {
420 : sal_uInt16 nRow, nRowHeight;
421 :
422 0 : nRow = aIn.ReaduInt16();
423 0 : aIn.Ignore( 4 );
424 :
425 0 : if( ValidRow( nRow ) )
426 : {
427 0 : nRowHeight = aIn.ReaduInt16(); // specify direct in Twips
428 0 : aIn.Ignore( 2 );
429 :
430 0 : if( GetBiff() == EXC_BIFF2 )
431 : {// -------------------- BIFF2
432 0 : pColRowBuff->SetHeight( nRow, nRowHeight );
433 : }
434 : else
435 : {// -------------------- BIFF5
436 : sal_uInt16 nGrbit;
437 :
438 0 : aIn.Ignore( 2 ); // reserved
439 0 : nGrbit = aIn.ReaduInt16();
440 :
441 0 : sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
442 0 : pRowOutlineBuff->SetLevel( nRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
443 0 : pColRowBuff->SetRowSettings( nRow, nRowHeight, nGrbit );
444 : }
445 : }
446 0 : }
447 :
448 0 : void ImportExcel::Bof2()
449 : {
450 : sal_uInt16 nSubType;
451 0 : maStrm.DisableDecryption();
452 0 : maStrm.Ignore( 2 );
453 0 : nSubType = maStrm.ReaduInt16();
454 :
455 0 : if( nSubType == 0x0020 ) // Chart
456 0 : pExcRoot->eDateiTyp = Biff2C;
457 0 : else if( nSubType == 0x0040 ) // Macro
458 0 : pExcRoot->eDateiTyp = Biff2M;
459 : else // #i51490# Excel interprets invalid indexes as worksheet
460 0 : pExcRoot->eDateiTyp = Biff2;
461 0 : }
462 :
463 224 : void ImportExcel::Eof()
464 : {
465 : // POST: cannot be called after an invalid table!
466 224 : EndSheet();
467 224 : IncCurrScTab();
468 224 : }
469 :
470 1 : void ImportExcel::SheetPassword()
471 : {
472 1 : if (GetRoot().GetBiff() != EXC_BIFF8)
473 1 : return;
474 :
475 1 : GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn, GetCurrScTab() );
476 : }
477 :
478 4 : void ImportExcel::Externsheet()
479 : {
480 8 : OUString aUrl, aTabName;
481 : bool bSameWorkBook;
482 8 : OUString aEncodedUrl( aIn.ReadByteString( false ) );
483 4 : XclImpUrlHelper::DecodeUrl( aUrl, aTabName, bSameWorkBook, *pExcRoot->pIR, aEncodedUrl );
484 8 : mnLastRefIdx = pExcRoot->pExtSheetBuff->Add( aUrl, aTabName, bSameWorkBook );
485 4 : }
486 :
487 49 : void ImportExcel:: WinProtection()
488 : {
489 49 : if (GetRoot().GetBiff() != EXC_BIFF8)
490 49 : return;
491 :
492 49 : GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn );
493 : }
494 :
495 0 : void ImportExcel::Columndefault()
496 : {// Default Cell Attributes
497 : sal_uInt16 nColMic, nColMac;
498 : sal_uInt8 nOpt0;
499 :
500 0 : nColMic = aIn.ReaduInt16();
501 0 : nColMac = aIn.ReaduInt16();
502 :
503 : OSL_ENSURE( aIn.GetRecLeft() == (sal_Size)(nColMac - nColMic) * 3 + 2,
504 : "ImportExcel::Columndefault - wrong record size" );
505 :
506 0 : nColMac--;
507 :
508 0 : if( nColMac > MAXCOL )
509 0 : nColMac = static_cast<sal_uInt16>(MAXCOL);
510 :
511 0 : for( sal_uInt16 nCol = nColMic ; nCol <= nColMac ; nCol++ )
512 : {
513 0 : nOpt0 = aIn.ReaduInt8();
514 0 : aIn.Ignore( 2 ); // only 0. Attribut-Byte used
515 :
516 0 : if( nOpt0 & 0x80 ) // Col hidden?
517 0 : pColRowBuff->HideCol( nCol );
518 : }
519 0 : }
520 :
521 0 : void ImportExcel::Array25()
522 : {
523 : sal_uInt16 nFirstRow, nLastRow, nFormLen;
524 : sal_uInt8 nFirstCol, nLastCol;
525 :
526 0 : nFirstRow = aIn.ReaduInt16();
527 0 : nLastRow = aIn.ReaduInt16();
528 0 : nFirstCol = aIn.ReaduInt8();
529 0 : nLastCol = aIn.ReaduInt8();
530 :
531 0 : if( GetBiff() == EXC_BIFF2 )
532 : {// BIFF2
533 0 : aIn.Ignore( 1 );
534 0 : nFormLen = aIn.ReaduInt8();
535 : }
536 : else
537 : {// BIFF5
538 0 : aIn.Ignore( 6 );
539 0 : nFormLen = aIn.ReaduInt16();
540 : }
541 :
542 0 : if( ValidColRow( nLastCol, nLastRow ) )
543 : {
544 : // the read mark is now on the formula, length in nFormLen
545 : const ScTokenArray* pErgebnis;
546 :
547 : pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
548 0 : static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
549 0 : pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
550 :
551 : OSL_ENSURE( pErgebnis, "*ImportExcel::Array25(): ScTokenArray is NULL!" );
552 :
553 0 : ScDocumentImport& rDoc = GetDocImport();
554 0 : ScRange aArrayRange(nFirstCol, nFirstRow, GetCurrScTab(), nLastCol, nLastRow, GetCurrScTab());
555 0 : rDoc.setMatrixCells(aArrayRange, *pErgebnis, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1);
556 : }
557 0 : }
558 :
559 81 : void ImportExcel::Rec1904()
560 : {
561 : sal_uInt16 n1904;
562 :
563 81 : n1904 = aIn.ReaduInt16();
564 :
565 81 : if( n1904 )
566 : {// 1904 date system
567 1 : ScDocOptions aOpt = pD->GetDocOptions();
568 1 : aOpt.SetDate( 1, 1, 1904 );
569 1 : pD->SetDocOptions( aOpt );
570 1 : pD->GetFormatTable()->ChangeNullDate( 1, 1, 1904 );
571 : }
572 81 : }
573 :
574 0 : void ImportExcel::Externname25()
575 : {
576 : sal_uInt32 nRes;
577 : sal_uInt16 nOpt;
578 :
579 0 : nOpt = aIn.ReaduInt16();
580 0 : nRes = aIn.ReaduInt32();
581 :
582 0 : OUString aName( aIn.ReadByteString( false ) );
583 :
584 0 : if( ( nOpt & 0x0001 ) || ( ( nOpt & 0xFFFE ) == 0x0000 ) )
585 : {// external name
586 0 : aName = ScfTools::ConvertToScDefinedName( aName );
587 0 : pExcRoot->pExtNameBuff->AddName( aName, mnLastRefIdx );
588 : }
589 0 : else if( nOpt & 0x0010 )
590 : {// ole link
591 0 : pExcRoot->pExtNameBuff->AddOLE( aName, mnLastRefIdx, nRes ); // nRes is storage ID
592 : }
593 : else
594 : {// dde link
595 0 : pExcRoot->pExtNameBuff->AddDDE( aName, mnLastRefIdx );
596 0 : }
597 0 : }
598 :
599 0 : void ImportExcel::Colwidth()
600 : {// Column Width
601 : sal_uInt8 nColFirst, nColLast;
602 : sal_uInt16 nColWidth;
603 :
604 0 : nColFirst = aIn.ReaduInt8();
605 0 : nColLast = aIn.ReaduInt8();
606 0 : nColWidth = aIn.ReaduInt16();
607 :
608 : //TODO: add a check for the unlikely case of changed MAXCOL (-> XclImpAddressConverter)
609 : // if( nColLast > MAXCOL )
610 : // nColLast = static_cast<sal_uInt16>(MAXCOL);
611 :
612 0 : sal_uInt16 nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
613 0 : pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
614 0 : }
615 :
616 0 : void ImportExcel::Defrowheight2()
617 : {
618 : sal_uInt16 nDefHeight;
619 0 : nDefHeight = maStrm.ReaduInt16();
620 0 : nDefHeight &= 0x7FFF;
621 0 : pColRowBuff->SetDefHeight( nDefHeight, EXC_DEFROW_UNSYNCED );
622 0 : }
623 :
624 13 : void ImportExcel::SheetProtect()
625 : {
626 13 : if (GetRoot().GetBiff() != EXC_BIFF8)
627 13 : return;
628 :
629 13 : GetRoot().GetSheetProtectBuffer().ReadProtect( aIn, GetCurrScTab() );
630 : }
631 :
632 52 : void ImportExcel::DocProtect()
633 : {
634 52 : if (GetRoot().GetBiff() != EXC_BIFF8)
635 55 : return;
636 :
637 49 : GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn );
638 : }
639 :
640 49 : void ImportExcel::DocPasssword()
641 : {
642 49 : if (GetRoot().GetBiff() != EXC_BIFF8)
643 49 : return;
644 :
645 49 : GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn );
646 : }
647 :
648 82 : void ImportExcel::Codepage()
649 : {
650 82 : SetCodePage( maStrm.ReaduInt16() );
651 82 : }
652 :
653 0 : void ImportExcel::Ixfe()
654 : {
655 0 : mnIxfeIndex = maStrm.ReaduInt16();
656 0 : }
657 :
658 222 : void ImportExcel::DefColWidth()
659 : {
660 : // stored as entire characters -> convert to 1/256 of characters (as in COLINFO)
661 222 : double fDefWidth = 256.0 * maStrm.ReaduInt16();
662 :
663 : // #i3006# additional space for default width - Excel adds space depending on font size
664 222 : long nFontHt = GetFontBuffer().GetAppFontData().mnHeight;
665 222 : fDefWidth += XclTools::GetXclDefColWidthCorrection( nFontHt );
666 :
667 222 : sal_uInt16 nScWidth = XclTools::GetScColumnWidth( limit_cast< sal_uInt16 >( fDefWidth ), GetCharWidth() );
668 222 : pColRowBuff->SetDefWidth( nScWidth );
669 222 : }
670 :
671 416 : void ImportExcel::Colinfo()
672 : {// Column Formatting Information
673 : sal_uInt16 nColFirst, nColLast, nColWidth, nXF;
674 : sal_uInt16 nOpt;
675 :
676 416 : nColFirst = aIn.ReaduInt16();
677 416 : nColLast = aIn.ReaduInt16();
678 416 : nColWidth = aIn.ReaduInt16();
679 416 : nXF = aIn.ReaduInt16();
680 416 : nOpt = aIn.ReaduInt16();
681 :
682 416 : if( nColFirst > MAXCOL )
683 416 : return;
684 :
685 416 : if( nColLast > MAXCOL )
686 0 : nColLast = static_cast<sal_uInt16>(MAXCOL);
687 :
688 416 : bool bHidden = ::get_flag( nOpt, EXC_COLINFO_HIDDEN );
689 416 : bool bCollapsed = ::get_flag( nOpt, EXC_COLINFO_COLLAPSED );
690 416 : sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nOpt, 8, 3 );
691 416 : pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed );
692 :
693 416 : if( bHidden )
694 1 : pColRowBuff->HideColRange( nColFirst, nColLast );
695 :
696 416 : sal_uInt16 nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
697 416 : pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
698 416 : pColRowBuff->SetDefaultXF( nColFirst, nColLast, nXF );
699 : }
700 :
701 223 : void ImportExcel::Wsbool()
702 : {
703 : sal_uInt16 nFlags;
704 223 : nFlags = aIn.ReaduInt16();
705 :
706 223 : pRowOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_ROWBELOW ) );
707 223 : pColOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_COLBELOW ) );
708 :
709 223 : GetPageSettings().SetFitToPages( ::get_flag( nFlags, EXC_WSBOOL_FITTOPAGE ) );
710 223 : }
711 :
712 6 : void ImportExcel::Boundsheet()
713 : {
714 6 : sal_uInt16 nGrbit = 0;
715 :
716 6 : if( GetBiff() == EXC_BIFF5 )
717 : {
718 6 : aIn.DisableDecryption();
719 6 : maSheetOffsets.push_back( aIn.ReaduInt32() );
720 6 : aIn.EnableDecryption();
721 6 : nGrbit = aIn.ReaduInt16();
722 : }
723 :
724 6 : OUString aName( aIn.ReadByteString( false ) );
725 :
726 6 : SCTAB nScTab = static_cast< SCTAB >( nBdshtTab );
727 6 : if( nScTab > 0 )
728 : {
729 : OSL_ENSURE( !pD->HasTable( nScTab ), "ImportExcel::Boundsheet - sheet exists already" );
730 3 : pD->MakeTable( nScTab );
731 : }
732 :
733 6 : if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
734 0 : pD->SetVisible( nScTab, false );
735 :
736 6 : if( !pD->RenameTab( nScTab, aName ) )
737 : {
738 0 : pD->CreateValidTabName( aName );
739 0 : pD->RenameTab( nScTab, aName );
740 : }
741 :
742 6 : nBdshtTab++;
743 6 : }
744 :
745 84 : void ImportExcel::Country()
746 : {
747 : sal_uInt16 nUICountry, nDocCountry;
748 84 : nUICountry = maStrm.ReaduInt16();
749 84 : nDocCountry = maStrm.ReaduInt16();
750 :
751 : // Store system language in XclRoot
752 84 : LanguageType eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nDocCountry ) );
753 84 : if( eLanguage != LANGUAGE_DONTKNOW )
754 84 : SetDocLanguage( eLanguage );
755 :
756 : // Set Excel UI language in add-in name translator
757 84 : eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nUICountry ) );
758 84 : if( eLanguage != LANGUAGE_DONTKNOW )
759 84 : SetUILanguage( eLanguage );
760 84 : }
761 :
762 77 : void ImportExcel::ReadUsesElfs()
763 : {
764 77 : if( maStrm.ReaduInt16() != 0 )
765 : {
766 21 : ScDocOptions aDocOpt = GetDoc().GetDocOptions();
767 21 : aDocOpt.SetLookUpColRowNames( true );
768 21 : GetDoc().SetDocOptions( aDocOpt );
769 : }
770 77 : }
771 :
772 81 : void ImportExcel::Hideobj()
773 : {
774 : sal_uInt16 nHide;
775 : ScVObjMode eOle, eChart, eDraw;
776 :
777 81 : nHide = aIn.ReaduInt16();
778 :
779 81 : ScViewOptions aOpts( pD->GetViewOptions() );
780 :
781 81 : switch( nHide )
782 : {
783 : case 1: // Placeholders
784 0 : eOle = VOBJ_MODE_SHOW; // in Excel 97 only charts as place holder are displayed
785 0 : eChart = VOBJ_MODE_SHOW; //#i80528# VOBJ_MODE_DUMMY replaced by VOBJ_MODE_SHOW now
786 0 : eDraw = VOBJ_MODE_SHOW;
787 0 : break;
788 : case 2: // Hide all
789 0 : eOle = VOBJ_MODE_HIDE;
790 0 : eChart = VOBJ_MODE_HIDE;
791 0 : eDraw = VOBJ_MODE_HIDE;
792 0 : break;
793 : default: // Show all
794 81 : eOle = VOBJ_MODE_SHOW;
795 81 : eChart = VOBJ_MODE_SHOW;
796 81 : eDraw = VOBJ_MODE_SHOW;
797 81 : break;
798 : }
799 :
800 81 : aOpts.SetObjMode( VOBJ_TYPE_OLE, eOle );
801 81 : aOpts.SetObjMode( VOBJ_TYPE_CHART, eChart );
802 81 : aOpts.SetObjMode( VOBJ_TYPE_DRAW, eDraw );
803 :
804 81 : pD->SetViewOptions( aOpts );
805 81 : }
806 :
807 1 : void ImportExcel::Standardwidth()
808 : {
809 1 : sal_uInt16 nScWidth = XclTools::GetScColumnWidth( maStrm.ReaduInt16(), GetCharWidth() );
810 1 : pColRowBuff->SetDefWidth( nScWidth, true );
811 1 : }
812 :
813 122 : void ImportExcel::Shrfmla()
814 : {
815 122 : switch (mnLastRecId)
816 : {
817 : case EXC_ID2_FORMULA:
818 : case EXC_ID3_FORMULA:
819 : case EXC_ID4_FORMULA:
820 : // This record MUST immediately follow a FORMULA record.
821 122 : break;
822 : default:
823 0 : return;
824 : }
825 :
826 122 : if (!mpLastFormula)
827 : // The last FORMULA record should have left this data.
828 0 : return;
829 :
830 122 : aIn.Ignore( 8 );
831 122 : sal_uInt16 nLenExpr = aIn.ReaduInt16();
832 :
833 : // read mark is now on the formula
834 :
835 : const ScTokenArray* pErgebnis;
836 :
837 : // The shared range in this record is erroneous more than half the time.
838 : // Don't ever rely on it. Use the one from the formula cell above.
839 122 : SCCOL nCol1 = mpLastFormula->mnCol;
840 122 : SCROW nRow1 = mpLastFormula->mnRow;
841 :
842 122 : ScAddress aPos(nCol1, nRow1, GetCurrScTab());
843 122 : pFormConv->Reset(aPos);
844 122 : pFormConv->Convert( pErgebnis, maStrm, nLenExpr, true, FT_SharedFormula );
845 :
846 : OSL_ENSURE( pErgebnis, "+ImportExcel::Shrfmla(): ScTokenArray is NULL!" );
847 :
848 122 : pExcRoot->pShrfmlaBuff->Store(aPos, *pErgebnis);
849 :
850 : // Create formula cell for the last formula record.
851 :
852 122 : ScDocumentImport& rDoc = GetDocImport();
853 :
854 122 : ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis);
855 122 : pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8);
856 122 : rDoc.getDoc().EnsureTable(aPos.Tab());
857 122 : rDoc.setFormulaCell(aPos, pCell);
858 122 : pCell->SetNeedNumberFormat(false);
859 122 : if (!rtl::math::isNan(mpLastFormula->mfValue))
860 120 : pCell->SetResultDouble(mpLastFormula->mfValue);
861 :
862 122 : GetXFRangeBuffer().SetXF(aPos, mpLastFormula->mnXF);
863 122 : mpLastFormula->mpCell = pCell;
864 : }
865 :
866 2483 : void ImportExcel::Mulrk()
867 : {
868 2483 : XclAddress aXclPos;
869 : sal_uInt16 nXF;
870 : sal_Int32 nRkNum;
871 :
872 2483 : aIn >> aXclPos;
873 :
874 15160 : for( XclAddress aCurrXclPos( aXclPos ); (aXclPos.mnCol <= aCurrXclPos.mnCol) && (aIn.GetRecLeft() > 2); ++aCurrXclPos.mnCol )
875 : {
876 12677 : nXF = aIn.ReaduInt16();
877 12677 : nRkNum = aIn.ReadInt32();
878 :
879 12677 : ScAddress aScPos( ScAddress::UNINITIALIZED );
880 12677 : if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
881 : {
882 12677 : GetXFRangeBuffer().SetXF( aScPos, nXF );
883 12677 : GetDocImport().setNumericCell(aScPos, XclTools::GetDoubleFromRK(nRkNum));
884 : }
885 : }
886 2483 : }
887 :
888 2468 : void ImportExcel::Mulblank()
889 : {
890 2468 : XclAddress aXclPos;
891 : sal_uInt16 nXF;
892 :
893 2468 : aIn >> aXclPos;
894 :
895 43291 : for( XclAddress aCurrXclPos( aXclPos ); (aXclPos.mnCol <= aCurrXclPos.mnCol) && (aIn.GetRecLeft() > 2); ++aCurrXclPos.mnCol )
896 : {
897 40823 : nXF = aIn.ReaduInt16();
898 :
899 40823 : ScAddress aScPos( ScAddress::UNINITIALIZED );
900 40823 : if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
901 34924 : GetXFRangeBuffer().SetBlankXF( aScPos, nXF );
902 : }
903 2468 : }
904 :
905 0 : void ImportExcel::Rstring()
906 : {
907 0 : XclAddress aXclPos;
908 : sal_uInt16 nXFIdx;
909 0 : aIn >> aXclPos;
910 0 : nXFIdx = aIn.ReaduInt16();
911 :
912 0 : ScAddress aScPos( ScAddress::UNINITIALIZED );
913 0 : if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
914 : {
915 : // unformatted Unicode string with separate formatting information
916 0 : XclImpString aString;
917 :
918 : // #i63105# use text encoding from FONT record
919 0 : rtl_TextEncoding eOldTextEnc = GetTextEncoding();
920 0 : if( const XclImpFont* pFont = GetXFBuffer().GetFont( nXFIdx ) )
921 0 : SetTextEncoding( pFont->GetFontEncoding() );
922 0 : aString.Read( maStrm );
923 0 : SetTextEncoding( eOldTextEnc );
924 :
925 : // character formatting runs
926 0 : if( !aString.IsRich() )
927 0 : aString.ReadFormats( maStrm );
928 :
929 0 : GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
930 0 : XclImpStringHelper::SetToDocument(GetDocImport(), aScPos, *this, aString, nXFIdx);
931 : }
932 0 : }
933 :
934 40 : void ImportExcel::Cellmerging()
935 : {
936 40 : XclImpAddressConverter& rAddrConv = GetAddressConverter();
937 40 : SCTAB nScTab = GetCurrScTab();
938 :
939 : sal_uInt16 nCount;
940 40 : nCount = maStrm.ReaduInt16();
941 754 : for( sal_uInt16 nIdx = 0; (nIdx < nCount) && (maStrm.GetRecLeft() >= 8); ++nIdx )
942 : {
943 714 : XclRange aXclRange;
944 714 : maStrm >> aXclRange; // 16-bit rows and columns
945 714 : ScRange aScRange( ScAddress::UNINITIALIZED );
946 714 : if( rAddrConv.ConvertRange( aScRange, aXclRange, nScTab, nScTab, true ) )
947 714 : GetXFRangeBuffer().SetMerge( aScRange.aStart.Col(), aScRange.aStart.Row(), aScRange.aEnd.Col(), aScRange.aEnd.Row() );
948 : }
949 40 : }
950 :
951 1 : void ImportExcel::Olesize()
952 : {
953 1 : XclRange aXclOleSize( ScAddress::UNINITIALIZED );
954 1 : maStrm.Ignore( 2 );
955 1 : aXclOleSize.Read( maStrm, false );
956 :
957 1 : SCTAB nScTab = GetCurrScTab();
958 1 : GetAddressConverter().ConvertRange( maScOleSize, aXclOleSize, nScTab, nScTab, false );
959 1 : }
960 :
961 267346 : void ImportExcel::Row34()
962 : {
963 : sal_uInt16 nRow, nRowHeight, nGrbit, nXF;
964 :
965 267346 : nRow = aIn.ReaduInt16();
966 267346 : aIn.Ignore( 4 );
967 :
968 267346 : SCROW nScRow = static_cast< SCROW >( nRow );
969 :
970 267346 : if( ValidRow( nScRow ) )
971 : {
972 267346 : nRowHeight = aIn.ReaduInt16(); // specify direct in Twips
973 267346 : aIn.Ignore( 4 );
974 :
975 267346 : nRowHeight = nRowHeight & 0x7FFF; // Bit 15: Row Height not changed manually
976 267346 : if( !nRowHeight )
977 0 : nRowHeight = (GetBiff() == EXC_BIFF2) ? 0x25 : 0x225;
978 :
979 267346 : nGrbit = aIn.ReaduInt16();
980 267346 : nXF = aIn.ReaduInt16();
981 :
982 267346 : sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
983 267346 : pRowOutlineBuff->SetLevel( nScRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
984 267346 : pColRowBuff->SetRowSettings( nScRow, nRowHeight, nGrbit );
985 :
986 267346 : if( nGrbit & EXC_ROW_USEDEFXF )
987 353 : GetXFRangeBuffer().SetRowDefXF( nScRow, nXF & EXC_ROW_XFMASK );
988 : }
989 267346 : }
990 :
991 0 : void ImportExcel::Bof3()
992 : {
993 : sal_uInt16 nSubType;
994 0 : maStrm.DisableDecryption();
995 0 : maStrm.Ignore( 2 );
996 0 : nSubType = maStrm.ReaduInt16();
997 :
998 : OSL_ENSURE( nSubType != 0x0100, "*ImportExcel::Bof3(): Biff3 as Workbook?!" );
999 0 : if( nSubType == 0x0100 ) // Book
1000 0 : pExcRoot->eDateiTyp = Biff3W;
1001 0 : else if( nSubType == 0x0020 ) // Chart
1002 0 : pExcRoot->eDateiTyp = Biff3C;
1003 0 : else if( nSubType == 0x0040 ) // Macro
1004 0 : pExcRoot->eDateiTyp = Biff3M;
1005 : else // #i51490# Excel interprets invalid indexes as worksheet
1006 0 : pExcRoot->eDateiTyp = Biff3;
1007 0 : }
1008 :
1009 8 : void ImportExcel::Array34()
1010 : {
1011 : sal_uInt16 nFirstRow, nLastRow, nFormLen;
1012 : sal_uInt8 nFirstCol, nLastCol;
1013 :
1014 8 : nFirstRow = aIn.ReaduInt16();
1015 8 : nLastRow = aIn.ReaduInt16();
1016 8 : nFirstCol = aIn.ReaduInt8();
1017 8 : nLastCol = aIn.ReaduInt8();
1018 8 : aIn.Ignore( (GetBiff() >= EXC_BIFF5) ? 6 : 2 );
1019 8 : nFormLen = aIn.ReaduInt16();
1020 :
1021 8 : if( ValidColRow( nLastCol, nLastRow ) )
1022 : {
1023 : // the read mark is now on the formula, length in nFormLen
1024 : const ScTokenArray* pErgebnis;
1025 :
1026 : pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
1027 8 : static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
1028 8 : pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
1029 :
1030 : OSL_ENSURE( pErgebnis, "+ImportExcel::Array34(): ScTokenArray is NULL!" );
1031 :
1032 8 : ScDocumentImport& rDoc = GetDocImport();
1033 8 : ScRange aArrayRange(nFirstCol, nFirstRow, GetCurrScTab(), nLastCol, nLastRow, GetCurrScTab());
1034 8 : rDoc.setMatrixCells(aArrayRange, *pErgebnis, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1);
1035 : }
1036 8 : }
1037 :
1038 223 : void ImportExcel::Defrowheight345()
1039 : {
1040 : sal_uInt16 nFlags, nDefHeight;
1041 223 : nFlags = maStrm.ReaduInt16();
1042 223 : nDefHeight = maStrm.ReaduInt16();
1043 223 : pColRowBuff->SetDefHeight( nDefHeight, nFlags );
1044 223 : }
1045 :
1046 2 : void ImportExcel::TableOp()
1047 : {
1048 : sal_uInt16 nFirstRow, nLastRow;
1049 : sal_uInt8 nFirstCol, nLastCol;
1050 : sal_uInt16 nGrbit;
1051 : sal_uInt16 nInpRow, nInpCol, nInpRow2, nInpCol2;
1052 :
1053 2 : nFirstRow = aIn.ReaduInt16();
1054 2 : nLastRow = aIn.ReaduInt16();
1055 2 : nFirstCol = aIn.ReaduInt8();
1056 2 : nLastCol = aIn.ReaduInt8();
1057 2 : nGrbit = aIn.ReaduInt16();
1058 2 : nInpRow = aIn.ReaduInt16();
1059 2 : nInpCol = aIn.ReaduInt16();
1060 2 : nInpRow2 = aIn.ReaduInt16();
1061 2 : nInpCol2 = aIn.ReaduInt16();
1062 :
1063 2 : if( ValidColRow( nLastCol, nLastRow ) )
1064 : {
1065 2 : if( nFirstCol && nFirstRow )
1066 : {
1067 2 : ScTabOpParam aTabOpParam;
1068 2 : aTabOpParam.meMode = (nGrbit & EXC_TABLEOP_BOTH) ? ScTabOpParam::Both : ((nGrbit & EXC_TABLEOP_ROW) ? ScTabOpParam::Row : ScTabOpParam::Column);
1069 2 : sal_uInt16 nCol = nFirstCol - 1;
1070 2 : sal_uInt16 nRow = nFirstRow - 1;
1071 2 : SCTAB nTab = GetCurrScTab();
1072 2 : switch (aTabOpParam.meMode)
1073 : {
1074 : case ScTabOpParam::Column:
1075 : aTabOpParam.aRefFormulaCell.Set(
1076 : static_cast<SCCOL>(nFirstCol),
1077 : static_cast<SCROW>(nFirstRow - 1), nTab, false,
1078 1 : false, false );
1079 : aTabOpParam.aRefFormulaEnd.Set(
1080 : static_cast<SCCOL>(nLastCol),
1081 : static_cast<SCROW>(nFirstRow - 1), nTab, false,
1082 1 : false, false );
1083 : aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol),
1084 : static_cast<SCROW>(nInpRow), nTab, false, false,
1085 1 : false );
1086 1 : nRow++;
1087 1 : break;
1088 : case ScTabOpParam::Row:
1089 : aTabOpParam.aRefFormulaCell.Set(
1090 : static_cast<SCCOL>(nFirstCol - 1),
1091 : static_cast<SCROW>(nFirstRow), nTab, false, false,
1092 0 : false );
1093 : aTabOpParam.aRefFormulaEnd.Set(
1094 : static_cast<SCCOL>(nFirstCol - 1),
1095 : static_cast<SCROW>(nLastRow), nTab, false, false,
1096 0 : false );
1097 : aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
1098 : static_cast<SCROW>(nInpRow), nTab, false, false,
1099 0 : false );
1100 0 : nCol++;
1101 0 : break;
1102 : case ScTabOpParam::Both: // TWO-INPUT
1103 : aTabOpParam.aRefFormulaCell.Set(
1104 : static_cast<SCCOL>(nFirstCol - 1),
1105 : static_cast<SCROW>(nFirstRow - 1), nTab, false,
1106 1 : false, false );
1107 : aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
1108 : static_cast<SCROW>(nInpRow), nTab, false, false,
1109 1 : false );
1110 : aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol2),
1111 : static_cast<SCROW>(nInpRow2), nTab, false, false,
1112 1 : false );
1113 1 : break;
1114 : }
1115 :
1116 2 : ScDocumentImport& rDoc = GetDocImport();
1117 2 : ScRange aTabOpRange(nCol, nRow, nTab, nLastCol, nLastRow, nTab);
1118 2 : rDoc.setTableOpCells(aTabOpRange, aTabOpParam);
1119 : }
1120 : }
1121 : else
1122 : {
1123 0 : bTabTruncated = true;
1124 0 : GetTracer().TraceInvalidRow(nLastRow, MAXROW);
1125 : }
1126 2 : }
1127 :
1128 0 : void ImportExcel::Bof4()
1129 : {
1130 : sal_uInt16 nSubType;
1131 0 : maStrm.DisableDecryption();
1132 0 : maStrm.Ignore( 2 );
1133 0 : nSubType = maStrm.ReaduInt16();
1134 :
1135 0 : if( nSubType == 0x0100 ) // Book
1136 0 : pExcRoot->eDateiTyp = Biff4W;
1137 0 : else if( nSubType == 0x0020 ) // Chart
1138 0 : pExcRoot->eDateiTyp = Biff4C;
1139 0 : else if( nSubType == 0x0040 ) // Macro
1140 0 : pExcRoot->eDateiTyp = Biff4M;
1141 : else // #i51490# Excel interprets invalid indexes as worksheet
1142 0 : pExcRoot->eDateiTyp = Biff4;
1143 0 : }
1144 :
1145 308 : void ImportExcel::Bof5()
1146 : {
1147 : //POST: eDateiTyp = Type of the file to be read
1148 : sal_uInt16 nSubType, nVers;
1149 : BiffTyp eDatei;
1150 :
1151 308 : maStrm.DisableDecryption();
1152 308 : nVers = maStrm.ReaduInt16();
1153 308 : nSubType = maStrm.ReaduInt16( );
1154 :
1155 308 : switch( nSubType )
1156 : {
1157 83 : case 0x0005: eDatei = Biff5W; break; // workbook globals
1158 0 : case 0x0006: eDatei = Biff5V; break; // VB module
1159 216 : case 0x0010: eDatei = Biff5; break; // worksheet
1160 0 : case 0x0020: eDatei = Biff5C; break; // chart
1161 8 : case 0x0040: eDatei = Biff5M4; break; // macro sheet
1162 : default:
1163 1 : pExcRoot->eDateiTyp = BiffX;
1164 309 : return;
1165 : }
1166 :
1167 307 : if( nVers == 0x0600 && (GetBiff() == EXC_BIFF8) )
1168 298 : eDatei = ( BiffTyp ) ( eDatei - Biff5 + Biff8 );
1169 :
1170 307 : pExcRoot->eDateiTyp = eDatei;
1171 : }
1172 :
1173 224 : void ImportExcel::EndSheet()
1174 : {
1175 224 : pExcRoot->pExtSheetBuff->Reset();
1176 :
1177 224 : if( GetBiff() <= EXC_BIFF5 )
1178 : {
1179 6 : pExcRoot->pExtNameBuff->Reset();
1180 6 : mnLastRefIdx = 0;
1181 : }
1182 :
1183 224 : FinalizeTable();
1184 224 : }
1185 :
1186 224 : void ImportExcel::NewTable()
1187 : {
1188 224 : SCTAB nTab = GetCurrScTab();
1189 224 : if( nTab > 0 && !pD->HasTable( nTab ) )
1190 0 : pD->MakeTable( nTab );
1191 :
1192 224 : if (nTab == 0 && GetBiff() == EXC_BIFF2)
1193 : {
1194 : // For Excel 2.1 Worksheet file, we need to set the file name as the
1195 : // sheet name.
1196 0 : INetURLObject aURL(GetDocUrl());
1197 0 : pD->RenameTab(0, aURL.getBase(), false);
1198 : }
1199 :
1200 224 : pExcRoot->pShrfmlaBuff->Clear();
1201 224 : maLastFormulaCells.clear();
1202 224 : mpLastFormula = NULL;
1203 :
1204 224 : InitializeTable( nTab );
1205 :
1206 224 : XclImpOutlineDataBuffer* pNewItem = new XclImpOutlineDataBuffer( GetRoot(), nTab );
1207 224 : pOutlineListBuffer->push_back( pNewItem );
1208 224 : pExcRoot->pColRowBuff = pColRowBuff = pNewItem->GetColRowBuff();
1209 224 : pColOutlineBuff = pNewItem->GetColOutline();
1210 224 : pRowOutlineBuff = pNewItem->GetRowOutline();
1211 224 : }
1212 :
1213 1 : const ScTokenArray* ImportExcel::ErrorToFormula( bool bErrOrVal, sal_uInt8 nError, double& rVal )
1214 : {
1215 1 : return pFormConv->GetBoolErr( XclTools::ErrorToEnum( rVal, bErrOrVal, nError ) );
1216 : }
1217 :
1218 3 : void ImportExcel::AdjustRowHeight()
1219 : {
1220 : /* Speed up chart import: import all sheets without charts, then
1221 : update row heights (here), last load all charts -> do not any longer
1222 : update inside of ScDocShell::ConvertFrom() (causes update of existing
1223 : charts during each and every change of row height). */
1224 3 : if( ScModelObj* pDocObj = GetDocModelObj() )
1225 3 : pDocObj->UpdateAllRowHeights();
1226 3 : }
1227 :
1228 84 : void ImportExcel::PostDocLoad()
1229 : {
1230 : /* Set automatic page numbering in Default page style (default is "page number = 1").
1231 : Otherwise hidden tables (i.e. for scenarios) which have Default page style will
1232 : break automatic page numbering. */
1233 84 : if( SfxStyleSheetBase* pStyleSheet = GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PAGE ) )
1234 84 : pStyleSheet->GetItemSet().Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, 0 ) );
1235 :
1236 : // outlines for all sheets, sets hidden rows and columns (#i11776# after filtered ranges)
1237 308 : for (XclImpOutlineListBuffer::iterator itBuffer = pOutlineListBuffer->begin(); itBuffer != pOutlineListBuffer->end(); ++itBuffer)
1238 224 : itBuffer->Convert();
1239 :
1240 : // document view settings (before visible OLE area)
1241 84 : GetDocViewSettings().Finalize();
1242 :
1243 : // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area)
1244 84 : GetObjectManager().ConvertObjects();
1245 :
1246 : // visible area (used if this document is an embedded OLE object)
1247 84 : if( SfxObjectShell* pDocShell = GetDocShell() )
1248 : {
1249 : // visible area if embedded
1250 84 : const ScExtDocSettings& rDocSett = GetExtDocOptions().GetDocSettings();
1251 84 : SCTAB nDisplScTab = rDocSett.mnDisplTab;
1252 :
1253 : /* #i44077# If a new OLE object is inserted from file, there is no
1254 : OLESIZE record in the Excel file. Calculate used area from file
1255 : contents (used cells and drawing objects). */
1256 84 : if( !maScOleSize.IsValid() )
1257 : {
1258 : // used area of displayed sheet (cell contents)
1259 83 : if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nDisplScTab ) )
1260 81 : maScOleSize = pTabSett->maUsedArea;
1261 : // add all valid drawing objects
1262 83 : ScRange aScObjArea = GetObjectManager().GetUsedArea( nDisplScTab );
1263 83 : if( aScObjArea.IsValid() )
1264 35 : maScOleSize.ExtendTo( aScObjArea );
1265 : }
1266 :
1267 : // valid size found - set it at the document
1268 84 : if( maScOleSize.IsValid() )
1269 : {
1270 77 : pDocShell->SetVisArea( GetDoc().GetMMRect(
1271 77 : maScOleSize.aStart.Col(), maScOleSize.aStart.Row(),
1272 231 : maScOleSize.aEnd.Col(), maScOleSize.aEnd.Row(), nDisplScTab ) );
1273 77 : GetDoc().SetVisibleTab( nDisplScTab );
1274 : }
1275 : }
1276 :
1277 : // open forms in alive mode (has no effect, if no controls in document)
1278 84 : if( ScModelObj* pDocObj = GetDocModelObj() )
1279 84 : pDocObj->setPropertyValue( SC_UNO_APPLYFMDES, uno::Any( false ) );
1280 :
1281 : // enables extended options to be set to the view after import
1282 84 : GetExtDocOptions().SetChanged( true );
1283 :
1284 : // root data owns the extended document options -> create a new object
1285 84 : GetDoc().SetExtDocOptions( new ScExtDocOptions( GetExtDocOptions() ) );
1286 :
1287 84 : const SCTAB nLast = pD->GetTableCount();
1288 : const ScRange* p;
1289 :
1290 84 : if( pExcRoot->pPrintRanges->HasRanges() )
1291 : {
1292 21 : for( SCTAB n = 0 ; n < nLast ; n++ )
1293 : {
1294 16 : p = pExcRoot->pPrintRanges->First(n);
1295 16 : if( p )
1296 : {
1297 5 : pD->ClearPrintRanges( n );
1298 18 : while( p )
1299 : {
1300 8 : pD->AddPrintRange( n, *p );
1301 8 : p = pExcRoot->pPrintRanges->Next();
1302 : }
1303 : }
1304 : else
1305 : {
1306 : // #i4063# no print ranges -> print entire sheet
1307 11 : pD->SetPrintEntireSheet( n );
1308 : }
1309 : }
1310 5 : GetTracer().TracePrintRange();
1311 : }
1312 :
1313 84 : if( pExcRoot->pPrintTitles->HasRanges() )
1314 : {
1315 0 : for( SCTAB n = 0 ; n < nLast ; n++ )
1316 : {
1317 0 : p = pExcRoot->pPrintTitles->First(n);
1318 0 : if( p )
1319 : {
1320 0 : bool bRowVirgin = true;
1321 0 : bool bColVirgin = true;
1322 :
1323 0 : while( p )
1324 : {
1325 0 : if( p->aStart.Col() == 0 && p->aEnd.Col() == MAXCOL && bRowVirgin )
1326 : {
1327 0 : pD->SetRepeatRowRange( n, p );
1328 0 : bRowVirgin = false;
1329 : }
1330 :
1331 0 : if( p->aStart.Row() == 0 && p->aEnd.Row() == MAXROW && bColVirgin )
1332 : {
1333 0 : pD->SetRepeatColRange( n, p );
1334 0 : bColVirgin = false;
1335 : }
1336 :
1337 0 : p = pExcRoot->pPrintTitles->Next();
1338 : }
1339 : }
1340 : }
1341 : }
1342 84 : }
1343 :
1344 224 : XclImpOutlineDataBuffer::XclImpOutlineDataBuffer( const XclImpRoot& rRoot, SCTAB nScTab ) :
1345 : XclImpRoot( rRoot ),
1346 448 : mxColOutlineBuff( new XclImpOutlineBuffer( rRoot.GetXclMaxPos().Col() + 1 ) ),
1347 448 : mxRowOutlineBuff( new XclImpOutlineBuffer( rRoot.GetXclMaxPos().Row() + 1 ) ),
1348 224 : mxColRowBuff( new XclImpColRowSettings( rRoot ) ),
1349 1344 : mnScTab( nScTab )
1350 : {
1351 224 : }
1352 :
1353 448 : XclImpOutlineDataBuffer::~XclImpOutlineDataBuffer()
1354 : {
1355 448 : }
1356 :
1357 224 : void XclImpOutlineDataBuffer::Convert()
1358 : {
1359 224 : mxColOutlineBuff->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab, true )->GetColArray() );
1360 224 : mxColOutlineBuff->MakeScOutline();
1361 :
1362 224 : mxRowOutlineBuff->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab, true )->GetRowArray() );
1363 224 : mxRowOutlineBuff->MakeScOutline();
1364 :
1365 224 : mxColRowBuff->ConvertHiddenFlags( mnScTab );
1366 254 : }
1367 :
1368 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|