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