1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: impop.cxx,v $
10 * $Revision: 1.95.36.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #include <svx/countryid.hxx>
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
41 #include <svx/editdata.hxx>
42 #include <svx/editeng.hxx>
43 #include <svx/editobj.hxx>
44 #include <svx/editstat.hxx>
45 #include <svx/flditem.hxx>
46 #include <svx/pageitem.hxx>
47 #include <svx/colritem.hxx>
48 #include <sfx2/printer.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <svtools/zforlist.hxx>
52 #include <sfx2/objsh.hxx>
56 #include "document.hxx"
57 #include "rangenam.hxx"
58 #include "compiler.hxx"
59 #include "patattr.hxx"
61 #include "globstr.hrc"
63 #include "markdata.hxx"
64 #include "olinetab.hxx"
65 #include "stlsheet.hxx"
66 #include "stlpool.hxx"
67 #include "compiler.hxx"
68 #include "viewopti.hxx"
69 #include "docoptio.hxx"
70 #include "scextopt.hxx"
71 #include "editutil.hxx"
72 #include "filtopt.hxx"
73 #include "scerrors.hxx"
74 #include "unonames.hxx"
75 #include "paramisc.hxx"
78 #include "fapihelper.hxx"
79 #include "xltools.hxx"
80 #include "xltable.hxx"
82 #include "xltracer.hxx"
83 #include "xihelper.hxx"
87 #include "xiescher.hxx"
88 #include "xicontent.hxx"
90 #include "excimp8.hxx"
91 #include "excform.hxx"
93 #if defined( WNT ) || defined( WIN )
99 using namespace ::com::sun::star
;
102 const double ImportExcel::fExcToTwips
=
103 ( double ) TWIPS_PER_CHAR
/ 256.0;
106 ImportTyp::ImportTyp( ScDocument
* pDoc
, CharSet eQ
)
113 ImportTyp::~ImportTyp()
118 FltError
ImportTyp::Read()
124 ImportExcel::ImportExcel( XclImpRootData
& rImpData
, SvStream
& rStrm
):
125 ImportTyp( &rImpData
.mrDoc
, rImpData
.meTextEnc
),
126 XclImpRoot( rImpData
),
127 maStrm( rStrm
, GetRoot() ),
132 nIxfeIndex
= 0; // zur Sicherheit auf 0
134 // Root-Daten fuellen - nach new's ohne Root als Parameter
135 pExcRoot
= &GetOldRoot();
136 pExcRoot
->pIR
= this; // ExcRoot -> XclImpRoot
137 pExcRoot
->eDateiTyp
= BiffX
;
138 pExcRoot
->pExtSheetBuff
= new ExtSheetBuffer( pExcRoot
); //&aExtSheetBuff;
139 pExcRoot
->pShrfmlaBuff
= new ShrfmlaBuffer( pExcRoot
); //&aShrfrmlaBuff;
140 pExcRoot
->pExtNameBuff
= new ExtNameBuff ( *this );
142 pExtNameBuff
= new NameBuffer( pExcRoot
); //#94039# prevent empty rootdata
143 pExtNameBuff
->SetBase( 1 );
145 pOutlineListBuffer
= new XclImpOutlineListBuffer( );
148 pFormConv
= pExcRoot
->pFmlaConverter
= new ExcelToSc( GetRoot() );
150 bTabTruncated
= FALSE
;
152 // Excel-Dokument per Default auf 31.12.1899, entspricht Excel-Einstellungen mit 1.1.1900
153 ScDocOptions aOpt
= pD
->GetDocOptions();
154 aOpt
.SetDate( 30, 12, 1899 );
155 pD
->SetDocOptions( aOpt
);
156 pD
->GetFormatTable()->ChangeNullDate( 30, 12, 1899 );
158 ScDocOptions
aDocOpt( pD
->GetDocOptions() );
159 aDocOpt
.SetIgnoreCase( TRUE
); // always in Excel
160 aDocOpt
.SetFormulaRegexEnabled( FALSE
); // regular expressions? what's that?
161 aDocOpt
.SetLookUpColRowNames( FALSE
); // default: no natural language refs
162 pD
->SetDocOptions( aDocOpt
);
166 ImportExcel::~ImportExcel( void )
168 GetDoc().SetSrcCharSet( GetTextEncoding() );
172 delete pOutlineListBuffer
;
178 void ImportExcel::ReadFileSharing()
180 sal_uInt16 nRecommendReadOnly
, nPasswordHash
;
181 maStrm
>> nRecommendReadOnly
>> nPasswordHash
;
183 if( (nRecommendReadOnly
!= 0) || (nPasswordHash
!= 0) )
184 if( SfxItemSet
* pItemSet
= GetMedium().GetItemSet() )
185 pItemSet
->Put( SfxBoolItem( SID_DOC_READONLY
, TRUE
) );
187 if( nPasswordHash
!= 0 )
189 if( SfxObjectShell
* pDocShell
= GetDocShell() )
191 ScfPropertySet
aPropSet( pDocShell
->GetModel() );
192 aPropSet
.SetProperty( CREATE_OUSTRING( "WriteProtectionPassword" ), static_cast< sal_Int32
>( nPasswordHash
) );
197 sal_uInt16
ImportExcel::ReadXFIndex( bool bBiff2
)
199 sal_uInt16 nXFIdx
= 0;
205 nXFIdx
= nXFIdx2
& 0x3F;
214 void ImportExcel::ReadDimensions()
216 XclRange
aXclUsedArea( ScAddress::UNINITIALIZED
);
217 if( (maStrm
.GetRecId() == EXC_ID2_DIMENSIONS
) || (GetBiff() <= EXC_BIFF5
) )
219 maStrm
>> aXclUsedArea
;
220 if( (aXclUsedArea
.GetColCount() > 1) && (aXclUsedArea
.GetRowCount() > 1) )
222 // Excel stores first unused row/column index
223 --aXclUsedArea
.maLast
.mnCol
;
224 --aXclUsedArea
.maLast
.mnRow
;
225 // create the Calc range
226 SCTAB nScTab
= GetCurrScTab();
227 ScRange
& rScUsedArea
= GetExtDocOptions().GetOrCreateTabSettings( nScTab
).maUsedArea
;
228 GetAddressConverter().ConvertRange( rScUsedArea
, aXclUsedArea
, nScTab
, nScTab
, false );
229 // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
234 sal_uInt32 nXclRow1
, nXclRow2
;
235 maStrm
>> nXclRow1
>> nXclRow2
>> aXclUsedArea
.maFirst
.mnCol
>> aXclUsedArea
.maLast
.mnCol
;
236 if( (nXclRow1
< nXclRow2
) && (aXclUsedArea
.GetColCount() > 1) &&
237 (nXclRow1
<= static_cast< sal_uInt32
>( GetScMaxPos().Row() )) )
239 // Excel stores first unused row/column index
241 --aXclUsedArea
.maLast
.mnCol
;
242 // convert row indexes to 16-bit values
243 aXclUsedArea
.maFirst
.mnRow
= static_cast< sal_uInt16
>( nXclRow1
);
244 aXclUsedArea
.maLast
.mnRow
= limit_cast
< sal_uInt16
>( nXclRow2
, aXclUsedArea
.maFirst
.mnRow
, SAL_MAX_UINT16
);
245 // create the Calc range
246 SCTAB nScTab
= GetCurrScTab();
247 ScRange
& rScUsedArea
= GetExtDocOptions().GetOrCreateTabSettings( nScTab
).maUsedArea
;
248 GetAddressConverter().ConvertRange( rScUsedArea
, aXclUsedArea
, nScTab
, nScTab
, false );
249 // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
254 void ImportExcel::ReadBlank()
259 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
260 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
262 sal_uInt16 nXFIdx
= ReadXFIndex( maStrm
.GetRecId() == EXC_ID2_BLANK
);
264 GetXFRangeBuffer().SetBlankXF( aScPos
, nXFIdx
);
268 void ImportExcel::ReadInteger()
273 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
274 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
276 sal_uInt16 nXFIdx
= ReadXFIndex( true );
280 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
281 GetDoc().PutCell( aScPos
, new ScValueCell( nValue
) );
285 void ImportExcel::ReadNumber()
290 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
291 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
293 sal_uInt16 nXFIdx
= ReadXFIndex( maStrm
.GetRecId() == EXC_ID2_NUMBER
);
297 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
298 GetDoc().PutCell( aScPos
, new ScValueCell( fValue
) );
302 void ImportExcel::ReadLabel()
307 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
308 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
310 /* Record ID BIFF XF type String type
311 0x0004 2-7 3 byte 8-bit length, byte string
312 0x0004 8 3 byte 16-bit length, unicode string
313 0x0204 2-7 2 byte 16-bit length, byte string
314 0x0204 8 2 byte 16-bit length, unicode string */
315 bool bBiff2
= maStrm
.GetRecId() == EXC_ID2_LABEL
;
316 sal_uInt16 nXFIdx
= ReadXFIndex( bBiff2
);
317 XclStrFlags nFlags
= (bBiff2
&& (GetBiff() <= EXC_BIFF5
)) ? EXC_STR_8BITLENGTH
: EXC_STR_DEFAULT
;
318 XclImpString aString
;
320 // #i63105# use text encoding from FONT record
321 rtl_TextEncoding eOldTextEnc
= GetTextEncoding();
322 if( const XclImpFont
* pFont
= GetXFBuffer().GetFont( nXFIdx
) )
323 SetTextEncoding( pFont
->GetFontEncoding() );
324 aString
.Read( maStrm
, nFlags
);
325 SetTextEncoding( eOldTextEnc
);
327 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
328 if( ScBaseCell
* pCell
= XclImpStringHelper::CreateCell( GetRoot(), aString
, nXFIdx
) )
329 GetDoc().PutCell( aScPos
, pCell
);
333 void ImportExcel::ReadBoolErr()
338 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
339 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
341 sal_uInt16 nXFIdx
= ReadXFIndex( maStrm
.GetRecId() == EXC_ID2_BOOLERR
);
342 sal_uInt8 nValue
, nType
;
343 maStrm
>> nValue
>> nType
;
345 if( nType
== EXC_BOOLERR_BOOL
)
346 GetXFRangeBuffer().SetBoolXF( aScPos
, nXFIdx
);
348 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
351 const ScTokenArray
* pScTokArr
= ErrorToFormula( nType
, nValue
, fValue
);
352 ScFormulaCell
* pCell
= new ScFormulaCell( pD
, aScPos
, pScTokArr
);
353 pCell
->SetHybridDouble( fValue
);
354 GetDoc().PutCell( aScPos
, pCell
);
358 void ImportExcel::ReadRk()
363 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
364 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
366 sal_uInt16 nXFIdx
= ReadXFIndex( false );
370 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
371 GetDoc().PutCell( aScPos
, new ScValueCell( XclTools::GetDoubleFromRK( nRk
) ) );
376 void ImportExcel::Window1()
378 GetDocViewSettings().ReadWindow1( maStrm
);
384 void ImportExcel::Row25( void )
386 UINT16 nRow
, nRowHeight
;
389 aIn
.Ignore( 4 ); // Mic und Mac ueberspringen
391 if( ValidRow( nRow
) )
393 aIn
>> nRowHeight
; // direkt in Twips angegeben
396 if( GetBiff() == EXC_BIFF2
)
397 {// -------------------- BIFF2
398 pColRowBuff
->SetHeight( nRow
, nRowHeight
);
401 {// -------------------- BIFF5
404 aIn
.Ignore( 2 ); // reserved
407 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nGrbit
, 0, 3 );
408 pRowOutlineBuff
->SetLevel( nRow
, nLevel
,
409 ::get_flag( nGrbit
, EXC_ROW_COLLAPSED
), ::get_flag( nGrbit
, EXC_ROW_HIDDEN
) );
411 pColRowBuff
->SetRowSettings( nRow
, nRowHeight
, nGrbit
);
417 void ImportExcel::Bof2( void )
420 maStrm
.DisableDecryption();
424 if( nSubType
== 0x0020 ) // Chart
425 pExcRoot
->eDateiTyp
= Biff2C
;
426 else if( nSubType
== 0x0040 ) // Macro
427 pExcRoot
->eDateiTyp
= Biff2M
;
428 else // #i51490# Excel interprets invalid indexes as worksheet
429 pExcRoot
->eDateiTyp
= Biff2
;
433 void ImportExcel::Eof( void )
435 // POST: darf nur nach einer GUELTIGEN Tabelle gerufen werden!
441 void ImportExcel::SheetPassword( void )
443 if (GetRoot().GetBiff() != EXC_BIFF8
)
446 GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn
, GetCurrScTab() );
450 void ImportExcel::Externsheet( void )
452 String aUrl
, aTabName
;
454 String
aEncodedUrl( aIn
.ReadByteString( false ) );
455 XclImpUrlHelper::DecodeUrl( aUrl
, aTabName
, bSameWorkBook
, *pExcRoot
->pIR
, aEncodedUrl
);
456 mnLastRefIdx
= pExcRoot
->pExtSheetBuff
->Add( aUrl
, aTabName
, bSameWorkBook
);
460 void ImportExcel:: WinProtection( void )
462 if (GetRoot().GetBiff() != EXC_BIFF8
)
465 GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn
);
469 void ImportExcel::Columndefault( void )
470 {// Default Cell Attributes
471 UINT16 nColMic
, nColMac
;
474 aIn
>> nColMic
>> nColMac
;
476 DBG_ASSERT( aIn
.GetRecLeft() == (sal_Size
)(nColMac
- nColMic
) * 3 + 2,
477 "ImportExcel::Columndefault - wrong record size" );
481 if( nColMac
> MAXCOL
)
482 nColMac
= static_cast<UINT16
>(MAXCOL
);
484 for( UINT16 nCol
= nColMic
; nCol
<= nColMac
; nCol
++ )
487 aIn
.Ignore( 2 ); // nur 0. Attribut-Byte benutzt
489 if( nOpt0
& 0x80 ) // Col hidden?
490 pColRowBuff
->HideCol( nCol
);
495 void ImportExcel::Array25( void )
497 UINT16 nFirstRow
, nLastRow
, nFormLen
;
498 BYTE nFirstCol
, nLastCol
;
500 aIn
>> nFirstRow
>> nLastRow
>> nFirstCol
>> nLastCol
;
502 if( GetBiff() == EXC_BIFF2
)
505 nFormLen
= aIn
.ReaduInt8();
513 if( ValidColRow( nLastCol
, nLastRow
) )
515 // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
516 const ScTokenArray
* pErgebnis
;
518 pFormConv
->Reset( ScAddress( static_cast<SCCOL
>(nFirstCol
),
519 static_cast<SCROW
>(nFirstRow
), GetCurrScTab() ) );
520 ExcelConverterBase::ConvertParam aParam
;
521 aParam
.mbAllowArrays
= true;
522 pFormConv
->Convert( pErgebnis
, maStrm
, nFormLen
, aParam
, FT_CellFormula
);
524 DBG_ASSERT( pErgebnis
, "*ImportExcel::Array25(): ScTokenArray ist NULL!" );
526 ScMarkData aMarkData
;
527 aMarkData
.SelectOneTable( GetCurrScTab() );
528 pD
->InsertMatrixFormula( static_cast<SCCOL
>(nFirstCol
),
529 static_cast<SCROW
>(nFirstRow
), static_cast<SCCOL
>(nLastCol
),
530 static_cast<SCROW
>(nLastRow
), aMarkData
, EMPTY_STRING
,
536 void ImportExcel::Rec1904( void )
544 ScDocOptions aOpt
= pD
->GetDocOptions();
545 aOpt
.SetDate( 1, 1, 1904 );
546 pD
->SetDocOptions( aOpt
);
547 pD
->GetFormatTable()->ChangeNullDate( 1, 1, 1904 );
552 void ImportExcel::Externname25( void )
559 String
aName( aIn
.ReadByteString( FALSE
) );
561 if( ( nOpt
& 0x0001 ) || ( ( nOpt
& 0xFFFE ) == 0x0000 ) )
563 ScfTools::ConvertToScDefinedName( aName
);
564 pExcRoot
->pExtNameBuff
->AddName( aName
, mnLastRefIdx
);
566 else if( nOpt
& 0x0010 )
568 pExcRoot
->pExtNameBuff
->AddOLE( aName
, mnLastRefIdx
, nRes
); // nRes is storage ID
572 pExcRoot
->pExtNameBuff
->AddDDE( aName
, mnLastRefIdx
);
577 void ImportExcel::Colwidth( void )
579 BYTE nColFirst
, nColLast
;
582 aIn
>> nColFirst
>> nColLast
>> nColWidth
;
584 //! TODO: add a check for the unlikely case of changed MAXCOL (-> XclImpAddressConverter)
585 // if( nColLast > MAXCOL )
586 // nColLast = static_cast<UINT16>(MAXCOL);
588 USHORT nScWidth
= XclTools::GetScColumnWidth( nColWidth
, GetCharWidth() );
589 pColRowBuff
->SetWidthRange( nColFirst
, nColLast
, nScWidth
);
593 void ImportExcel::Defrowheight2( void )
595 sal_uInt16 nDefHeight
;
596 maStrm
>> nDefHeight
;
597 nDefHeight
&= 0x7FFF;
598 pColRowBuff
->SetDefHeight( nDefHeight
, EXC_DEFROW_UNSYNCED
);
602 void ImportExcel::SheetProtect( void )
604 if (GetRoot().GetBiff() != EXC_BIFF8
)
607 GetRoot().GetSheetProtectBuffer().ReadProtect( aIn
, GetCurrScTab() );
610 void ImportExcel::DocProtect( void )
612 if (GetRoot().GetBiff() != EXC_BIFF8
)
615 GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn
);
618 void ImportExcel::DocPasssword( void )
620 if (GetRoot().GetBiff() != EXC_BIFF8
)
623 GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn
);
626 void ImportExcel::Codepage( void )
628 SetCodePage( maStrm
.ReaduInt16() );
632 void ImportExcel::Ixfe( void )
638 void ImportExcel::DefColWidth( void )
640 // stored as entire characters -> convert to 1/256 of characters (as in COLINFO)
641 double fDefWidth
= 256.0 * maStrm
.ReaduInt16();
643 // #i3006# additional space for default width - Excel adds space depending on font size
644 long nFontHt
= GetFontBuffer().GetAppFontData().mnHeight
;
645 fDefWidth
+= XclTools::GetXclDefColWidthCorrection( nFontHt
);
647 USHORT nScWidth
= XclTools::GetScColumnWidth( limit_cast
< sal_uInt16
>( fDefWidth
), GetCharWidth() );
648 pColRowBuff
->SetDefWidth( nScWidth
);
652 void ImportExcel::Builtinfmtcnt( void )
657 void ImportExcel::Colinfo( void )
658 {// Column Formatting Information
659 UINT16 nColFirst
, nColLast
, nColWidth
, nXF
;
662 aIn
>> nColFirst
>> nColLast
>> nColWidth
>> nXF
>> nOpt
;
664 if( nColFirst
> MAXCOL
)
667 if( nColLast
> MAXCOL
)
668 nColLast
= static_cast<UINT16
>(MAXCOL
);
670 bool bHidden
= ::get_flag( nOpt
, EXC_COLINFO_HIDDEN
);
671 bool bCollapsed
= ::get_flag( nOpt
, EXC_COLINFO_COLLAPSED
);
672 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nOpt
, 8, 3 );
673 pColOutlineBuff
->SetLevelRange( nColFirst
, nColLast
, nLevel
, bCollapsed
, bHidden
);
676 pColRowBuff
->HideColRange( nColFirst
, nColLast
);
678 USHORT nScWidth
= XclTools::GetScColumnWidth( nColWidth
, GetCharWidth() );
679 pColRowBuff
->SetWidthRange( nColFirst
, nColLast
, nScWidth
);
680 pColRowBuff
->SetDefaultXF( nColFirst
, nColLast
, nXF
);
684 void ImportExcel::Wsbool( void )
689 pRowOutlineBuff
->SetButtonMode( ::get_flag( nFlags
, EXC_WSBOOL_ROWBELOW
) );
690 pColOutlineBuff
->SetButtonMode( ::get_flag( nFlags
, EXC_WSBOOL_COLBELOW
) );
692 GetPageSettings().SetFitToPages( ::get_flag( nFlags
, EXC_WSBOOL_FITTOPAGE
) );
696 void ImportExcel::Boundsheet( void )
700 if( GetBiff() == EXC_BIFF5
)
702 aIn
.DisableDecryption();
703 maSheetOffsets
.push_back( aIn
.ReaduInt32() );
704 aIn
.EnableDecryption();
708 String
aName( aIn
.ReadByteString( FALSE
) );
710 SCTAB nScTab
= static_cast< SCTAB
>( nBdshtTab
);
713 DBG_ASSERT( !pD
->HasTable( nScTab
), "ImportExcel::Boundsheet - sheet exists already" );
714 pD
->MakeTable( nScTab
);
717 if( ( nGrbit
& 0x0001 ) || ( nGrbit
& 0x0002 ) )
718 pD
->SetVisible( nScTab
, FALSE
);
720 if( !pD
->RenameTab( nScTab
, aName
) )
722 pD
->CreateValidTabName( aName
);
723 pD
->RenameTab( nScTab
, aName
);
730 void ImportExcel::Country( void )
732 sal_uInt16 nUICountry
, nDocCountry
;
733 maStrm
>> nUICountry
>> nDocCountry
;
735 // Store system language in XclRoot
736 LanguageType eLanguage
= ::svx::ConvertCountryToLanguage( static_cast< ::svx::CountryId
>( nDocCountry
) );
737 if( eLanguage
!= LANGUAGE_DONTKNOW
)
738 SetDocLanguage( eLanguage
);
740 // Set Excel UI language in add-in name translator
741 eLanguage
= ::svx::ConvertCountryToLanguage( static_cast< ::svx::CountryId
>( nUICountry
) );
742 if( eLanguage
!= LANGUAGE_DONTKNOW
)
743 SetUILanguage( eLanguage
);
747 void ImportExcel::ReadUsesElfs()
749 if( maStrm
.ReaduInt16() != 0 )
751 ScDocOptions aDocOpt
= GetDoc().GetDocOptions();
752 aDocOpt
.SetLookUpColRowNames( TRUE
);
753 GetDoc().SetDocOptions( aDocOpt
);
758 void ImportExcel::Hideobj( void )
761 ScVObjMode eOle
, eChart
, eDraw
;
765 ScViewOptions
aOpts( pD
->GetViewOptions() );
769 case 1: // Placeholders
770 eOle
= VOBJ_MODE_SHOW
; // in Excel 97 werden nur Charts als Platzhalter angezeigt
771 eChart
= VOBJ_MODE_SHOW
; //#i80528# VOBJ_MODE_DUMMY replaced by VOBJ_MODE_SHOW now
772 eDraw
= VOBJ_MODE_SHOW
;
775 eOle
= VOBJ_MODE_HIDE
;
776 eChart
= VOBJ_MODE_HIDE
;
777 eDraw
= VOBJ_MODE_HIDE
;
780 eOle
= VOBJ_MODE_SHOW
;
781 eChart
= VOBJ_MODE_SHOW
;
782 eDraw
= VOBJ_MODE_SHOW
;
786 aOpts
.SetObjMode( VOBJ_TYPE_OLE
, eOle
);
787 aOpts
.SetObjMode( VOBJ_TYPE_CHART
, eChart
);
788 aOpts
.SetObjMode( VOBJ_TYPE_DRAW
, eDraw
);
790 pD
->SetViewOptions( aOpts
);
794 void ImportExcel::Bundleheader( void )
799 void ImportExcel::Standardwidth( void )
801 USHORT nScWidth
= XclTools::GetScColumnWidth( maStrm
.ReaduInt16(), GetCharWidth() );
802 pColRowBuff
->SetDefWidth( nScWidth
, TRUE
);
806 void ImportExcel::Shrfmla( void )
808 UINT16 nFirstRow
, nLastRow
, nLenExpr
;
809 BYTE nFirstCol
, nLastCol
;
811 aIn
>> nFirstRow
>> nLastRow
>> nFirstCol
>> nLastCol
;
815 // jetzt steht Lesemarke an der Formel
817 const ScTokenArray
* pErgebnis
;
820 ExcelConverterBase::ConvertParam aParam
;
821 aParam
.mbAllowArrays
= true;
822 pFormConv
->Convert( pErgebnis
, maStrm
, nLenExpr
, aParam
, FT_SharedFormula
);
825 DBG_ASSERT( pErgebnis
, "+ImportExcel::Shrfmla(): ScTokenArray ist NULL!" );
827 pExcRoot
->pShrfmlaBuff
->Store( ScRange( static_cast<SCCOL
>(nFirstCol
),
828 static_cast<SCROW
>(nFirstRow
), GetCurrScTab(),
829 static_cast<SCCOL
>(nLastCol
), static_cast<SCROW
>(nLastRow
),
830 GetCurrScTab()), *pErgebnis
);
834 void ImportExcel::Mulrk( void )
842 for( XclAddress
aCurrXclPos( aXclPos
); (aXclPos
.mnCol
<= aCurrXclPos
.mnCol
) && (aIn
.GetRecLeft() > 2); ++aCurrXclPos
.mnCol
)
844 aIn
>> nXF
>> nRkNum
;
846 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
847 if( GetAddressConverter().ConvertAddress( aScPos
, aCurrXclPos
, GetCurrScTab(), true ) )
849 GetXFRangeBuffer().SetXF( aScPos
, nXF
);
850 GetDoc().PutCell( aScPos
, new ScValueCell( XclTools::GetDoubleFromRK( nRkNum
) ) );
856 void ImportExcel::Mulblank( void )
863 for( XclAddress
aCurrXclPos( aXclPos
); (aXclPos
.mnCol
<= aCurrXclPos
.mnCol
) && (aIn
.GetRecLeft() > 2); ++aCurrXclPos
.mnCol
)
867 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
868 if( GetAddressConverter().ConvertAddress( aScPos
, aCurrXclPos
, GetCurrScTab(), true ) )
869 GetXFRangeBuffer().SetBlankXF( aScPos
, nXF
);
874 void ImportExcel::Rstring( void )
878 aIn
>> aXclPos
>> nXFIdx
;
880 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
881 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
883 // unformatted Unicode string with separate formatting information
884 XclImpString aString
;
886 // #i63105# use text encoding from FONT record
887 rtl_TextEncoding eOldTextEnc
= GetTextEncoding();
888 if( const XclImpFont
* pFont
= GetXFBuffer().GetFont( nXFIdx
) )
889 SetTextEncoding( pFont
->GetFontEncoding() );
890 aString
.Read( maStrm
);
891 SetTextEncoding( eOldTextEnc
);
893 // character formatting runs
894 if( !aString
.IsRich() )
895 aString
.ReadFormats( maStrm
);
897 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
898 if( ScBaseCell
* pCell
= XclImpStringHelper::CreateCell( *this, aString
, nXFIdx
) )
899 GetDoc().PutCell( aScPos
, pCell
);
904 void ImportExcel::Cellmerging()
906 XclImpAddressConverter
& rAddrConv
= GetAddressConverter();
907 SCTAB nScTab
= GetCurrScTab();
911 for( sal_uInt16 nIdx
= 0; (nIdx
< nCount
) && (maStrm
.GetRecLeft() >= 8); ++nIdx
)
914 maStrm
>> aXclRange
; // 16-bit rows and columns
915 ScRange
aScRange( ScAddress::UNINITIALIZED
);
916 if( rAddrConv
.ConvertRange( aScRange
, aXclRange
, nScTab
, nScTab
, true ) )
917 GetXFRangeBuffer().SetMerge( aScRange
.aStart
.Col(), aScRange
.aStart
.Row(), aScRange
.aEnd
.Col(), aScRange
.aEnd
.Row() );
922 void ImportExcel::Olesize( void )
924 XclRange
aXclOleSize( ScAddress::UNINITIALIZED
);
926 aXclOleSize
.Read( maStrm
, false );
928 SCTAB nScTab
= GetCurrScTab();
929 ScRange
& rOleSize
= GetExtDocOptions().GetDocSettings().maOleSize
;
930 GetAddressConverter().ConvertRange( rOleSize
, aXclOleSize
, nScTab
, nScTab
, false );
934 void ImportExcel::Row34( void )
936 UINT16 nRow
, nRowHeight
, nGrbit
, nXF
;
939 aIn
.Ignore( 4 ); // Mic und Mac ueberspringen
941 SCROW nScRow
= static_cast< SCROW
>( nRow
);
943 if( ValidRow( nScRow
) )
945 aIn
>> nRowHeight
; // direkt in Twips angegeben
948 aIn
>> nGrbit
>> nXF
;
950 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nGrbit
, 0, 3 );
951 pRowOutlineBuff
->SetLevel( nScRow
, nLevel
,
952 ::get_flag( nGrbit
, EXC_ROW_COLLAPSED
), ::get_flag( nGrbit
, EXC_ROW_HIDDEN
) );
954 pColRowBuff
->SetRowSettings( nScRow
, nRowHeight
, nGrbit
);
956 if( nGrbit
& EXC_ROW_USEDEFXF
)
957 GetXFRangeBuffer().SetRowDefXF( nScRow
, nXF
& EXC_ROW_XFMASK
);
962 void ImportExcel::Bof3( void )
965 maStrm
.DisableDecryption();
969 DBG_ASSERT( nSubType
!= 0x0100, "*ImportExcel::Bof3(): Biff3 als Workbook?!" );
970 if( nSubType
== 0x0100 ) // Book
971 pExcRoot
->eDateiTyp
= Biff3W
;
972 else if( nSubType
== 0x0020 ) // Chart
973 pExcRoot
->eDateiTyp
= Biff3C
;
974 else if( nSubType
== 0x0040 ) // Macro
975 pExcRoot
->eDateiTyp
= Biff3M
;
976 else // #i51490# Excel interprets invalid indexes as worksheet
977 pExcRoot
->eDateiTyp
= Biff3
;
981 void ImportExcel::Array34( void )
983 UINT16 nFirstRow
, nLastRow
, nFormLen
;
984 BYTE nFirstCol
, nLastCol
;
986 aIn
>> nFirstRow
>> nLastRow
>> nFirstCol
>> nLastCol
;
987 aIn
.Ignore( (GetBiff() >= EXC_BIFF5
) ? 6 : 2 );
990 if( ValidColRow( nLastCol
, nLastRow
) )
992 // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
993 const ScTokenArray
* pErgebnis
;
994 ExcelConverterBase::ConvertParam aParam
;
995 aParam
.mbAllowArrays
= true;
996 aParam
.mnArrayColSize
= nLastCol
- nFirstCol
+ 1;
997 aParam
.mnArrayRowSize
= nLastRow
- nFirstRow
+ 1;
999 pFormConv
->Reset( ScAddress( static_cast<SCCOL
>(nFirstCol
),
1000 static_cast<SCROW
>(nFirstRow
), GetCurrScTab() ) );
1001 pFormConv
->Convert( pErgebnis
, maStrm
, nFormLen
, aParam
, FT_CellFormula
);
1003 DBG_ASSERT( pErgebnis
, "+ImportExcel::Array34(): ScTokenArray ist NULL!" );
1005 ScMarkData aMarkData
;
1006 aMarkData
.SelectOneTable( GetCurrScTab() );
1007 pD
->InsertMatrixFormula( static_cast<SCCOL
>(nFirstCol
),
1008 static_cast<SCROW
>(nFirstRow
), static_cast<SCCOL
>(nLastCol
),
1009 static_cast<SCROW
>(nLastRow
), aMarkData
, EMPTY_STRING
,
1015 void ImportExcel::Externname34( void )
1020 void ImportExcel::Defrowheight345( void )
1022 sal_uInt16 nFlags
, nDefHeight
;
1023 maStrm
>> nFlags
>> nDefHeight
;
1024 pColRowBuff
->SetDefHeight( nDefHeight
, nFlags
);
1028 void ImportExcel::TableOp( void )
1030 UINT16 nFirstRow
, nLastRow
;
1031 UINT8 nFirstCol
, nLastCol
;
1033 UINT16 nInpRow
, nInpCol
, nInpRow2
, nInpCol2
;
1035 aIn
>> nFirstRow
>> nLastRow
>> nFirstCol
>> nLastCol
>> nGrbit
1036 >> nInpRow
>> nInpCol
>> nInpRow2
>> nInpCol2
;
1038 if( ValidColRow( nLastCol
, nLastRow
) )
1040 if( nFirstCol
&& nFirstRow
)
1042 ScTabOpParam aTabOpParam
;
1043 aTabOpParam
.nMode
= (nGrbit
& EXC_TABLEOP_BOTH
) ? 2 : ((nGrbit
& EXC_TABLEOP_ROW
) ? 1 : 0 );
1044 USHORT nCol
= nFirstCol
- 1;
1045 USHORT nRow
= nFirstRow
- 1;
1046 SCTAB nTab
= GetCurrScTab();
1047 switch( aTabOpParam
.nMode
)
1050 aTabOpParam
.aRefFormulaCell
.Set(
1051 static_cast<SCCOL
>(nFirstCol
),
1052 static_cast<SCROW
>(nFirstRow
- 1), nTab
, FALSE
,
1054 aTabOpParam
.aRefFormulaEnd
.Set(
1055 static_cast<SCCOL
>(nLastCol
),
1056 static_cast<SCROW
>(nFirstRow
- 1), nTab
, FALSE
,
1058 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol
),
1059 static_cast<SCROW
>(nInpRow
), nTab
, FALSE
, FALSE
,
1064 aTabOpParam
.aRefFormulaCell
.Set(
1065 static_cast<SCCOL
>(nFirstCol
- 1),
1066 static_cast<SCROW
>(nFirstRow
), nTab
, FALSE
, FALSE
,
1068 aTabOpParam
.aRefFormulaEnd
.Set(
1069 static_cast<SCCOL
>(nFirstCol
- 1),
1070 static_cast<SCROW
>(nLastRow
), nTab
, FALSE
, FALSE
,
1072 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1073 static_cast<SCROW
>(nInpRow
), nTab
, FALSE
, FALSE
,
1077 case 2: // TWO-INPUT
1078 aTabOpParam
.aRefFormulaCell
.Set(
1079 static_cast<SCCOL
>(nFirstCol
- 1),
1080 static_cast<SCROW
>(nFirstRow
- 1), nTab
, FALSE
,
1082 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1083 static_cast<SCROW
>(nInpRow
), nTab
, FALSE
, FALSE
,
1085 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol2
),
1086 static_cast<SCROW
>(nInpRow2
), nTab
, FALSE
, FALSE
,
1091 ScMarkData aMarkData
;
1092 aMarkData
.SelectOneTable( nTab
);
1093 pD
->InsertTableOp( aTabOpParam
, static_cast<SCCOL
>(nCol
),
1094 static_cast<SCROW
>(nRow
), static_cast<SCCOL
>(nLastCol
),
1095 static_cast<SCROW
>(nLastRow
), aMarkData
);
1100 bTabTruncated
= TRUE
;
1101 GetTracer().TraceInvalidRow(GetCurrScTab(), nLastRow
, MAXROW
);
1106 void ImportExcel::Bof4( void )
1108 sal_uInt16 nSubType
;
1109 maStrm
.DisableDecryption();
1113 if( nSubType
== 0x0100 ) // Book
1114 pExcRoot
->eDateiTyp
= Biff4W
;
1115 else if( nSubType
== 0x0020 ) // Chart
1116 pExcRoot
->eDateiTyp
= Biff4C
;
1117 else if( nSubType
== 0x0040 ) // Macro
1118 pExcRoot
->eDateiTyp
= Biff4M
;
1119 else // #i51490# Excel interprets invalid indexes as worksheet
1120 pExcRoot
->eDateiTyp
= Biff4
;
1124 void ImportExcel::Bof5( void )
1126 //POST: eDateiTyp = Typ der zu lesenden Datei
1127 UINT16 nSubType
, nVers
;
1130 maStrm
.DisableDecryption();
1131 maStrm
>> nVers
>> nSubType
;
1135 case 0x0005: eDatei
= Biff5W
; break; // workbook globals
1136 case 0x0006: eDatei
= Biff5V
; break; // VB module
1137 case 0x0010: eDatei
= Biff5
; break; // worksheet
1138 case 0x0020: eDatei
= Biff5C
; break; // chart
1139 case 0x0040: eDatei
= Biff5M4
; break; // macro sheet
1141 pExcRoot
->eDateiTyp
= BiffX
;
1145 if( nVers
== 0x0600 && (GetBiff() == EXC_BIFF8
) )
1146 eDatei
= ( BiffTyp
) ( eDatei
- Biff5
+ Biff8
);
1148 pExcRoot
->eDateiTyp
= eDatei
;
1151 void ImportExcel::EndSheet( void )
1153 pExcRoot
->pExtSheetBuff
->Reset();
1155 if( GetBiff() <= EXC_BIFF5
)
1157 pExcRoot
->pExtNameBuff
->Reset();
1165 void ImportExcel::NeueTabelle( void )
1167 SCTAB nTab
= GetCurrScTab();
1168 if( nTab
> 0 && !pD
->HasTable( nTab
) )
1169 pD
->MakeTable( nTab
);
1171 pExcRoot
->pShrfmlaBuff
->Clear();
1173 InitializeTable( nTab
);
1175 pOutlineListBuffer
->Append( new XclImpOutlineDataBuffer( GetRoot(), nTab
) );
1177 pExcRoot
->pColRowBuff
= pColRowBuff
= pOutlineListBuffer
->Last()->GetColRowBuff();
1178 pColOutlineBuff
= pOutlineListBuffer
->Last()->GetColOutline();
1179 pRowOutlineBuff
= pOutlineListBuffer
->Last()->GetRowOutline();
1183 const ScTokenArray
* ImportExcel::ErrorToFormula( BYTE bErrOrVal
, BYTE nError
, double& rVal
)
1185 return pFormConv
->GetBoolErr( XclTools::ErrorToEnum( rVal
, bErrOrVal
, nError
) );
1189 void ImportExcel::AdjustRowHeight()
1191 /* #93255# Speed up chart import: import all sheets without charts, then
1192 update row heights (here), last load all charts -> do not any longer
1193 update inside of ScDocShell::ConvertFrom() (causes update of existing
1194 charts during each and every change of row height). */
1195 if( ScModelObj
* pDocObj
= GetDocModelObj() )
1196 pDocObj
->UpdateAllRowHeights();
1200 void ImportExcel::PostDocLoad( void )
1202 /* Set automatic page numbering in Default page style (default is "page number = 1").
1203 Otherwise hidden tables (i.e. for scenarios) which have Default page style will
1204 break automatic page numbering. */
1205 if( SfxStyleSheetBase
* pStyleSheet
= GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD
), SFX_STYLE_FAMILY_PAGE
) )
1206 pStyleSheet
->GetItemSet().Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO
, 0 ) );
1208 // outlines for all sheets, sets hidden rows and columns (#i11776# after filtered ranges)
1209 for( XclImpOutlineDataBuffer
* pBuffer
= pOutlineListBuffer
->First(); pBuffer
; pBuffer
= pOutlineListBuffer
->Next() )
1212 // document view settings (before visible OLE area)
1213 GetDocViewSettings().Finalize();
1215 // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area)
1216 GetObjectManager().ConvertObjects();
1218 // visible area if embedded OLE
1219 if( ScModelObj
* pDocObj
= GetDocModelObj() )
1221 if( SfxObjectShell
* pEmbObj
= pDocObj
->GetEmbeddedObject() )
1223 // visible area if embedded
1224 const ScExtDocSettings
& rDocSett
= GetExtDocOptions().GetDocSettings();
1225 SCTAB nDisplScTab
= rDocSett
.mnDisplTab
;
1227 // first try if there was an OLESIZE record
1228 ScRange aScOleSize
= rDocSett
.maOleSize
;
1230 /* #i44077# If a new OLE object is inserted from file, there
1231 is no OLESIZE record in the Excel file. Calculate used area
1232 from file contents (used cells and drawing objects). */
1233 if( !aScOleSize
.IsValid() )
1235 // used area of displayed sheet (cell contents)
1236 if( const ScExtTabSettings
* pTabSett
= GetExtDocOptions().GetTabSettings( nDisplScTab
) )
1237 aScOleSize
= pTabSett
->maUsedArea
;
1238 // add all valid drawing objects
1239 ScRange aScObjArea
= GetObjectManager().GetUsedArea( nDisplScTab
);
1240 if( aScObjArea
.IsValid() )
1241 aScOleSize
.ExtendTo( aScObjArea
);
1244 // valid size found - set it at the document
1245 if( aScOleSize
.IsValid() )
1247 pEmbObj
->SetVisArea( GetDoc().GetMMRect(
1248 aScOleSize
.aStart
.Col(), aScOleSize
.aStart
.Row(),
1249 aScOleSize
.aEnd
.Col(), aScOleSize
.aEnd
.Row(), nDisplScTab
) );
1250 GetDoc().SetVisibleTab( nDisplScTab
);
1254 // #111099# open forms in alive mode (has no effect, if no controls in document)
1255 pDocObj
->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES
), ::comphelper::makeBoolAny( sal_False
) );
1258 // enables extended options to be set to the view after import
1259 GetExtDocOptions().SetChanged( true );
1261 // root data owns the extended document options -> create a new object
1262 GetDoc().SetExtDocOptions( new ScExtDocOptions( GetExtDocOptions() ) );
1264 const SCTAB nLast
= pD
->GetTableCount();
1267 if( pExcRoot
->pPrintRanges
->HasRanges() )
1269 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1271 p
= pExcRoot
->pPrintRanges
->First( static_cast<UINT16
>(n
) );
1274 DBG_ASSERT( pExcRoot
->pPrintRanges
->GetActList(),
1275 "-ImportExcel::PostDocLoad(): Imaginaere Tabelle gefunden!" );
1277 pD
->ClearPrintRanges( n
);
1280 pD
->AddPrintRange( n
, *p
);
1281 p
= pExcRoot
->pPrintRanges
->Next();
1286 // #i4063# no print ranges -> print entire sheet
1287 pD
->SetPrintEntireSheet( n
);
1290 GetTracer().TracePrintRange();
1293 if( pExcRoot
->pPrintTitles
->HasRanges() )
1295 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1297 p
= pExcRoot
->pPrintTitles
->First( static_cast<UINT16
>(n
) );
1300 DBG_ASSERT( pExcRoot
->pPrintTitles
->GetActList(),
1301 "-ImportExcel::PostDocLoad(): Imaginaere Tabelle gefunden!" );
1303 BOOL bRowVirgin
= TRUE
;
1304 BOOL bColVirgin
= TRUE
;
1308 if( p
->aStart
.Col() == 0 && p
->aEnd
.Col() == MAXCOL
&& bRowVirgin
)
1310 pD
->SetRepeatRowRange( n
, p
);
1314 if( p
->aStart
.Row() == 0 && p
->aEnd
.Row() == MAXROW
&& bColVirgin
)
1316 pD
->SetRepeatColRange( n
, p
);
1320 p
= pExcRoot
->pPrintTitles
->Next();
1327 XclImpOutlineDataBuffer::XclImpOutlineDataBuffer( const XclImpRoot
& rRoot
, SCTAB nScTab
) :
1328 XclImpRoot( rRoot
),
1329 mxColOutlineBuff( new XclImpOutlineBuffer( MAXCOLCOUNT
) ),
1330 mxRowOutlineBuff( new XclImpOutlineBuffer( MAXROWCOUNT
) ),
1331 mxColRowBuff( new XclImpColRowSettings( rRoot
) ),
1336 XclImpOutlineDataBuffer::~XclImpOutlineDataBuffer()
1340 void XclImpOutlineDataBuffer::Convert()
1342 mxColOutlineBuff
->SetOutlineArray( GetDoc().GetOutlineTable( mnScTab
, TRUE
)->GetColArray() );
1343 mxColOutlineBuff
->MakeScOutline();
1345 mxRowOutlineBuff
->SetOutlineArray( GetDoc().GetOutlineTable( mnScTab
, TRUE
)->GetRowArray() );
1346 mxRowOutlineBuff
->MakeScOutline();
1348 mxColRowBuff
->ConvertHiddenFlags( mnScTab
);