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