diff options
Diffstat (limited to 'sc/source/filter/excel/xipage.cxx')
-rw-r--r-- | sc/source/filter/excel/xipage.cxx | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/sc/source/filter/excel/xipage.cxx b/sc/source/filter/excel/xipage.cxx new file mode 100644 index 000000000000..38cebc2e6ca8 --- /dev/null +++ b/sc/source/filter/excel/xipage.cxx @@ -0,0 +1,390 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include "xipage.hxx" +#include <svl/itemset.hxx> +#include <vcl/graph.hxx> +#include "scitems.hxx" +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <svx/pageitem.hxx> +#include <editeng/sizeitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/brshitem.hxx> +#include "document.hxx" +#include "stlsheet.hxx" +#include "attrib.hxx" +#include "xistream.hxx" +#include "xihelper.hxx" +#include "xiescher.hxx" + +// Page settings ============================================================== + +XclImpPageSettings::XclImpPageSettings( const XclImpRoot& rRoot ) : + XclImpRoot( rRoot ) +{ + Initialize(); +} + +void XclImpPageSettings::Initialize() +{ + maData.SetDefaults(); + mbValidPaper = false; +} + +void XclImpPageSettings::ReadSetup( XclImpStream& rStrm ) +{ + DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF4 ); + if( GetBiff() < EXC_BIFF4 ) + return; + + // BIFF4 - BIFF8 + sal_uInt16 nFlags; + rStrm >> maData.mnPaperSize >> maData.mnScaling >> maData.mnStartPage + >> maData.mnFitToWidth >> maData.mnFitToHeight >> nFlags; + + mbValidPaper = maData.mbValid = !::get_flag( nFlags, EXC_SETUP_INVALID ); + maData.mbPrintInRows = ::get_flag( nFlags, EXC_SETUP_INROWS ); + maData.mbPortrait = ::get_flag( nFlags, EXC_SETUP_PORTRAIT ); + maData.mbBlackWhite = ::get_flag( nFlags, EXC_SETUP_BLACKWHITE ); + maData.mbManualStart = true; + + // new in BIFF5 - BIFF8 + if( GetBiff() >= EXC_BIFF5 ) + { + rStrm >> maData.mnHorPrintRes >> maData.mnVerPrintRes + >> maData.mfHeaderMargin >> maData.mfFooterMargin >> maData.mnCopies; + + maData.mbDraftQuality = ::get_flag( nFlags, EXC_SETUP_DRAFT ); + maData.mbPrintNotes = ::get_flag( nFlags, EXC_SETUP_PRINTNOTES ); + maData.mbManualStart = ::get_flag( nFlags, EXC_SETUP_STARTPAGE ); + } +} + +void XclImpPageSettings::ReadMargin( XclImpStream& rStrm ) +{ + switch( rStrm.GetRecId() ) + { + case EXC_ID_LEFTMARGIN: rStrm >> maData.mfLeftMargin; break; + case EXC_ID_RIGHTMARGIN: rStrm >> maData.mfRightMargin; break; + case EXC_ID_TOPMARGIN: rStrm >> maData.mfTopMargin; break; + case EXC_ID_BOTTOMMARGIN: rStrm >> maData.mfBottomMargin; break; + default: DBG_ERRORFILE( "XclImpPageSettings::ReadMargin - unknown record" ); + } +} + +void XclImpPageSettings::ReadCenter( XclImpStream& rStrm ) +{ + DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF3 ); // read it anyway + bool bCenter = (rStrm.ReaduInt16() != 0); + switch( rStrm.GetRecId() ) + { + case EXC_ID_HCENTER: maData.mbHorCenter = bCenter; break; + case EXC_ID_VCENTER: maData.mbVerCenter = bCenter; break; + default: DBG_ERRORFILE( "XclImpPageSettings::ReadCenter - unknown record" ); + } +} + +void XclImpPageSettings::ReadHeaderFooter( XclImpStream& rStrm ) +{ + String aString; + if( rStrm.GetRecLeft() ) + aString = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString(); + + switch( rStrm.GetRecId() ) + { + case EXC_ID_HEADER: maData.maHeader = aString; break; + case EXC_ID_FOOTER: maData.maFooter = aString; break; + default: DBG_ERRORFILE( "XclImpPageSettings::ReadHeaderFooter - unknown record" ); + } +} + +void XclImpPageSettings::ReadPageBreaks( XclImpStream& rStrm ) +{ + ScfUInt16Vec* pVec = 0; + switch( rStrm.GetRecId() ) + { + case EXC_ID_HORPAGEBREAKS: pVec = &maData.maHorPageBreaks; break; + case EXC_ID_VERPAGEBREAKS: pVec = &maData.maVerPageBreaks; break; + default: DBG_ERRORFILE( "XclImpPageSettings::ReadPageBreaks - unknown record" ); + } + + if( pVec ) + { + bool bIgnore = GetBiff() == EXC_BIFF8; // ignore start/end columns or rows in BIFF8 + + sal_uInt16 nCount, nBreak; + rStrm >> nCount; + pVec->clear(); + pVec->reserve( nCount ); + + while( nCount-- ) + { + rStrm >> nBreak; + if( nBreak ) + pVec->push_back( nBreak ); + if( bIgnore ) + rStrm.Ignore( 4 ); + } + } +} + +void XclImpPageSettings::ReadPrintHeaders( XclImpStream& rStrm ) +{ + maData.mbPrintHeadings = (rStrm.ReaduInt16() != 0); +} + +void XclImpPageSettings::ReadPrintGridLines( XclImpStream& rStrm ) +{ + maData.mbPrintGrid = (rStrm.ReaduInt16() != 0); +} + +void XclImpPageSettings::ReadImgData( XclImpStream& rStrm ) +{ + Graphic aGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); + if( aGraphic.GetType() != GRAPHIC_NONE ) + maData.mxBrushItem.reset( new SvxBrushItem( aGraphic, GPOS_TILED, ATTR_BACKGROUND ) ); +} + +void XclImpPageSettings::SetPaperSize( sal_uInt16 nXclPaperSize, bool bPortrait ) +{ + maData.mnPaperSize = nXclPaperSize; + maData.mbPortrait = bPortrait; + mbValidPaper = true; +} + +// ---------------------------------------------------------------------------- + +namespace { + +void lclPutMarginItem( SfxItemSet& rItemSet, sal_uInt16 nRecId, double fMarginInch ) +{ + sal_uInt16 nMarginTwips = XclTools::GetTwipsFromInch( fMarginInch ); + switch( nRecId ) + { + case EXC_ID_TOPMARGIN: + case EXC_ID_BOTTOMMARGIN: + { + SvxULSpaceItem aItem( GETITEM( rItemSet, SvxULSpaceItem, ATTR_ULSPACE ) ); + if( nRecId == EXC_ID_TOPMARGIN ) + aItem.SetUpperValue( nMarginTwips ); + else + aItem.SetLowerValue( nMarginTwips ); + rItemSet.Put( aItem ); + } + break; + case EXC_ID_LEFTMARGIN: + case EXC_ID_RIGHTMARGIN: + { + SvxLRSpaceItem aItem( GETITEM( rItemSet, SvxLRSpaceItem, ATTR_LRSPACE ) ); + if( nRecId == EXC_ID_LEFTMARGIN ) + aItem.SetLeftValue( nMarginTwips ); + else + aItem.SetRightValue( nMarginTwips ); + rItemSet.Put( aItem ); + } + break; + default: + DBG_ERRORFILE( "XclImpPageSettings::SetMarginItem - unknown record id" ); + } +} + +} // namespace + +void XclImpPageSettings::Finalize() +{ + ScDocument& rDoc = GetDoc(); + SCTAB nScTab = GetCurrScTab(); + + // *** create page style sheet *** + + String aStyleName( RTL_CONSTASCII_USTRINGPARAM( "PageStyle_" ) ); + String aTableName; + if( GetDoc().GetName( nScTab, aTableName ) ) + aStyleName.Append( aTableName ); + else + aStyleName.Append( String::CreateFromInt32( nScTab + 1 ) ); + + ScStyleSheet& rStyleSheet = ScfTools::MakePageStyleSheet( GetStyleSheetPool(), aStyleName, false ); + SfxItemSet& rItemSet = rStyleSheet.GetItemSet(); + + // *** page settings *** + + ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_TOPDOWN, !maData.mbPrintInRows ), true ); + ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HORCENTER, maData.mbHorCenter ), true ); + ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_VERCENTER, maData.mbVerCenter ), true ); + ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HEADERS, maData.mbPrintHeadings ), true ); + ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_GRID, maData.mbPrintGrid ), true ); + ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_NOTES, maData.mbPrintNotes ), true ); + + sal_uInt16 nStartPage = maData.mbManualStart ? maData.mnStartPage : 0; + ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, nStartPage ), true ); + + if( maData.mxBrushItem.get() ) + rItemSet.Put( *maData.mxBrushItem ); + + if( mbValidPaper ) + { + SvxPageItem aPageItem( GETITEM( rItemSet, SvxPageItem, ATTR_PAGE ) ); + aPageItem.SetLandscape( !maData.mbPortrait ); + rItemSet.Put( aPageItem ); + ScfTools::PutItem( rItemSet, SvxSizeItem( ATTR_PAGE_SIZE, maData.GetScPaperSize() ), true ); + } + + if( maData.mbFitToPages ) + rItemSet.Put( ScPageScaleToItem( maData.mnFitToWidth, maData.mnFitToHeight ) ); + else if( maData.mbValid ) + rItemSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, maData.mnScaling ) ); + + // *** margin preparations *** + + double fLeftMargin = maData.mfLeftMargin; + double fRightMargin = maData.mfRightMargin; + double fTopMargin = maData.mfTopMargin; + double fBottomMargin = maData.mfBottomMargin; + // distances between header/footer and page area + double fHeaderHeight = 0.0; + double fHeaderDist = 0.0; + double fFooterHeight = 0.0; + double fFooterDist = 0.0; + // in Calc, "header/footer left/right margin" is X distance between header/footer and page margin + double fHdrLeftMargin = maData.mfHdrLeftMargin - maData.mfLeftMargin; + double fHdrRightMargin = maData.mfHdrRightMargin - maData.mfRightMargin; + double fFtrLeftMargin = maData.mfFtrLeftMargin - maData.mfLeftMargin; + double fFtrRightMargin = maData.mfFtrRightMargin - maData.mfRightMargin; + + // *** header and footer *** + + XclImpHFConverter aHFConv( GetRoot() ); + + // header + bool bHasHeader = (maData.maHeader.Len() != 0); + SvxSetItem aHdrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_HEADERSET ) ); + SfxItemSet& rHdrItemSet = aHdrSetItem.GetItemSet(); + rHdrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasHeader ) ); + if( bHasHeader ) + { + aHFConv.ParseString( maData.maHeader ); + aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERLEFT ); + aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERRIGHT ); + // #i23296# In Calc, "top margin" is distance to header + fTopMargin = maData.mfHeaderMargin; + // Calc uses distance between header and sheet data area + fHeaderHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() ); + fHeaderDist = maData.mfTopMargin - maData.mfHeaderMargin - fHeaderHeight; + } + if( fHeaderDist < 0.0 ) + { + /* #i23296# Header overlays sheet data: + -> set fixed header height to get correct sheet data position. */ + ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true ); + // shrink header height + long nHdrHeight = XclTools::GetTwipsFromInch( fHeaderHeight + fHeaderDist ); + ScfTools::PutItem( rHdrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nHdrHeight ) ), true ); + lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, 0.0 ); + } + else + { + // use dynamic header height + ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true ); + lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, fHeaderDist ); + } + lclPutMarginItem( rHdrItemSet, EXC_ID_LEFTMARGIN, fHdrLeftMargin ); + lclPutMarginItem( rHdrItemSet, EXC_ID_RIGHTMARGIN, fHdrRightMargin ); + rItemSet.Put( aHdrSetItem ); + + // footer + bool bHasFooter = (maData.maFooter.Len() != 0); + SvxSetItem aFtrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_FOOTERSET ) ); + SfxItemSet& rFtrItemSet = aFtrSetItem.GetItemSet(); + rFtrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasFooter ) ); + if( bHasFooter ) + { + aHFConv.ParseString( maData.maFooter ); + aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERLEFT ); + aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERRIGHT ); + // #i23296# In Calc, "bottom margin" is distance to footer + fBottomMargin = maData.mfFooterMargin; + // Calc uses distance between footer and sheet data area + fFooterHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() ); + fFooterDist = maData.mfBottomMargin - maData.mfFooterMargin - fFooterHeight; + } + if( fFooterDist < 0.0 ) + { + /* #i23296# Footer overlays sheet data: + -> set fixed footer height to get correct sheet data end position. */ + ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true ); + // shrink footer height + long nFtrHeight = XclTools::GetTwipsFromInch( fFooterHeight + fFooterDist ); + ScfTools::PutItem( rFtrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nFtrHeight ) ), true ); + lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, 0.0 ); + } + else + { + // use dynamic footer height + ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true ); + lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, fFooterDist ); + } + lclPutMarginItem( rFtrItemSet, EXC_ID_LEFTMARGIN, fFtrLeftMargin ); + lclPutMarginItem( rFtrItemSet, EXC_ID_RIGHTMARGIN, fFtrRightMargin ); + rItemSet.Put( aFtrSetItem ); + + // *** set final margins *** + + lclPutMarginItem( rItemSet, EXC_ID_LEFTMARGIN, fLeftMargin ); + lclPutMarginItem( rItemSet, EXC_ID_RIGHTMARGIN, fRightMargin ); + lclPutMarginItem( rItemSet, EXC_ID_TOPMARGIN, fTopMargin ); + lclPutMarginItem( rItemSet, EXC_ID_BOTTOMMARGIN, fBottomMargin ); + + // *** put style sheet into document *** + + rDoc.SetPageStyle( nScTab, rStyleSheet.GetName() ); + + // *** page breaks *** + + ScfUInt16Vec::const_iterator aIt, aEnd; + + for( aIt = maData.maHorPageBreaks.begin(), aEnd = maData.maHorPageBreaks.end(); aIt != aEnd; ++aIt ) + { + SCROW nScRow = static_cast< SCROW >( *aIt ); + if( nScRow <= MAXROW ) + rDoc.SetRowBreak(nScRow, nScTab, false, true); + } + + for( aIt = maData.maVerPageBreaks.begin(), aEnd = maData.maVerPageBreaks.end(); aIt != aEnd; ++aIt ) + { + SCCOL nScCol = static_cast< SCCOL >( *aIt ); + if( nScCol <= MAXCOL ) + rDoc.SetColBreak(nScCol, nScTab, false, true); + } +} + +// ============================================================================ + |