| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "oox/xls/pagesettings.hxx" |
| |
| #include <algorithm> |
| #include <set> |
| #include <com/sun/star/awt/Size.hpp> |
| #include <com/sun/star/container/XNamed.hpp> |
| #include <com/sun/star/sheet/XHeaderFooterContent.hpp> |
| #include <com/sun/star/style/GraphicLocation.hpp> |
| #include <com/sun/star/text/FilenameDisplayFormat.hpp> |
| #include <com/sun/star/text/XText.hpp> |
| #include <com/sun/star/text/XTextContent.hpp> |
| #include <com/sun/star/text/XTextCursor.hpp> |
| #include <rtl/strbuf.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include "oox/core/xmlfilterbase.hxx" |
| #include "oox/helper/attributelist.hxx" |
| #include "oox/helper/graphichelper.hxx" |
| #include "oox/helper/propertymap.hxx" |
| #include "oox/helper/propertyset.hxx" |
| #include "oox/xls/biffinputstream.hxx" |
| #include "oox/xls/excelhandlers.hxx" |
| #include "oox/xls/stylesbuffer.hxx" |
| #include "oox/xls/unitconverter.hxx" |
| |
| namespace oox { |
| namespace xls { |
| |
| // ============================================================================ |
| |
| using namespace ::com::sun::star::awt; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::sheet; |
| using namespace ::com::sun::star::style; |
| using namespace ::com::sun::star::text; |
| using namespace ::com::sun::star::uno; |
| |
| using ::oox::core::Relations; |
| using ::rtl::OString; |
| using ::rtl::OStringBuffer; |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| const double OOX_MARGIN_DEFAULT_LR = 0.748; /// Left/right default margin in inches. |
| const double OOX_MARGIN_DEFAULT_TB = 0.984; /// Top/bottom default margin in inches. |
| const double OOX_MARGIN_DEFAULT_HF = 0.512; /// Header/footer default margin in inches. |
| |
| const sal_uInt16 BIFF12_PRINTOPT_HORCENTER = 0x0001; |
| const sal_uInt16 BIFF12_PRINTOPT_VERCENTER = 0x0002; |
| const sal_uInt16 BIFF12_PRINTOPT_PRINTHEADING = 0x0004; |
| const sal_uInt16 BIFF12_PRINTOPT_PRINTGRID = 0x0008; |
| |
| const sal_uInt16 BIFF12_HEADERFOOTER_DIFFEVEN = 0x0001; |
| const sal_uInt16 BIFF12_HEADERFOOTER_DIFFFIRST = 0x0002; |
| const sal_uInt16 BIFF12_HEADERFOOTER_SCALEDOC = 0x0004; |
| const sal_uInt16 BIFF12_HEADERFOOTER_ALIGNMARGIN = 0x0008; |
| |
| const sal_uInt16 BIFF12_PAGESETUP_INROWS = 0x0001; |
| const sal_uInt16 BIFF12_PAGESETUP_LANDSCAPE = 0x0002; |
| const sal_uInt16 BIFF12_PAGESETUP_INVALID = 0x0004; |
| const sal_uInt16 BIFF12_PAGESETUP_BLACKWHITE = 0x0008; |
| const sal_uInt16 BIFF12_PAGESETUP_DRAFTQUALITY = 0x0010; |
| const sal_uInt16 BIFF12_PAGESETUP_PRINTNOTES = 0x0020; |
| const sal_uInt16 BIFF12_PAGESETUP_DEFAULTORIENT = 0x0040; |
| const sal_uInt16 BIFF12_PAGESETUP_USEFIRSTPAGE = 0x0080; |
| const sal_uInt16 BIFF12_PAGESETUP_NOTES_END = 0x0100; // different to BIFF flag |
| |
| const sal_uInt16 BIFF12_CHARTPAGESETUP_LANDSCAPE = 0x0001; |
| const sal_uInt16 BIFF12_CHARTPAGESETUP_INVALID = 0x0002; |
| const sal_uInt16 BIFF12_CHARTPAGESETUP_BLACKWHITE = 0x0004; |
| const sal_uInt16 BIFF12_CHARTPAGESETUP_DEFAULTORIENT= 0x0008; |
| const sal_uInt16 BIFF12_CHARTPAGESETUP_USEFIRSTPAGE = 0x0010; |
| const sal_uInt16 BIFF12_CHARTPAGESETUP_DRAFTQUALITY = 0x0020; |
| |
| const sal_uInt16 BIFF_PAGESETUP_INROWS = 0x0001; |
| const sal_uInt16 BIFF_PAGESETUP_PORTRAIT = 0x0002; |
| const sal_uInt16 BIFF_PAGESETUP_INVALID = 0x0004; |
| const sal_uInt16 BIFF_PAGESETUP_BLACKWHITE = 0x0008; |
| const sal_uInt16 BIFF_PAGESETUP_DRAFTQUALITY = 0x0010; |
| const sal_uInt16 BIFF_PAGESETUP_PRINTNOTES = 0x0020; |
| const sal_uInt16 BIFF_PAGESETUP_DEFAULTORIENT = 0x0040; |
| const sal_uInt16 BIFF_PAGESETUP_USEFIRSTPAGE = 0x0080; |
| const sal_uInt16 BIFF_PAGESETUP_NOTES_END = 0x0200; |
| |
| } // namespace |
| |
| // ============================================================================ |
| |
| PageSettingsModel::PageSettingsModel() : |
| mfLeftMargin( OOX_MARGIN_DEFAULT_LR ), |
| mfRightMargin( OOX_MARGIN_DEFAULT_LR ), |
| mfTopMargin( OOX_MARGIN_DEFAULT_TB ), |
| mfBottomMargin( OOX_MARGIN_DEFAULT_TB ), |
| mfHeaderMargin( OOX_MARGIN_DEFAULT_HF ), |
| mfFooterMargin( OOX_MARGIN_DEFAULT_HF ), |
| mnPaperSize( 1 ), |
| mnCopies( 1 ), |
| mnScale( 100 ), |
| mnFirstPage( 1 ), |
| mnFitToWidth( 1 ), |
| mnFitToHeight( 1 ), |
| mnHorPrintRes( 600 ), |
| mnVerPrintRes( 600 ), |
| mnOrientation( XML_default ), |
| mnPageOrder( XML_downThenOver ), |
| mnCellComments( XML_none ), |
| mnPrintErrors( XML_displayed ), |
| mbUseEvenHF( false ), |
| mbUseFirstHF( false ), |
| mbValidSettings( true ), |
| mbUseFirstPage( false ), |
| mbBlackWhite( false ), |
| mbDraftQuality( false ), |
| mbFitToPages( false ), |
| mbHorCenter( false ), |
| mbVerCenter( false ), |
| mbPrintGrid( false ), |
| mbPrintHeadings( false ) |
| { |
| } |
| |
| void PageSettingsModel::setBiffPrintErrors( sal_uInt8 nPrintErrors ) |
| { |
| static const sal_Int32 spnErrorIds[] = { XML_displayed, XML_none, XML_dash, XML_NA }; |
| mnPrintErrors = STATIC_ARRAY_SELECT( spnErrorIds, nPrintErrors, XML_none ); |
| } |
| |
| // ============================================================================ |
| |
| PageSettings::PageSettings( const WorksheetHelper& rHelper ) : |
| WorksheetHelper( rHelper ) |
| { |
| } |
| |
| void PageSettings::importPrintOptions( const AttributeList& rAttribs ) |
| { |
| maModel.mbHorCenter = rAttribs.getBool( XML_horizontalCentered, false ); |
| maModel.mbVerCenter = rAttribs.getBool( XML_verticalCentered, false ); |
| maModel.mbPrintGrid = rAttribs.getBool( XML_gridLines, false ); |
| maModel.mbPrintHeadings = rAttribs.getBool( XML_headings, false ); |
| } |
| |
| void PageSettings::importPageMargins( const AttributeList& rAttribs ) |
| { |
| maModel.mfLeftMargin = rAttribs.getDouble( XML_left, OOX_MARGIN_DEFAULT_LR ); |
| maModel.mfRightMargin = rAttribs.getDouble( XML_right, OOX_MARGIN_DEFAULT_LR ); |
| maModel.mfTopMargin = rAttribs.getDouble( XML_top, OOX_MARGIN_DEFAULT_TB ); |
| maModel.mfBottomMargin = rAttribs.getDouble( XML_bottom, OOX_MARGIN_DEFAULT_TB ); |
| maModel.mfHeaderMargin = rAttribs.getDouble( XML_header, OOX_MARGIN_DEFAULT_HF ); |
| maModel.mfFooterMargin = rAttribs.getDouble( XML_footer, OOX_MARGIN_DEFAULT_HF ); |
| } |
| |
| void PageSettings::importPageSetup( const Relations& rRelations, const AttributeList& rAttribs ) |
| { |
| maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) ); |
| maModel.mnPaperSize = rAttribs.getInteger( XML_paperSize, 1 ); |
| maModel.mnCopies = rAttribs.getInteger( XML_copies, 1 ); |
| maModel.mnScale = rAttribs.getInteger( XML_scale, 100 ); |
| maModel.mnFirstPage = rAttribs.getInteger( XML_firstPageNumber, 1 ); |
| maModel.mnFitToWidth = rAttribs.getInteger( XML_fitToWidth, 1 ); |
| maModel.mnFitToHeight = rAttribs.getInteger( XML_fitToHeight, 1 ); |
| maModel.mnHorPrintRes = rAttribs.getInteger( XML_horizontalDpi, 600 ); |
| maModel.mnVerPrintRes = rAttribs.getInteger( XML_verticalDpi, 600 ); |
| maModel.mnOrientation = rAttribs.getToken( XML_orientation, XML_default ); |
| maModel.mnPageOrder = rAttribs.getToken( XML_pageOrder, XML_downThenOver ); |
| maModel.mnCellComments = rAttribs.getToken( XML_cellComments, XML_none ); |
| maModel.mnPrintErrors = rAttribs.getToken( XML_errors, XML_displayed ); |
| maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true ); |
| maModel.mbUseFirstPage = rAttribs.getBool( XML_useFirstPageNumber, false ); |
| maModel.mbBlackWhite = rAttribs.getBool( XML_blackAndWhite, false ); |
| maModel.mbDraftQuality = rAttribs.getBool( XML_draft, false ); |
| } |
| |
| void PageSettings::importChartPageSetup( const Relations& rRelations, const AttributeList& rAttribs ) |
| { |
| maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) ); |
| maModel.mnPaperSize = rAttribs.getInteger( XML_paperSize, 1 ); |
| maModel.mnCopies = rAttribs.getInteger( XML_copies, 1 ); |
| maModel.mnFirstPage = rAttribs.getInteger( XML_firstPageNumber, 1 ); |
| maModel.mnHorPrintRes = rAttribs.getInteger( XML_horizontalDpi, 600 ); |
| maModel.mnVerPrintRes = rAttribs.getInteger( XML_verticalDpi, 600 ); |
| maModel.mnOrientation = rAttribs.getToken( XML_orientation, XML_default ); |
| maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true ); |
| maModel.mbUseFirstPage = rAttribs.getBool( XML_useFirstPageNumber, false ); |
| maModel.mbBlackWhite = rAttribs.getBool( XML_blackAndWhite, false ); |
| maModel.mbDraftQuality = rAttribs.getBool( XML_draft, false ); |
| } |
| |
| void PageSettings::importHeaderFooter( const AttributeList& rAttribs ) |
| { |
| maModel.mbUseEvenHF = rAttribs.getBool( XML_differentOddEven, false ); |
| maModel.mbUseFirstHF = rAttribs.getBool( XML_differentFirst, false ); |
| } |
| |
| void PageSettings::importHeaderFooterCharacters( const OUString& rChars, sal_Int32 nElement ) |
| { |
| switch( nElement ) |
| { |
| case XLS_TOKEN( oddHeader ): maModel.maOddHeader += rChars; break; |
| case XLS_TOKEN( oddFooter ): maModel.maOddFooter += rChars; break; |
| case XLS_TOKEN( evenHeader ): maModel.maEvenHeader += rChars; break; |
| case XLS_TOKEN( evenFooter ): maModel.maEvenFooter += rChars; break; |
| case XLS_TOKEN( firstHeader ): maModel.maFirstHeader += rChars; break; |
| case XLS_TOKEN( firstFooter ): maModel.maFirstFooter += rChars; break; |
| } |
| } |
| |
| void PageSettings::importPicture( const Relations& rRelations, const AttributeList& rAttribs ) |
| { |
| importPictureData( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) ); |
| } |
| |
| void PageSettings::importPageMargins( SequenceInputStream& rStrm ) |
| { |
| rStrm >> maModel.mfLeftMargin >> maModel.mfRightMargin |
| >> maModel.mfTopMargin >> maModel.mfBottomMargin |
| >> maModel.mfHeaderMargin >> maModel.mfFooterMargin; |
| } |
| |
| void PageSettings::importPrintOptions( SequenceInputStream& rStrm ) |
| { |
| sal_uInt16 nFlags; |
| rStrm >> nFlags; |
| maModel.mbHorCenter = getFlag( nFlags, BIFF12_PRINTOPT_HORCENTER ); |
| maModel.mbVerCenter = getFlag( nFlags, BIFF12_PRINTOPT_VERCENTER ); |
| maModel.mbPrintGrid = getFlag( nFlags, BIFF12_PRINTOPT_PRINTGRID ); |
| maModel.mbPrintHeadings = getFlag( nFlags, BIFF12_PRINTOPT_PRINTHEADING ); |
| } |
| |
| void PageSettings::importPageSetup( const Relations& rRelations, SequenceInputStream& rStrm ) |
| { |
| OUString aRelId; |
| sal_uInt16 nFlags; |
| rStrm >> maModel.mnPaperSize >> maModel.mnScale |
| >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes |
| >> maModel.mnCopies >> maModel.mnFirstPage |
| >> maModel.mnFitToWidth >> maModel.mnFitToHeight |
| >> nFlags >> aRelId; |
| maModel.setBiffPrintErrors( extractValue< sal_uInt8 >( nFlags, 9, 2 ) ); |
| maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( aRelId ); |
| maModel.mnOrientation = getFlagValue( nFlags, BIFF12_PAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_PAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) ); |
| maModel.mnPageOrder = getFlagValue( nFlags, BIFF12_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver ); |
| maModel.mnCellComments = getFlagValue( nFlags, BIFF12_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF12_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none ); |
| maModel.mbValidSettings = !getFlag( nFlags, BIFF12_PAGESETUP_INVALID ); |
| maModel.mbUseFirstPage = getFlag( nFlags, BIFF12_PAGESETUP_USEFIRSTPAGE ); |
| maModel.mbBlackWhite = getFlag( nFlags, BIFF12_PAGESETUP_BLACKWHITE ); |
| maModel.mbDraftQuality = getFlag( nFlags, BIFF12_PAGESETUP_DRAFTQUALITY ); |
| } |
| |
| void PageSettings::importChartPageSetup( const Relations& rRelations, SequenceInputStream& rStrm ) |
| { |
| OUString aRelId; |
| sal_uInt16 nFirstPage, nFlags; |
| rStrm >> maModel.mnPaperSize >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes |
| >> maModel.mnCopies >> nFirstPage >> nFlags >> aRelId; |
| maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( aRelId ); |
| maModel.mnFirstPage = nFirstPage; // 16-bit in CHARTPAGESETUP |
| maModel.mnOrientation = getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) ); |
| maModel.mbValidSettings = !getFlag( nFlags, BIFF12_CHARTPAGESETUP_INVALID ); |
| maModel.mbUseFirstPage = getFlag( nFlags, BIFF12_CHARTPAGESETUP_USEFIRSTPAGE ); |
| maModel.mbBlackWhite = getFlag( nFlags, BIFF12_CHARTPAGESETUP_BLACKWHITE ); |
| maModel.mbDraftQuality = getFlag( nFlags, BIFF12_CHARTPAGESETUP_DRAFTQUALITY ); |
| } |
| |
| void PageSettings::importHeaderFooter( SequenceInputStream& rStrm ) |
| { |
| sal_uInt16 nFlags; |
| rStrm >> nFlags |
| >> maModel.maOddHeader >> maModel.maOddFooter |
| >> maModel.maEvenHeader >> maModel.maEvenFooter |
| >> maModel.maFirstHeader >> maModel.maFirstFooter; |
| maModel.mbUseEvenHF = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFEVEN ); |
| maModel.mbUseFirstHF = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFFIRST ); |
| } |
| |
| void PageSettings::importPicture( const Relations& rRelations, SequenceInputStream& rStrm ) |
| { |
| importPictureData( rRelations, BiffHelper::readString( rStrm ) ); |
| } |
| |
| void PageSettings::importLeftMargin( BiffInputStream& rStrm ) |
| { |
| rStrm >> maModel.mfLeftMargin; |
| } |
| |
| void PageSettings::importRightMargin( BiffInputStream& rStrm ) |
| { |
| rStrm >> maModel.mfRightMargin; |
| } |
| |
| void PageSettings::importTopMargin( BiffInputStream& rStrm ) |
| { |
| rStrm >> maModel.mfTopMargin; |
| } |
| |
| void PageSettings::importBottomMargin( BiffInputStream& rStrm ) |
| { |
| rStrm >> maModel.mfBottomMargin; |
| } |
| |
| void PageSettings::importPageSetup( BiffInputStream& rStrm ) |
| { |
| sal_uInt16 nPaperSize, nScale, nFirstPage, nFitToWidth, nFitToHeight, nFlags; |
| rStrm >> nPaperSize >> nScale >> nFirstPage >> nFitToWidth >> nFitToHeight >> nFlags; |
| |
| maModel.mnPaperSize = nPaperSize; // equal in BIFF and OOX |
| maModel.mnScale = nScale; |
| maModel.mnFirstPage = nFirstPage; |
| maModel.mnFitToWidth = nFitToWidth; |
| maModel.mnFitToHeight = nFitToHeight; |
| maModel.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_PORTRAIT, XML_portrait, XML_landscape ); |
| maModel.mnPageOrder = getFlagValue( nFlags, BIFF_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver ); |
| maModel.mbValidSettings = !getFlag( nFlags, BIFF_PAGESETUP_INVALID ); |
| maModel.mbUseFirstPage = true; |
| maModel.mbBlackWhite = getFlag( nFlags, BIFF_PAGESETUP_BLACKWHITE ); |
| |
| if( getBiff() >= BIFF5 ) |
| { |
| sal_uInt16 nHorPrintRes, nVerPrintRes, nCopies; |
| rStrm >> nHorPrintRes >> nVerPrintRes >> maModel.mfHeaderMargin >> maModel.mfFooterMargin >> nCopies; |
| |
| maModel.mnCopies = nCopies; |
| maModel.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_DEFAULTORIENT, XML_default, maModel.mnOrientation ); |
| maModel.mnHorPrintRes = nHorPrintRes; |
| maModel.mnVerPrintRes = nVerPrintRes; |
| maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, XML_asDisplayed, XML_none ); |
| maModel.mbUseFirstPage = getFlag( nFlags, BIFF_PAGESETUP_USEFIRSTPAGE ); |
| maModel.mbDraftQuality = getFlag( nFlags, BIFF_PAGESETUP_DRAFTQUALITY ); |
| |
| if( getBiff() == BIFF8 ) |
| { |
| maModel.setBiffPrintErrors( extractValue< sal_uInt8 >( nFlags, 10, 2 ) ); |
| maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none ); |
| } |
| } |
| } |
| |
| void PageSettings::importHorCenter( BiffInputStream& rStrm ) |
| { |
| maModel.mbHorCenter = rStrm.readuInt16() != 0; |
| } |
| |
| void PageSettings::importVerCenter( BiffInputStream& rStrm ) |
| { |
| maModel.mbVerCenter = rStrm.readuInt16() != 0; |
| } |
| |
| void PageSettings::importPrintHeaders( BiffInputStream& rStrm ) |
| { |
| maModel.mbPrintHeadings = rStrm.readuInt16() != 0; |
| } |
| |
| void PageSettings::importPrintGridLines( BiffInputStream& rStrm ) |
| { |
| maModel.mbPrintGrid = rStrm.readuInt16() != 0; |
| } |
| |
| void PageSettings::importHeader( BiffInputStream& rStrm ) |
| { |
| if( rStrm.getRemaining() > 0 ) |
| maModel.maOddHeader = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() ); |
| else |
| maModel.maOddHeader = OUString(); |
| } |
| |
| void PageSettings::importFooter( BiffInputStream& rStrm ) |
| { |
| if( rStrm.getRemaining() > 0 ) |
| maModel.maOddFooter = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() ); |
| else |
| maModel.maOddFooter = OUString(); |
| } |
| |
| void PageSettings::importPicture( BiffInputStream& rStrm ) |
| { |
| StreamDataSequence aPictureData; |
| BiffHelper::importImgData( aPictureData, rStrm, getBiff() ); |
| maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importGraphicObject( aPictureData ); |
| } |
| |
| void PageSettings::setFitToPagesMode( bool bFitToPages ) |
| { |
| maModel.mbFitToPages = bFitToPages; |
| } |
| |
| void PageSettings::finalizeImport() |
| { |
| OUStringBuffer aStyleNameBuffer( CREATE_OUSTRING( "PageStyle_" ) ); |
| Reference< XNamed > xSheetName( getSheet(), UNO_QUERY ); |
| if( xSheetName.is() ) |
| aStyleNameBuffer.append( xSheetName->getName() ); |
| else |
| aStyleNameBuffer.append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ); |
| OUString aStyleName = aStyleNameBuffer.makeStringAndClear(); |
| |
| Reference< XStyle > xStyle = createStyleObject( aStyleName, true ); |
| PropertySet aStyleProps( xStyle ); |
| getPageSettingsConverter().writePageSettingsProperties( aStyleProps, maModel, getSheetType() ); |
| |
| PropertySet aSheetProps( getSheet() ); |
| aSheetProps.setProperty( PROP_PageStyle, aStyleName ); |
| } |
| |
| void PageSettings::importPictureData( const Relations& rRelations, const OUString& rRelId ) |
| { |
| OUString aPicturePath = rRelations.getFragmentPathFromRelId( rRelId ); |
| if( aPicturePath.getLength() > 0 ) |
| maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importEmbeddedGraphicObject( aPicturePath ); |
| } |
| |
| // ============================================================================ |
| // ============================================================================ |
| |
| enum HFPortionId |
| { |
| HF_LEFT, |
| HF_CENTER, |
| HF_RIGHT, |
| HF_COUNT |
| }; |
| |
| // ---------------------------------------------------------------------------- |
| |
| struct HFPortionInfo |
| { |
| Reference< XText > mxText; /// XText interface of this portion. |
| Reference< XTextCursor > mxStart; /// Start position of current text range for formatting. |
| Reference< XTextCursor > mxEnd; /// End position of current text range for formatting. |
| double mfTotalHeight; /// Sum of heights of previous lines in points. |
| double mfCurrHeight; /// Height of the current text line in points. |
| |
| bool initialize( const Reference< XText >& rxText ); |
| }; |
| |
| bool HFPortionInfo::initialize( const Reference< XText >& rxText ) |
| { |
| mfTotalHeight = mfCurrHeight = 0.0; |
| mxText = rxText; |
| if( mxText.is() ) |
| { |
| mxStart = mxText->createTextCursor(); |
| mxEnd = mxText->createTextCursor(); |
| } |
| bool bRet = mxText.is() && mxStart.is() && mxEnd.is(); |
| OSL_ENSURE( bRet, "HFPortionInfo::initialize - missing interfaces" ); |
| return bRet; |
| } |
| |
| // ============================================================================ |
| |
| class HeaderFooterParser : public WorkbookHelper |
| { |
| public: |
| explicit HeaderFooterParser( const WorkbookHelper& rHelper ); |
| |
| /** Parses the passed string and creates the header/footer contents. |
| @returns The total height of the converted header or footer in points. */ |
| double parse( |
| const Reference< XHeaderFooterContent >& rxContext, |
| const OUString& rData ); |
| |
| private: |
| /** Returns the current edit engine text object. */ |
| inline HFPortionInfo& getPortion() { return maPortions[ meCurrPortion ]; } |
| /** Returns the start cursor of the current text range. */ |
| inline const Reference< XTextCursor >& getStartPos() { return getPortion().mxStart; } |
| /** Returns the end cursor of the current text range. */ |
| inline const Reference< XTextCursor >& getEndPos() { return getPortion().mxEnd; } |
| |
| /** Returns the current line height of the specified portion. */ |
| double getCurrHeight( HFPortionId ePortion ) const; |
| /** Returns the current line height. */ |
| double getCurrHeight() const; |
| |
| /** Updates the current line height of the specified portion, using the current font size. */ |
| void updateCurrHeight( HFPortionId ePortion ); |
| /** Updates the current line height, using the current font size. */ |
| void updateCurrHeight(); |
| |
| /** Sets the font attributes at the current selection. */ |
| void setAttributes(); |
| /** Appends and clears internal string buffer. */ |
| void appendText(); |
| /** Appends a line break and adjusts internal text height data. */ |
| void appendLineBreak(); |
| |
| /** Creates a text field from the passed service name. */ |
| Reference< XTextContent > createField( const OUString& rServiceName ) const; |
| /** Appends the passed text field. */ |
| void appendField( const Reference< XTextContent >& rxContent ); |
| |
| /** Sets the passed font name if it is valid. */ |
| void convertFontName( const OUString& rStyle ); |
| /** Converts a font style given as string. */ |
| void convertFontStyle( const OUString& rStyle ); |
| /** Converts a font color given as string. */ |
| void convertFontColor( const OUString& rColor ); |
| |
| /** Finalizes current portion: sets font attributes and updates text height data. */ |
| void finalizePortion(); |
| /** Changes current header/footer portion. */ |
| void setNewPortion( HFPortionId ePortion ); |
| |
| private: |
| typedef ::std::vector< HFPortionInfo > HFPortionInfoVec; |
| typedef ::std::set< OString > OStringSet; |
| |
| const OUString maPageNumberService; |
| const OUString maPageCountService; |
| const OUString maSheetNameService; |
| const OUString maFileNameService; |
| const OUString maDateTimeService; |
| const OStringSet maBoldNames; /// All names for bold font style in lowercase UTF-8. |
| const OStringSet maItalicNames; /// All names for italic font style in lowercase UTF-8. |
| HFPortionInfoVec maPortions; |
| HFPortionId meCurrPortion; /// Identifier of current H/F portion. |
| OUStringBuffer maBuffer; /// Text data to append to current text range. |
| FontModel maFontModel; /// Font attributes of current text range. |
| }; |
| |
| // ---------------------------------------------------------------------------- |
| |
| namespace { |
| |
| // different names for bold font style (lowercase) |
| static const sal_Char* const sppcBoldNames[] = |
| { |
| "bold", |
| "fett", // German 'bold' |
| "demibold", |
| "halbfett", // German 'demibold' |
| "black", |
| "heavy" |
| }; |
| |
| // different names for italic font style (lowercase) |
| static const sal_Char* const sppcItalicNames[] = |
| { |
| "italic", |
| "kursiv", // German 'italic' |
| "oblique", |
| "schr\303\204g", // German 'oblique' with uppercase A umlaut |
| "schr\303\244g" // German 'oblique' with lowercase A umlaut |
| }; |
| |
| } // namespace |
| |
| // ---------------------------------------------------------------------------- |
| |
| HeaderFooterParser::HeaderFooterParser( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ), |
| maPageNumberService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageNumber" ) ), |
| maPageCountService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageCount" ) ), |
| maSheetNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.SheetName" ) ), |
| maFileNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.FileName" ) ), |
| maDateTimeService( CREATE_OUSTRING( "com.sun.star.text.TextField.DateTime" ) ), |
| maBoldNames( sppcBoldNames, STATIC_ARRAY_END( sppcBoldNames ) ), |
| maItalicNames( sppcItalicNames, STATIC_ARRAY_END( sppcItalicNames ) ), |
| maPortions( static_cast< size_t >( HF_COUNT ) ), |
| meCurrPortion( HF_CENTER ) |
| { |
| } |
| |
| double HeaderFooterParser::parse( const Reference< XHeaderFooterContent >& rxContext, const OUString& rData ) |
| { |
| if( !rxContext.is() || (rData.getLength() == 0) || |
| !maPortions[ HF_LEFT ].initialize( rxContext->getLeftText() ) || |
| !maPortions[ HF_CENTER ].initialize( rxContext->getCenterText() ) || |
| !maPortions[ HF_RIGHT ].initialize( rxContext->getRightText() ) ) |
| return 0.0; |
| |
| meCurrPortion = HF_CENTER; |
| maBuffer.setLength( 0 ); |
| maFontModel = getStyles().getDefaultFontModel(); |
| OUStringBuffer aFontName; // current font name |
| OUStringBuffer aFontStyle; // current font style |
| sal_Int32 nFontHeight = 0; // current font height |
| |
| /** State of the parser. */ |
| enum |
| { |
| STATE_TEXT, /// Literal text data. |
| STATE_TOKEN, /// Control token following a '&' character. |
| STATE_FONTNAME, /// Font name ('&' is followed by '"', reads until next '"' or ','). |
| STATE_FONTSTYLE, /// Font style name (font part after ',', reads until next '"'). |
| STATE_FONTHEIGHT /// Font height ('&' is followed by num. digits, reads until non-digit). |
| } |
| eState = STATE_TEXT; |
| |
| const sal_Unicode* pcChar = rData.getStr(); |
| const sal_Unicode* pcEnd = pcChar + rData.getLength(); |
| for( ; (pcChar != pcEnd) && (*pcChar != 0); ++pcChar ) |
| { |
| sal_Unicode cChar = *pcChar; |
| switch( eState ) |
| { |
| case STATE_TEXT: |
| { |
| switch( cChar ) |
| { |
| case '&': // new token |
| appendText(); |
| eState = STATE_TOKEN; |
| break; |
| case '\n': // line break |
| appendText(); |
| appendLineBreak(); |
| break; |
| default: |
| maBuffer.append( cChar ); |
| } |
| } |
| break; |
| |
| case STATE_TOKEN: |
| { |
| // default: back to text mode, may be changed in specific cases |
| eState = STATE_TEXT; |
| // ignore case of token codes |
| if( ('a' <= cChar) && (cChar <= 'z') ) |
| (cChar -= 'a') += 'A'; |
| switch( cChar ) |
| { |
| case '&': maBuffer.append( cChar ); break; // the '&' character |
| |
| case 'L': setNewPortion( HF_LEFT ); break; // left portion |
| case 'C': setNewPortion( HF_CENTER ); break; // center portion |
| case 'R': setNewPortion( HF_RIGHT ); break; // right portion |
| |
| case 'P': // page number |
| appendField( createField( maPageNumberService ) ); |
| break; |
| case 'N': // total page count |
| appendField( createField( maPageCountService ) ); |
| break; |
| case 'A': // current sheet name |
| appendField( createField( maSheetNameService ) ); |
| break; |
| |
| case 'F': // file name |
| { |
| Reference< XTextContent > xContent = createField( maFileNameService ); |
| PropertySet aPropSet( xContent ); |
| aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::NAME_AND_EXT ); |
| appendField( xContent ); |
| } |
| break; |
| case 'Z': // file path (without file name), OOXML, BIFF12, and BIFF8 only |
| if( (getFilterType() == FILTER_OOXML) || ((getFilterType() == FILTER_BIFF) && (getBiff() == BIFF8)) ) |
| { |
| Reference< XTextContent > xContent = createField( maFileNameService ); |
| PropertySet aPropSet( xContent ); |
| // FilenameDisplayFormat::PATH not supported by Calc |
| aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::FULL ); |
| appendField( xContent ); |
| /* path only is not supported -- if we find a '&Z&F' |
| combination for path/name, skip the '&F' part */ |
| if( (pcChar + 2 < pcEnd) && (pcChar[ 1 ] == '&') && ((pcChar[ 2 ] == 'f') || (pcChar[ 2 ] == 'F')) ) |
| pcChar += 2; |
| } |
| break; |
| case 'D': // date |
| { |
| Reference< XTextContent > xContent = createField( maDateTimeService ); |
| PropertySet aPropSet( xContent ); |
| aPropSet.setProperty( PROP_IsDate, true ); |
| appendField( xContent ); |
| } |
| break; |
| case 'T': // time |
| { |
| Reference< XTextContent > xContent = createField( maDateTimeService ); |
| PropertySet aPropSet( xContent ); |
| aPropSet.setProperty( PROP_IsDate, false ); |
| appendField( xContent ); |
| } |
| break; |
| |
| case 'B': // bold |
| setAttributes(); |
| maFontModel.mbBold = !maFontModel.mbBold; |
| break; |
| case 'I': // italic |
| setAttributes(); |
| maFontModel.mbItalic = !maFontModel.mbItalic; |
| break; |
| case 'U': // underline |
| setAttributes(); |
| maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_single) ? XML_none : XML_single; |
| break; |
| case 'E': // double underline |
| setAttributes(); |
| maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_double) ? XML_none : XML_double; |
| break; |
| case 'S': // strikeout |
| setAttributes(); |
| maFontModel.mbStrikeout = !maFontModel.mbStrikeout; |
| break; |
| case 'X': // superscript |
| setAttributes(); |
| maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_superscript) ? XML_baseline : XML_superscript; |
| break; |
| case 'Y': // subsrcipt |
| setAttributes(); |
| maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_subscript) ? XML_baseline : XML_subscript; |
| break; |
| case 'O': // outlined |
| setAttributes(); |
| maFontModel.mbOutline = !maFontModel.mbOutline; |
| break; |
| case 'H': // shadow |
| setAttributes(); |
| maFontModel.mbShadow = !maFontModel.mbShadow; |
| break; |
| |
| case 'K': // text color (not in BIFF) |
| if( (getFilterType() == FILTER_OOXML) && (pcChar + 6 < pcEnd) ) |
| { |
| setAttributes(); |
| // eat the following 6 characters |
| convertFontColor( OUString( pcChar + 1, 6 ) ); |
| pcChar += 6; |
| } |
| break; |
| |
| case '\"': // font name |
| aFontName.setLength( 0 ); |
| aFontStyle.setLength( 0 ); |
| eState = STATE_FONTNAME; |
| break; |
| default: |
| if( ('0' <= cChar) && (cChar <= '9') ) // font size |
| { |
| nFontHeight = cChar - '0'; |
| eState = STATE_FONTHEIGHT; |
| } |
| } |
| } |
| break; |
| |
| case STATE_FONTNAME: |
| { |
| switch( cChar ) |
| { |
| case '\"': |
| setAttributes(); |
| convertFontName( aFontName.makeStringAndClear() ); |
| eState = STATE_TEXT; |
| break; |
| case ',': |
| eState = STATE_FONTSTYLE; |
| break; |
| default: |
| aFontName.append( cChar ); |
| } |
| } |
| break; |
| |
| case STATE_FONTSTYLE: |
| { |
| switch( cChar ) |
| { |
| case '\"': |
| setAttributes(); |
| convertFontName( aFontName.makeStringAndClear() ); |
| convertFontStyle( aFontStyle.makeStringAndClear() ); |
| eState = STATE_TEXT; |
| break; |
| default: |
| aFontStyle.append( cChar ); |
| } |
| } |
| break; |
| |
| case STATE_FONTHEIGHT: |
| { |
| if( ('0' <= cChar) && (cChar <= '9') ) |
| { |
| if( nFontHeight >= 0 ) |
| { |
| nFontHeight *= 10; |
| nFontHeight += (cChar - '0'); |
| if( nFontHeight > 1000 ) |
| nFontHeight = -1; |
| } |
| } |
| else |
| { |
| if( nFontHeight > 0 ) |
| { |
| setAttributes(); |
| maFontModel.mfHeight = nFontHeight; |
| } |
| --pcChar; |
| eState = STATE_TEXT; |
| } |
| } |
| break; |
| } |
| } |
| |
| // finalize |
| finalizePortion(); |
| maPortions[ HF_LEFT ].mfTotalHeight += getCurrHeight( HF_LEFT ); |
| maPortions[ HF_CENTER ].mfTotalHeight += getCurrHeight( HF_CENTER ); |
| maPortions[ HF_RIGHT ].mfTotalHeight += getCurrHeight( HF_RIGHT ); |
| |
| return ::std::max( maPortions[ HF_LEFT ].mfTotalHeight, |
| ::std::max( maPortions[ HF_CENTER ].mfTotalHeight, maPortions[ HF_RIGHT ].mfTotalHeight ) ); |
| } |
| |
| // private -------------------------------------------------------------------- |
| |
| double HeaderFooterParser::getCurrHeight( HFPortionId ePortion ) const |
| { |
| double fMaxHt = maPortions[ ePortion ].mfCurrHeight; |
| return (fMaxHt == 0.0) ? maFontModel.mfHeight : fMaxHt; |
| } |
| |
| double HeaderFooterParser::getCurrHeight() const |
| { |
| return getCurrHeight( meCurrPortion ); |
| } |
| |
| void HeaderFooterParser::updateCurrHeight( HFPortionId ePortion ) |
| { |
| double& rfMaxHt = maPortions[ ePortion ].mfCurrHeight; |
| rfMaxHt = ::std::max( rfMaxHt, maFontModel.mfHeight ); |
| } |
| |
| void HeaderFooterParser::updateCurrHeight() |
| { |
| updateCurrHeight( meCurrPortion ); |
| } |
| |
| void HeaderFooterParser::setAttributes() |
| { |
| Reference< XTextRange > xRange( getStartPos(), UNO_QUERY ); |
| getEndPos()->gotoRange( xRange, sal_False ); |
| getEndPos()->gotoEnd( sal_True ); |
| if( !getEndPos()->isCollapsed() ) |
| { |
| Font aFont( *this, maFontModel ); |
| aFont.finalizeImport(); |
| PropertySet aPropSet( getEndPos() ); |
| aFont.writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); |
| getStartPos()->gotoEnd( sal_False ); |
| getEndPos()->gotoEnd( sal_False ); |
| } |
| } |
| |
| void HeaderFooterParser::appendText() |
| { |
| if( maBuffer.getLength() > 0 ) |
| { |
| getEndPos()->gotoEnd( sal_False ); |
| getEndPos()->setString( maBuffer.makeStringAndClear() ); |
| updateCurrHeight(); |
| } |
| } |
| |
| void HeaderFooterParser::appendLineBreak() |
| { |
| getEndPos()->gotoEnd( sal_False ); |
| getEndPos()->setString( OUString( sal_Unicode( '\n' ) ) ); |
| getPortion().mfTotalHeight += getCurrHeight(); |
| getPortion().mfCurrHeight = 0; |
| } |
| |
| Reference< XTextContent > HeaderFooterParser::createField( const OUString& rServiceName ) const |
| { |
| Reference< XTextContent > xContent; |
| try |
| { |
| xContent.set( getBaseFilter().getModelFactory()->createInstance( rServiceName ), UNO_QUERY_THROW ); |
| } |
| catch( Exception& ) |
| { |
| OSL_ENSURE( false, |
| OStringBuffer( "HeaderFooterParser::createField - error while creating text field \"" ). |
| append( OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ) ). |
| append( '"' ).getStr() ); |
| } |
| return xContent; |
| } |
| |
| void HeaderFooterParser::appendField( const Reference< XTextContent >& rxContent ) |
| { |
| getEndPos()->gotoEnd( sal_False ); |
| try |
| { |
| Reference< XTextRange > xRange( getEndPos(), UNO_QUERY_THROW ); |
| getPortion().mxText->insertTextContent( xRange, rxContent, sal_False ); |
| updateCurrHeight(); |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| void HeaderFooterParser::convertFontName( const OUString& rName ) |
| { |
| if( rName.getLength() > 0 ) |
| { |
| // single dash is document default font |
| if( (rName.getLength() == 1) && (rName[ 0 ] == '-') ) |
| maFontModel.maName = getStyles().getDefaultFontModel().maName; |
| else |
| maFontModel.maName = rName; |
| } |
| } |
| |
| void HeaderFooterParser::convertFontStyle( const OUString& rStyle ) |
| { |
| maFontModel.mbBold = maFontModel.mbItalic = false; |
| sal_Int32 nPos = 0; |
| sal_Int32 nLen = rStyle.getLength(); |
| while( (0 <= nPos) && (nPos < nLen) ) |
| { |
| OString aToken = OUStringToOString( rStyle.getToken( 0, ' ', nPos ), RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase(); |
| if( aToken.getLength() > 0 ) |
| { |
| if( maBoldNames.count( aToken ) > 0 ) |
| maFontModel.mbBold = true; |
| else if( maItalicNames.count( aToken ) > 0 ) |
| maFontModel.mbItalic = true; |
| } |
| } |
| } |
| |
| void HeaderFooterParser::convertFontColor( const OUString& rColor ) |
| { |
| OSL_ENSURE( rColor.getLength() == 6, "HeaderFooterParser::convertFontColor - invalid font color code" ); |
| if( (rColor[ 2 ] == '+') || (rColor[ 2 ] == '-') ) |
| // theme color: TTSNNN (TT = decimal theme index, S = +/-, NNN = decimal tint/shade in percent) |
| maFontModel.maColor.setTheme( |
| rColor.copy( 0, 2 ).toInt32(), |
| static_cast< double >( rColor.copy( 2 ).toInt32() ) / 100.0 ); |
| else |
| // RGB color: RRGGBB |
| maFontModel.maColor.setRgb( rColor.toInt32( 16 ) ); |
| } |
| |
| void HeaderFooterParser::finalizePortion() |
| { |
| appendText(); |
| setAttributes(); |
| } |
| |
| void HeaderFooterParser::setNewPortion( HFPortionId ePortion ) |
| { |
| if( ePortion != meCurrPortion ) |
| { |
| finalizePortion(); |
| meCurrPortion = ePortion; |
| maFontModel = getStyles().getDefaultFontModel(); |
| } |
| } |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| /** Paper size in 1/100 millimeters. */ |
| struct ApiPaperSize |
| { |
| sal_Int32 mnWidth; |
| sal_Int32 mnHeight; |
| }; |
| |
| #define IN2MM100( v ) static_cast< sal_Int32 >( (v) * 2540.0 + 0.5 ) |
| #define MM2MM100( v ) static_cast< sal_Int32 >( (v) * 100.0 + 0.5 ) |
| |
| static const ApiPaperSize spPaperSizeTable[] = |
| { |
| { 0, 0 }, // 0 - (undefined) |
| { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 1 - Letter paper |
| { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 2 - Letter small paper |
| { IN2MM100( 11 ), IN2MM100( 17 ) }, // 3 - Tabloid paper |
| { IN2MM100( 17 ), IN2MM100( 11 ) }, // 4 - Ledger paper |
| { IN2MM100( 8.5 ), IN2MM100( 14 ) }, // 5 - Legal paper |
| { IN2MM100( 5.5 ), IN2MM100( 8.5 ) }, // 6 - Statement paper |
| { IN2MM100( 7.25 ), IN2MM100( 10.5 ) }, // 7 - Executive paper |
| { MM2MM100( 297 ), MM2MM100( 420 ) }, // 8 - A3 paper |
| { MM2MM100( 210 ), MM2MM100( 297 ) }, // 9 - A4 paper |
| { MM2MM100( 210 ), MM2MM100( 297 ) }, // 10 - A4 small paper |
| { MM2MM100( 148 ), MM2MM100( 210 ) }, // 11 - A5 paper |
| { MM2MM100( 250 ), MM2MM100( 353 ) }, // 12 - B4 paper |
| { MM2MM100( 176 ), MM2MM100( 250 ) }, // 13 - B5 paper |
| { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 14 - Folio paper |
| { MM2MM100( 215 ), MM2MM100( 275 ) }, // 15 - Quarto paper |
| { IN2MM100( 10 ), IN2MM100( 14 ) }, // 16 - Standard paper |
| { IN2MM100( 11 ), IN2MM100( 17 ) }, // 17 - Standard paper |
| { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 18 - Note paper |
| { IN2MM100( 3.875 ), IN2MM100( 8.875 ) }, // 19 - #9 envelope |
| { IN2MM100( 4.125 ), IN2MM100( 9.5 ) }, // 20 - #10 envelope |
| { IN2MM100( 4.5 ), IN2MM100( 10.375 ) }, // 21 - #11 envelope |
| { IN2MM100( 4.75 ), IN2MM100( 11 ) }, // 22 - #12 envelope |
| { IN2MM100( 5 ), IN2MM100( 11.5 ) }, // 23 - #14 envelope |
| { IN2MM100( 17 ), IN2MM100( 22 ) }, // 24 - C paper |
| { IN2MM100( 22 ), IN2MM100( 34 ) }, // 25 - D paper |
| { IN2MM100( 34 ), IN2MM100( 44 ) }, // 26 - E paper |
| { MM2MM100( 110 ), MM2MM100( 220 ) }, // 27 - DL envelope |
| { MM2MM100( 162 ), MM2MM100( 229 ) }, // 28 - C5 envelope |
| { MM2MM100( 324 ), MM2MM100( 458 ) }, // 29 - C3 envelope |
| { MM2MM100( 229 ), MM2MM100( 324 ) }, // 30 - C4 envelope |
| { MM2MM100( 114 ), MM2MM100( 162 ) }, // 31 - C6 envelope |
| { MM2MM100( 114 ), MM2MM100( 229 ) }, // 32 - C65 envelope |
| { MM2MM100( 250 ), MM2MM100( 353 ) }, // 33 - B4 envelope |
| { MM2MM100( 176 ), MM2MM100( 250 ) }, // 34 - B5 envelope |
| { MM2MM100( 176 ), MM2MM100( 125 ) }, // 35 - B6 envelope |
| { MM2MM100( 110 ), MM2MM100( 230 ) }, // 36 - Italy envelope |
| { IN2MM100( 3.875 ), IN2MM100( 7.5 ) }, // 37 - Monarch envelope |
| { IN2MM100( 3.625 ), IN2MM100( 6.5 ) }, // 38 - 6 3/4 envelope |
| { IN2MM100( 14.875 ), IN2MM100( 11 ) }, // 39 - US standard fanfold |
| { IN2MM100( 8.5 ), IN2MM100( 12 ) }, // 40 - German standard fanfold |
| { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 41 - German legal fanfold |
| { MM2MM100( 250 ), MM2MM100( 353 ) }, // 42 - ISO B4 |
| { MM2MM100( 200 ), MM2MM100( 148 ) }, // 43 - Japanese double postcard |
| { IN2MM100( 9 ), IN2MM100( 11 ) }, // 44 - Standard paper |
| { IN2MM100( 10 ), IN2MM100( 11 ) }, // 45 - Standard paper |
| { IN2MM100( 15 ), IN2MM100( 11 ) }, // 46 - Standard paper |
| { MM2MM100( 220 ), MM2MM100( 220 ) }, // 47 - Invite envelope |
| { 0, 0 }, // 48 - (undefined) |
| { 0, 0 }, // 49 - (undefined) |
| { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 50 - Letter extra paper |
| { IN2MM100( 9.275 ), IN2MM100( 15 ) }, // 51 - Legal extra paper |
| { IN2MM100( 11.69 ), IN2MM100( 18 ) }, // 52 - Tabloid extra paper |
| { MM2MM100( 236 ), MM2MM100( 322 ) }, // 53 - A4 extra paper |
| { IN2MM100( 8.275 ), IN2MM100( 11 ) }, // 54 - Letter transverse paper |
| { MM2MM100( 210 ), MM2MM100( 297 ) }, // 55 - A4 transverse paper |
| { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 56 - Letter extra transverse paper |
| { MM2MM100( 227 ), MM2MM100( 356 ) }, // 57 - SuperA/SuperA/A4 paper |
| { MM2MM100( 305 ), MM2MM100( 487 ) }, // 58 - SuperB/SuperB/A3 paper |
| { IN2MM100( 8.5 ), IN2MM100( 12.69 ) }, // 59 - Letter plus paper |
| { MM2MM100( 210 ), MM2MM100( 330 ) }, // 60 - A4 plus paper |
| { MM2MM100( 148 ), MM2MM100( 210 ) }, // 61 - A5 transverse paper |
| { MM2MM100( 182 ), MM2MM100( 257 ) }, // 62 - JIS B5 transverse paper |
| { MM2MM100( 322 ), MM2MM100( 445 ) }, // 63 - A3 extra paper |
| { MM2MM100( 174 ), MM2MM100( 235 ) }, // 64 - A5 extra paper |
| { MM2MM100( 201 ), MM2MM100( 276 ) }, // 65 - ISO B5 extra paper |
| { MM2MM100( 420 ), MM2MM100( 594 ) }, // 66 - A2 paper |
| { MM2MM100( 297 ), MM2MM100( 420 ) }, // 67 - A3 transverse paper |
| { MM2MM100( 322 ), MM2MM100( 445 ) } // 68 - A3 extra transverse paper |
| }; |
| |
| } // namespace |
| |
| // ---------------------------------------------------------------------------- |
| |
| PageSettingsConverter::HFHelperData::HFHelperData( sal_Int32 nLeftPropId, sal_Int32 nRightPropId ) : |
| mnLeftPropId( nLeftPropId ), |
| mnRightPropId( nRightPropId ), |
| mnHeight( 0 ), |
| mnBodyDist( 0 ), |
| mbHasContent( false ), |
| mbShareOddEven( false ), |
| mbDynamicHeight( false ) |
| { |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| PageSettingsConverter::PageSettingsConverter( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ), |
| mxHFParser( new HeaderFooterParser( rHelper ) ), |
| maHeaderData( PROP_LeftPageHeaderContent, PROP_RightPageHeaderContent ), |
| maFooterData( PROP_LeftPageFooterContent, PROP_RightPageFooterContent ) |
| { |
| } |
| |
| PageSettingsConverter::~PageSettingsConverter() |
| { |
| } |
| |
| void PageSettingsConverter::writePageSettingsProperties( |
| PropertySet& rPropSet, const PageSettingsModel& rModel, WorksheetType eSheetType ) |
| { |
| // special handling for chart sheets |
| bool bChartSheet = eSheetType == SHEETTYPE_CHARTSHEET; |
| |
| // printout scaling |
| if( bChartSheet ) |
| { |
| // always fit chart sheet to 1 page |
| rPropSet.setProperty< sal_Int16 >( PROP_ScaleToPages, 1 ); |
| } |
| else if( rModel.mbFitToPages ) |
| { |
| // fit to number of pages |
| rPropSet.setProperty( PROP_ScaleToPagesX, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToWidth, 0, 1000 ) ); |
| rPropSet.setProperty( PROP_ScaleToPagesY, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToHeight, 0, 1000 ) ); |
| } |
| else |
| { |
| // scale may be 0 which indicates uninitialized |
| sal_Int16 nScale = (rModel.mbValidSettings && (rModel.mnScale > 0)) ? getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnScale, 10, 400 ) : 100; |
| rPropSet.setProperty( PROP_PageScale, nScale ); |
| } |
| |
| // paper orientation |
| bool bLandscape = rModel.mnOrientation == XML_landscape; |
| // default orientation for current sheet type (chart sheets default to landscape) |
| if( !rModel.mbValidSettings || (rModel.mnOrientation == XML_default) ) |
| bLandscape = bChartSheet; |
| |
| // paper size |
| if( rModel.mbValidSettings && (0 < rModel.mnPaperSize) && (rModel.mnPaperSize < static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( spPaperSizeTable ) )) ) |
| { |
| const ApiPaperSize& rPaperSize = spPaperSizeTable[ rModel.mnPaperSize ]; |
| Size aSize( rPaperSize.mnWidth, rPaperSize.mnHeight ); |
| if( bLandscape ) |
| ::std::swap( aSize.Width, aSize.Height ); |
| rPropSet.setProperty( PROP_Size, aSize ); |
| } |
| |
| // header/footer |
| convertHeaderFooterData( rPropSet, maHeaderData, rModel.maOddHeader, rModel.maEvenHeader, rModel.mbUseEvenHF, rModel.mfTopMargin, rModel.mfHeaderMargin ); |
| convertHeaderFooterData( rPropSet, maFooterData, rModel.maOddFooter, rModel.maEvenFooter, rModel.mbUseEvenHF, rModel.mfBottomMargin, rModel.mfFooterMargin ); |
| |
| // write all properties to property set |
| const UnitConverter& rUnitConv = getUnitConverter(); |
| PropertyMap aPropMap; |
| aPropMap[ PROP_IsLandscape ] <<= bLandscape; |
| aPropMap[ PROP_FirstPageNumber ] <<= getLimitedValue< sal_Int16, sal_Int32 >( rModel.mbUseFirstPage ? rModel.mnFirstPage : 0, 0, 9999 ); |
| aPropMap[ PROP_PrintDownFirst ] <<= (rModel.mnPageOrder == XML_downThenOver); |
| aPropMap[ PROP_PrintAnnotations ] <<= (rModel.mnCellComments == XML_asDisplayed); |
| aPropMap[ PROP_CenterHorizontally ] <<= rModel.mbHorCenter; |
| aPropMap[ PROP_CenterVertically ] <<= rModel.mbVerCenter; |
| aPropMap[ PROP_PrintGrid ] <<= (!bChartSheet && rModel.mbPrintGrid); // no gridlines in chart sheets |
| aPropMap[ PROP_PrintHeaders ] <<= (!bChartSheet && rModel.mbPrintHeadings); // no column/row headings in chart sheets |
| aPropMap[ PROP_LeftMargin ] <<= rUnitConv.scaleToMm100( rModel.mfLeftMargin, UNIT_INCH ); |
| aPropMap[ PROP_RightMargin ] <<= rUnitConv.scaleToMm100( rModel.mfRightMargin, UNIT_INCH ); |
| // #i23296# In Calc, "TopMargin" property is distance to top of header if enabled |
| aPropMap[ PROP_TopMargin ] <<= rUnitConv.scaleToMm100( maHeaderData.mbHasContent ? rModel.mfHeaderMargin : rModel.mfTopMargin, UNIT_INCH ); |
| // #i23296# In Calc, "BottomMargin" property is distance to bottom of footer if enabled |
| aPropMap[ PROP_BottomMargin ] <<= rUnitConv.scaleToMm100( maFooterData.mbHasContent ? rModel.mfFooterMargin : rModel.mfBottomMargin, UNIT_INCH ); |
| aPropMap[ PROP_HeaderIsOn ] <<= maHeaderData.mbHasContent; |
| aPropMap[ PROP_HeaderIsShared ] <<= maHeaderData.mbShareOddEven; |
| aPropMap[ PROP_HeaderIsDynamicHeight ] <<= maHeaderData.mbDynamicHeight; |
| aPropMap[ PROP_HeaderHeight ] <<= maHeaderData.mnHeight; |
| aPropMap[ PROP_HeaderBodyDistance ] <<= maHeaderData.mnBodyDist; |
| aPropMap[ PROP_FooterIsOn ] <<= maFooterData.mbHasContent; |
| aPropMap[ PROP_FooterIsShared ] <<= maFooterData.mbShareOddEven; |
| aPropMap[ PROP_FooterIsDynamicHeight ] <<= maFooterData.mbDynamicHeight; |
| aPropMap[ PROP_FooterHeight ] <<= maFooterData.mnHeight; |
| aPropMap[ PROP_FooterBodyDistance ] <<= maFooterData.mnBodyDist; |
| // background image |
| if( rModel.maGraphicUrl.getLength() > 0 ) |
| { |
| aPropMap[ PROP_BackGraphicURL ] <<= rModel.maGraphicUrl; |
| aPropMap[ PROP_BackGraphicLocation ] <<= ::com::sun::star::style::GraphicLocation_TILED; |
| } |
| |
| rPropSet.setProperties( aPropMap ); |
| } |
| |
| void PageSettingsConverter::convertHeaderFooterData( |
| PropertySet& rPropSet, HFHelperData& orHFData, |
| const OUString rOddContent, const OUString rEvenContent, bool bUseEvenContent, |
| double fPageMargin, double fContentMargin ) |
| { |
| bool bHasOddContent = rOddContent.getLength() > 0; |
| bool bHasEvenContent = bUseEvenContent && (rEvenContent.getLength() > 0); |
| |
| sal_Int32 nOddHeight = bHasOddContent ? writeHeaderFooter( rPropSet, orHFData.mnRightPropId, rOddContent ) : 0; |
| sal_Int32 nEvenHeight = bHasEvenContent ? writeHeaderFooter( rPropSet, orHFData.mnLeftPropId, rEvenContent ) : 0; |
| |
| orHFData.mnHeight = 750; |
| orHFData.mnBodyDist = 250; |
| orHFData.mbHasContent = bHasOddContent || bHasEvenContent; |
| orHFData.mbShareOddEven = !bUseEvenContent; |
| orHFData.mbDynamicHeight = true; |
| |
| if( orHFData.mbHasContent ) |
| { |
| // use maximum height of odd/even header/footer |
| orHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight ); |
| /* Calc contains distance between bottom of header and top of page |
| body in "HeaderBodyDistance" property, and distance between bottom |
| of page body and top of footer in "FooterBodyDistance" property */ |
| orHFData.mnBodyDist = getUnitConverter().scaleToMm100( fPageMargin - fContentMargin, UNIT_INCH ) - orHFData.mnHeight; |
| /* #i23296# Distance less than 0 means, header or footer overlays page |
| body. As this is not possible in Calc, set fixed header or footer |
| height (crop header/footer) to get correct top position of page body. */ |
| orHFData.mbDynamicHeight = orHFData.mnBodyDist >= 0; |
| /* "HeaderHeight" property is in fact distance from top of header to |
| top of page body (including "HeaderBodyDistance"). |
| "FooterHeight" property is in fact distance from bottom of page |
| body to bottom of footer (including "FooterBodyDistance"). */ |
| orHFData.mnHeight += orHFData.mnBodyDist; |
| // negative body distance not allowed |
| orHFData.mnBodyDist = ::std::max< sal_Int32 >( orHFData.mnBodyDist, 0 ); |
| } |
| } |
| |
| sal_Int32 PageSettingsConverter::writeHeaderFooter( |
| PropertySet& rPropSet, sal_Int32 nPropId, const OUString& rContent ) |
| { |
| OSL_ENSURE( rContent.getLength() > 0, "PageSettingsConverter::writeHeaderFooter - empty h/f string found" ); |
| sal_Int32 nHeight = 0; |
| if( rContent.getLength() > 0 ) |
| { |
| Reference< XHeaderFooterContent > xHFContent( rPropSet.getAnyProperty( nPropId ), UNO_QUERY ); |
| if( xHFContent.is() ) |
| { |
| double fTotalHeight = mxHFParser->parse( xHFContent, rContent ); |
| rPropSet.setProperty( nPropId, xHFContent ); |
| nHeight = getUnitConverter().scaleToMm100( fTotalHeight, UNIT_POINT ); |
| } |
| } |
| return nHeight; |
| } |
| |
| // ============================================================================ |
| |
| } // namespace xls |
| } // namespace oox |