LCOV - code coverage report
Current view: top level - sc/source/filter/oox - pagesettings.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 300 486 61.7 %
Date: 2014-11-03 Functions: 39 52 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "pagesettings.hxx"
      21             : 
      22             : #include <algorithm>
      23             : #include <set>
      24             : #include <com/sun/star/awt/Size.hpp>
      25             : #include <com/sun/star/container/XNamed.hpp>
      26             : #include <com/sun/star/sheet/XHeaderFooterContent.hpp>
      27             : #include <com/sun/star/style/GraphicLocation.hpp>
      28             : #include <com/sun/star/text/FilenameDisplayFormat.hpp>
      29             : #include <com/sun/star/text/XText.hpp>
      30             : #include <com/sun/star/text/XTextContent.hpp>
      31             : #include <com/sun/star/text/XTextCursor.hpp>
      32             : #include <rtl/strbuf.hxx>
      33             : #include <rtl/ustrbuf.hxx>
      34             : #include <sax/tools/converter.hxx>
      35             : #include <oox/core/xmlfilterbase.hxx>
      36             : #include <oox/helper/attributelist.hxx>
      37             : #include <oox/helper/graphichelper.hxx>
      38             : #include <oox/helper/propertymap.hxx>
      39             : #include <oox/helper/propertyset.hxx>
      40             : #include "biffinputstream.hxx"
      41             : #include "excelhandlers.hxx"
      42             : #include "stylesbuffer.hxx"
      43             : #include "unitconverter.hxx"
      44             : #include "document.hxx"
      45             : #include <filter/msfilter/util.hxx>
      46             : 
      47             : namespace oox {
      48             : namespace xls {
      49             : 
      50             : using namespace ::com::sun::star;
      51             : using namespace ::com::sun::star::lang;
      52             : using namespace ::com::sun::star::uno;
      53             : 
      54             : using ::oox::core::Relations;
      55             : 
      56             : namespace {
      57             : 
      58             : const double OOX_MARGIN_DEFAULT_LR                  = 0.748;    /// Left/right default margin in inches.
      59             : const double OOX_MARGIN_DEFAULT_TB                  = 0.984;    /// Top/bottom default margin in inches.
      60             : const double OOX_MARGIN_DEFAULT_HF                  = 0.512;    /// Header/footer default margin in inches.
      61             : 
      62             : const sal_uInt16 BIFF12_PRINTOPT_HORCENTER          = 0x0001;
      63             : const sal_uInt16 BIFF12_PRINTOPT_VERCENTER          = 0x0002;
      64             : const sal_uInt16 BIFF12_PRINTOPT_PRINTHEADING       = 0x0004;
      65             : const sal_uInt16 BIFF12_PRINTOPT_PRINTGRID          = 0x0008;
      66             : 
      67             : const sal_uInt16 BIFF12_HEADERFOOTER_DIFFEVEN       = 0x0001;
      68             : const sal_uInt16 BIFF12_HEADERFOOTER_DIFFFIRST      = 0x0002;
      69             : 
      70             : const sal_uInt16 BIFF12_PAGESETUP_INROWS            = 0x0001;
      71             : const sal_uInt16 BIFF12_PAGESETUP_LANDSCAPE         = 0x0002;
      72             : const sal_uInt16 BIFF12_PAGESETUP_INVALID           = 0x0004;
      73             : const sal_uInt16 BIFF12_PAGESETUP_BLACKWHITE        = 0x0008;
      74             : const sal_uInt16 BIFF12_PAGESETUP_DRAFTQUALITY      = 0x0010;
      75             : const sal_uInt16 BIFF12_PAGESETUP_PRINTNOTES        = 0x0020;
      76             : const sal_uInt16 BIFF12_PAGESETUP_DEFAULTORIENT     = 0x0040;
      77             : const sal_uInt16 BIFF12_PAGESETUP_USEFIRSTPAGE      = 0x0080;
      78             : const sal_uInt16 BIFF12_PAGESETUP_NOTES_END         = 0x0100;   // different to BIFF flag
      79             : 
      80             : const sal_uInt16 BIFF12_CHARTPAGESETUP_LANDSCAPE    = 0x0001;
      81             : const sal_uInt16 BIFF12_CHARTPAGESETUP_INVALID      = 0x0002;
      82             : const sal_uInt16 BIFF12_CHARTPAGESETUP_BLACKWHITE   = 0x0004;
      83             : const sal_uInt16 BIFF12_CHARTPAGESETUP_DEFAULTORIENT= 0x0008;
      84             : const sal_uInt16 BIFF12_CHARTPAGESETUP_USEFIRSTPAGE = 0x0010;
      85             : const sal_uInt16 BIFF12_CHARTPAGESETUP_DRAFTQUALITY = 0x0020;
      86             : 
      87             : } // namespace
      88             : 
      89         260 : PageSettingsModel::PageSettingsModel() :
      90             :     mfLeftMargin( OOX_MARGIN_DEFAULT_LR ),
      91             :     mfRightMargin( OOX_MARGIN_DEFAULT_LR ),
      92             :     mfTopMargin( OOX_MARGIN_DEFAULT_TB ),
      93             :     mfBottomMargin( OOX_MARGIN_DEFAULT_TB ),
      94             :     mfHeaderMargin( OOX_MARGIN_DEFAULT_HF ),
      95             :     mfFooterMargin( OOX_MARGIN_DEFAULT_HF ),
      96             :     mnPaperSize( 1 ),
      97             :     mnPaperWidth( 0 ),
      98             :     mnPaperHeight( 0 ),
      99             :     mnCopies( 1 ),
     100             :     mnScale( 100 ),
     101             :     mnFirstPage( 1 ),
     102             :     mnFitToWidth( 1 ),
     103             :     mnFitToHeight( 1 ),
     104             :     mnHorPrintRes( 600 ),
     105             :     mnVerPrintRes( 600 ),
     106             :     mnOrientation( XML_default ),
     107             :     mnPageOrder( XML_downThenOver ),
     108             :     mnCellComments( XML_none ),
     109             :     mnPrintErrors( XML_displayed ),
     110             :     mbUseEvenHF( false ),
     111             :     mbUseFirstHF( false ),
     112             :     mbValidSettings( true ),
     113             :     mbUseFirstPage( false ),
     114             :     mbBlackWhite( false ),
     115             :     mbDraftQuality( false ),
     116             :     mbFitToPages( false ),
     117             :     mbHorCenter( false ),
     118             :     mbVerCenter( false ),
     119             :     mbPrintGrid( false ),
     120         260 :     mbPrintHeadings( false )
     121             : {
     122         260 : }
     123             : 
     124           0 : void PageSettingsModel::setBiffPrintErrors( sal_uInt8 nPrintErrors )
     125             : {
     126             :     static const sal_Int32 spnErrorIds[] = { XML_displayed, XML_none, XML_dash, XML_NA };
     127           0 :     mnPrintErrors = STATIC_ARRAY_SELECT( spnErrorIds, nPrintErrors, XML_none );
     128           0 : }
     129             : 
     130         260 : PageSettings::PageSettings( const WorksheetHelper& rHelper ) :
     131         260 :     WorksheetHelper( rHelper )
     132             : {
     133         260 : }
     134             : 
     135         116 : void PageSettings::importPrintOptions( const AttributeList& rAttribs )
     136             : {
     137         116 :     maModel.mbHorCenter     = rAttribs.getBool( XML_horizontalCentered, false );
     138         116 :     maModel.mbVerCenter     = rAttribs.getBool( XML_verticalCentered, false );
     139         116 :     maModel.mbPrintGrid     = rAttribs.getBool( XML_gridLines, false );
     140         116 :     maModel.mbPrintHeadings = rAttribs.getBool( XML_headings, false );
     141         116 : }
     142             : 
     143         260 : void PageSettings::importPageMargins( const AttributeList& rAttribs )
     144             : {
     145         260 :     maModel.mfLeftMargin   = rAttribs.getDouble( XML_left,   OOX_MARGIN_DEFAULT_LR );
     146         260 :     maModel.mfRightMargin  = rAttribs.getDouble( XML_right,  OOX_MARGIN_DEFAULT_LR );
     147         260 :     maModel.mfTopMargin    = rAttribs.getDouble( XML_top,    OOX_MARGIN_DEFAULT_TB );
     148         260 :     maModel.mfBottomMargin = rAttribs.getDouble( XML_bottom, OOX_MARGIN_DEFAULT_TB );
     149         260 :     maModel.mfHeaderMargin = rAttribs.getDouble( XML_header, OOX_MARGIN_DEFAULT_HF );
     150         260 :     maModel.mfFooterMargin = rAttribs.getDouble( XML_footer, OOX_MARGIN_DEFAULT_HF );
     151         260 : }
     152             : 
     153         152 : void PageSettings::importPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
     154             : {
     155         152 :     OUString aStr;
     156         152 :     maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
     157         152 :     maModel.mnPaperSize     = rAttribs.getInteger( XML_paperSize, 1 );
     158         152 :     aStr                    = rAttribs.getString ( XML_paperWidth, OUString() );
     159             :     ::sax::Converter::convertMeasure(
     160         152 :             maModel.mnPaperWidth, aStr, util::MeasureUnit::MM_100TH);
     161         152 :     aStr                    = rAttribs.getString ( XML_paperHeight, OUString() );
     162             :     ::sax::Converter::convertMeasure(
     163         152 :             maModel.mnPaperHeight, aStr, util::MeasureUnit::MM_100TH );
     164         152 :     maModel.mnCopies        = rAttribs.getInteger( XML_copies, 1 );
     165         152 :     maModel.mnScale         = rAttribs.getInteger( XML_scale, 100 );
     166         152 :     maModel.mnFirstPage     = rAttribs.getInteger( XML_firstPageNumber, 1 );
     167         152 :     maModel.mnFitToWidth    = rAttribs.getInteger( XML_fitToWidth, 1 );
     168         152 :     maModel.mnFitToHeight   = rAttribs.getInteger( XML_fitToHeight, 1 );
     169         152 :     maModel.mnHorPrintRes   = rAttribs.getInteger( XML_horizontalDpi, 600 );
     170         152 :     maModel.mnVerPrintRes   = rAttribs.getInteger( XML_verticalDpi, 600 );
     171         152 :     maModel.mnOrientation   = rAttribs.getToken( XML_orientation, XML_default );
     172         152 :     maModel.mnPageOrder     = rAttribs.getToken( XML_pageOrder, XML_downThenOver );
     173         152 :     maModel.mnCellComments  = rAttribs.getToken( XML_cellComments, XML_none );
     174         152 :     maModel.mnPrintErrors   = rAttribs.getToken( XML_errors, XML_displayed );
     175         152 :     maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, false );
     176         152 :     maModel.mbUseFirstPage  = rAttribs.getBool( XML_useFirstPageNumber, false );
     177         152 :     maModel.mbBlackWhite    = rAttribs.getBool( XML_blackAndWhite, false );
     178         152 :     maModel.mbDraftQuality  = rAttribs.getBool( XML_draft, false );
     179         152 : }
     180             : 
     181           0 : void PageSettings::importChartPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
     182             : {
     183           0 :     OUString aStr;
     184           0 :     maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
     185           0 :     maModel.mnPaperSize     = rAttribs.getInteger( XML_paperSize, 1 );
     186           0 :     aStr                    = rAttribs.getString ( XML_paperWidth, OUString() );
     187             :     ::sax::Converter::convertMeasure(
     188           0 :             maModel.mnPaperWidth, aStr, util::MeasureUnit::MM_100TH );
     189           0 :     aStr                    = rAttribs.getString ( XML_paperHeight, OUString() );
     190             :     ::sax::Converter::convertMeasure(
     191           0 :             maModel.mnPaperHeight, aStr, util::MeasureUnit::MM_100TH );
     192           0 :     maModel.mnCopies        = rAttribs.getInteger( XML_copies, 1 );
     193           0 :     maModel.mnFirstPage     = rAttribs.getInteger( XML_firstPageNumber, 1 );
     194           0 :     maModel.mnHorPrintRes   = rAttribs.getInteger( XML_horizontalDpi, 600 );
     195           0 :     maModel.mnVerPrintRes   = rAttribs.getInteger( XML_verticalDpi, 600 );
     196           0 :     maModel.mnOrientation   = rAttribs.getToken( XML_orientation, XML_default );
     197           0 :     maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, false );
     198           0 :     maModel.mbUseFirstPage  = rAttribs.getBool( XML_useFirstPageNumber, false );
     199           0 :     maModel.mbBlackWhite    = rAttribs.getBool( XML_blackAndWhite, false );
     200           0 :     maModel.mbDraftQuality  = rAttribs.getBool( XML_draft, false );
     201           0 : }
     202             : 
     203         148 : void PageSettings::importHeaderFooter( const AttributeList& rAttribs )
     204             : {
     205         148 :     maModel.mbUseEvenHF  = rAttribs.getBool( XML_differentOddEven, false );
     206         148 :     maModel.mbUseFirstHF = rAttribs.getBool( XML_differentFirst, false );
     207         148 : }
     208             : 
     209         132 : void PageSettings::importHeaderFooterCharacters( const OUString& rChars, sal_Int32 nElement )
     210             : {
     211         132 :     switch( nElement )
     212             :     {
     213          66 :         case XLS_TOKEN( oddHeader ):    maModel.maOddHeader += rChars;      break;
     214          66 :         case XLS_TOKEN( oddFooter ):    maModel.maOddFooter += rChars;      break;
     215           0 :         case XLS_TOKEN( evenHeader ):   maModel.maEvenHeader += rChars;     break;
     216           0 :         case XLS_TOKEN( evenFooter ):   maModel.maEvenFooter += rChars;     break;
     217           0 :         case XLS_TOKEN( firstHeader ):  maModel.maFirstHeader += rChars;    break;
     218           0 :         case XLS_TOKEN( firstFooter ):  maModel.maFirstFooter += rChars;    break;
     219             :     }
     220         132 : }
     221             : 
     222           0 : void PageSettings::importPicture( const Relations& rRelations, const AttributeList& rAttribs )
     223             : {
     224           0 :     importPictureData( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
     225           0 : }
     226             : 
     227           0 : void PageSettings::importPageMargins( SequenceInputStream& rStrm )
     228             : {
     229           0 :     rStrm   >> maModel.mfLeftMargin   >> maModel.mfRightMargin
     230           0 :             >> maModel.mfTopMargin    >> maModel.mfBottomMargin
     231           0 :             >> maModel.mfHeaderMargin >> maModel.mfFooterMargin;
     232           0 : }
     233             : 
     234           0 : void PageSettings::importPrintOptions( SequenceInputStream& rStrm )
     235             : {
     236             :     sal_uInt16 nFlags;
     237           0 :     rStrm >> nFlags;
     238           0 :     maModel.mbHorCenter     = getFlag( nFlags, BIFF12_PRINTOPT_HORCENTER );
     239           0 :     maModel.mbVerCenter     = getFlag( nFlags, BIFF12_PRINTOPT_VERCENTER );
     240           0 :     maModel.mbPrintGrid     = getFlag( nFlags, BIFF12_PRINTOPT_PRINTGRID );
     241           0 :     maModel.mbPrintHeadings = getFlag( nFlags, BIFF12_PRINTOPT_PRINTHEADING );
     242           0 : }
     243             : 
     244           0 : void PageSettings::importPageSetup( const Relations& rRelations, SequenceInputStream& rStrm )
     245             : {
     246           0 :     OUString aRelId;
     247             :     sal_uInt16 nFlags;
     248           0 :     rStrm   >> maModel.mnPaperSize >> maModel.mnScale
     249           0 :             >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
     250           0 :             >> maModel.mnCopies >> maModel.mnFirstPage
     251           0 :             >> maModel.mnFitToWidth >> maModel.mnFitToHeight
     252           0 :             >> nFlags >> aRelId;
     253           0 :     maModel.setBiffPrintErrors( extractValue< sal_uInt8 >( nFlags, 9, 2 ) );
     254           0 :     maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( aRelId );
     255           0 :     maModel.mnOrientation   = getFlagValue( nFlags, BIFF12_PAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_PAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
     256           0 :     maModel.mnPageOrder     = getFlagValue( nFlags, BIFF12_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
     257           0 :     maModel.mnCellComments  = getFlagValue( nFlags, BIFF12_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF12_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
     258           0 :     maModel.mbValidSettings = !getFlag( nFlags, BIFF12_PAGESETUP_INVALID );
     259           0 :     maModel.mbUseFirstPage  = getFlag( nFlags, BIFF12_PAGESETUP_USEFIRSTPAGE );
     260           0 :     maModel.mbBlackWhite    = getFlag( nFlags, BIFF12_PAGESETUP_BLACKWHITE );
     261           0 :     maModel.mbDraftQuality  = getFlag( nFlags, BIFF12_PAGESETUP_DRAFTQUALITY );
     262           0 : }
     263             : 
     264           0 : void PageSettings::importChartPageSetup( const Relations& rRelations, SequenceInputStream& rStrm )
     265             : {
     266           0 :     OUString aRelId;
     267             :     sal_uInt16 nFirstPage, nFlags;
     268           0 :     rStrm   >> maModel.mnPaperSize >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
     269           0 :             >> maModel.mnCopies >> nFirstPage >> nFlags >> aRelId;
     270           0 :     maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( aRelId );
     271           0 :     maModel.mnFirstPage     = nFirstPage; // 16-bit in CHARTPAGESETUP
     272           0 :     maModel.mnOrientation   = getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
     273           0 :     maModel.mbValidSettings = !getFlag( nFlags, BIFF12_CHARTPAGESETUP_INVALID );
     274           0 :     maModel.mbUseFirstPage  = getFlag( nFlags, BIFF12_CHARTPAGESETUP_USEFIRSTPAGE );
     275           0 :     maModel.mbBlackWhite    = getFlag( nFlags, BIFF12_CHARTPAGESETUP_BLACKWHITE );
     276           0 :     maModel.mbDraftQuality  = getFlag( nFlags, BIFF12_CHARTPAGESETUP_DRAFTQUALITY );
     277           0 : }
     278             : 
     279           0 : void PageSettings::importHeaderFooter( SequenceInputStream& rStrm )
     280             : {
     281             :     sal_uInt16 nFlags;
     282           0 :     rStrm   >> nFlags
     283           0 :             >> maModel.maOddHeader   >> maModel.maOddFooter
     284           0 :             >> maModel.maEvenHeader  >> maModel.maEvenFooter
     285           0 :             >> maModel.maFirstHeader >> maModel.maFirstFooter;
     286           0 :     maModel.mbUseEvenHF  = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFEVEN );
     287           0 :     maModel.mbUseFirstHF = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFFIRST );
     288           0 : }
     289             : 
     290           0 : void PageSettings::importPicture( const Relations& rRelations, SequenceInputStream& rStrm )
     291             : {
     292           0 :     importPictureData( rRelations, BiffHelper::readString( rStrm ) );
     293           0 : }
     294             : 
     295         114 : void PageSettings::setFitToPagesMode( bool bFitToPages )
     296             : {
     297         114 :     maModel.mbFitToPages = bFitToPages;
     298         114 : }
     299             : 
     300         260 : void PageSettings::finalizeImport()
     301             : {
     302         260 :     OUStringBuffer aStyleNameBuffer( "PageStyle_" );
     303         520 :     Reference<container::XNamed> xSheetName(getSheet(), UNO_QUERY);
     304         260 :     if( xSheetName.is() )
     305         260 :         aStyleNameBuffer.append( xSheetName->getName() );
     306             :     else
     307           0 :         aStyleNameBuffer.append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) );
     308         520 :     OUString aStyleName = aStyleNameBuffer.makeStringAndClear();
     309             : 
     310         520 :     Reference<style::XStyle> xStyle = createStyleObject(aStyleName, true);
     311         520 :     PropertySet aStyleProps( xStyle );
     312         260 :     getPageSettingsConverter().writePageSettingsProperties( aStyleProps, maModel, getSheetType() );
     313             : 
     314             :     // Set page style name to the sheet.
     315         260 :     SCTAB nTab = getSheetIndex();
     316         520 :     getScDocument().SetPageStyle(nTab, aStyleName);
     317         260 : }
     318             : 
     319           0 : void PageSettings::importPictureData( const Relations& rRelations, const OUString& rRelId )
     320             : {
     321           0 :     OUString aPicturePath = rRelations.getFragmentPathFromRelId( rRelId );
     322           0 :     if( !aPicturePath.isEmpty() )
     323           0 :         maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importEmbeddedGraphicObject( aPicturePath );
     324           0 : }
     325             : 
     326             : enum HFPortionId
     327             : {
     328             :     HF_LEFT,
     329             :     HF_CENTER,
     330             :     HF_RIGHT,
     331             :     HF_COUNT
     332             : };
     333             : 
     334         768 : struct HFPortionInfo
     335             : {
     336             :     Reference<text::XText>  mxText;                 /// XText interface of this portion.
     337             :     Reference<text::XTextCursor> mxStart;           /// Start position of current text range for formatting.
     338             :     Reference<text::XTextCursor> mxEnd;             /// End position of current text range for formatting.
     339             :     double              mfTotalHeight;          /// Sum of heights of previous lines in points.
     340             :     double              mfCurrHeight;           /// Height of the current text line in points.
     341             : 
     342             :     bool                initialize( const Reference<text::XText>& rxText );
     343             : };
     344             : 
     345         396 : bool HFPortionInfo::initialize( const Reference<text::XText>& rxText )
     346             : {
     347         396 :     mfTotalHeight = mfCurrHeight = 0.0;
     348         396 :     mxText = rxText;
     349         396 :     if( mxText.is() )
     350             :     {
     351         396 :         mxStart = mxText->createTextCursor();
     352         396 :         mxEnd = mxText->createTextCursor();
     353             :     }
     354         396 :     bool bRet = mxText.is() && mxStart.is() && mxEnd.is();
     355             :     OSL_ENSURE( bRet, "HFPortionInfo::initialize - missing interfaces" );
     356         396 :     return bRet;
     357             : }
     358             : 
     359         256 : class HeaderFooterParser : public WorkbookHelper
     360             : {
     361             : public:
     362             :     explicit            HeaderFooterParser( const WorkbookHelper& rHelper );
     363             : 
     364             :     /** Parses the passed string and creates the header/footer contents.
     365             :         @returns  The total height of the converted header or footer in points. */
     366             :     double              parse(
     367             :                             const Reference<sheet::XHeaderFooterContent>& rxContext,
     368             :                             const OUString& rData );
     369             : 
     370             : private:
     371             :     /** Returns the current edit engine text object. */
     372        1836 :     inline HFPortionInfo& getPortion() { return maPortions[ meCurrPortion ]; }
     373             :     /** Returns the start cursor of the current text range. */
     374         360 :     inline const Reference<text::XTextCursor>& getStartPos() { return getPortion().mxStart; }
     375             :     /** Returns the end cursor of the current text range. */
     376        1344 :     inline const Reference<text::XTextCursor>& getEndPos() { return getPortion().mxEnd; }
     377             : 
     378             :     /** Returns the current line height of the specified portion. */
     379             :     double              getCurrHeight( HFPortionId ePortion ) const;
     380             :     /** Returns the current line height. */
     381             :     double              getCurrHeight() const;
     382             : 
     383             :     /** Updates the current line height of the specified portion, using the current font size. */
     384             :     void                updateCurrHeight( HFPortionId ePortion );
     385             :     /** Updates the current line height, using the current font size. */
     386             :     void                updateCurrHeight();
     387             : 
     388             :     /** Sets the font attributes at the current selection. */
     389             :     void                setAttributes();
     390             :     /** Appends and clears internal string buffer. */
     391             :     void                appendText();
     392             :     /** Appends a line break and adjusts internal text height data. */
     393             :     void                appendLineBreak();
     394             : 
     395             :     /** Creates a text field from the passed service name. */
     396             :     Reference<text::XTextContent> createField( const OUString& rServiceName ) const;
     397             :     /** Appends the passed text field. */
     398             :     void                appendField( const Reference<text::XTextContent>& rxContent );
     399             : 
     400             :     /** Sets the passed font name if it is valid. */
     401             :     void                convertFontName( const OUString& rStyle );
     402             :     /** Converts a font style given as string. */
     403             :     void                convertFontStyle( const OUString& rStyle );
     404             :     /** Converts a font color given as string. */
     405             :     void                convertFontColor( const OUString& rColor );
     406             : 
     407             :     /** Finalizes current portion: sets font attributes and updates text height data. */
     408             :     void                finalizePortion();
     409             :     /** Changes current header/footer portion. */
     410             :     void                setNewPortion( HFPortionId ePortion );
     411             : 
     412             : private:
     413             :     typedef ::std::vector< HFPortionInfo >  HFPortionInfoVec;
     414             :     typedef ::std::set< OString >           OStringSet;
     415             : 
     416             :     const OUString      maPageNumberService;
     417             :     const OUString      maPageCountService;
     418             :     const OUString      maSheetNameService;
     419             :     const OUString      maFileNameService;
     420             :     const OUString      maDateTimeService;
     421             :     const OStringSet    maBoldNames;            /// All names for bold font style in lowercase UTF-8.
     422             :     const OStringSet    maItalicNames;          /// All names for italic font style in lowercase UTF-8.
     423             :     HFPortionInfoVec    maPortions;
     424             :     HFPortionId         meCurrPortion;          /// Identifier of current H/F portion.
     425             :     OUStringBuffer      maBuffer;               /// Text data to append to current text range.
     426             :     FontModel           maFontModel;            /// Font attributes of current text range.
     427             : };
     428             : 
     429             : namespace {
     430             : 
     431             : // different names for bold font style (lowercase)
     432             : static const sal_Char* const sppcBoldNames[] =
     433             : {
     434             :     "bold",
     435             :     "fett",             // German 'bold'
     436             :     "demibold",
     437             :     "halbfett",         // German 'demibold'
     438             :     "black",
     439             :     "heavy"
     440             : };
     441             : 
     442             : // different names for italic font style (lowercase)
     443             : static const sal_Char* const sppcItalicNames[] =
     444             : {
     445             :     "italic",
     446             :     "kursiv",           // German 'italic'
     447             :     "oblique",
     448             :     "schr\303\204g",    // German 'oblique' with uppercase A umlaut
     449             :     "schr\303\244g"     // German 'oblique' with lowercase A umlaut
     450             : };
     451             : 
     452             : } // namespace
     453             : 
     454         128 : HeaderFooterParser::HeaderFooterParser( const WorkbookHelper& rHelper ) :
     455             :     WorkbookHelper( rHelper ),
     456             :     maPageNumberService( "com.sun.star.text.TextField.PageNumber" ),
     457             :     maPageCountService( "com.sun.star.text.TextField.PageCount" ),
     458             :     maSheetNameService( "com.sun.star.text.TextField.SheetName" ),
     459             :     maFileNameService( "com.sun.star.text.TextField.FileName" ),
     460             :     maDateTimeService( "com.sun.star.text.TextField.DateTime" ),
     461             :     maBoldNames( sppcBoldNames, STATIC_ARRAY_END( sppcBoldNames ) ),
     462             :     maItalicNames( sppcItalicNames, STATIC_ARRAY_END( sppcItalicNames ) ),
     463             :     maPortions( static_cast< size_t >( HF_COUNT ) ),
     464         128 :     meCurrPortion( HF_CENTER )
     465             : {
     466         128 : }
     467             : 
     468         132 : double HeaderFooterParser::parse( const Reference<sheet::XHeaderFooterContent>& rxContext, const OUString& rData )
     469             : {
     470         792 :     if( !rxContext.is() || rData.isEmpty() ||
     471         792 :             !maPortions[ HF_LEFT ].initialize( rxContext->getLeftText() ) ||
     472         924 :             !maPortions[ HF_CENTER ].initialize( rxContext->getCenterText() ) ||
     473         396 :             !maPortions[ HF_RIGHT ].initialize( rxContext->getRightText() ) )
     474           0 :         return 0.0;
     475             : 
     476         132 :     meCurrPortion = HF_CENTER;
     477         132 :     maBuffer.setLength( 0 );
     478         132 :     maFontModel = getStyles().getDefaultFontModel();
     479         132 :     OUStringBuffer aFontName;           // current font name
     480         264 :     OUStringBuffer aFontStyle;          // current font style
     481         132 :     sal_Int32 nFontHeight = 0;          // current font height
     482             : 
     483             :     /** State of the parser. */
     484             :     enum
     485             :     {
     486             :         STATE_TEXT,         /// Literal text data.
     487             :         STATE_TOKEN,        /// Control token following a '&' character.
     488             :         STATE_FONTNAME,     /// Font name ('&' is followed by '"', reads until next '"' or ',').
     489             :         STATE_FONTSTYLE,    /// Font style name (font part after ',', reads until next '"').
     490             :         STATE_FONTHEIGHT    /// Font height ('&' is followed by num. digits, reads until non-digit).
     491             :     }
     492         132 :     eState = STATE_TEXT;
     493             : 
     494         132 :     const sal_Unicode* pcChar = rData.getStr();
     495         132 :     const sal_Unicode* pcEnd = pcChar + rData.getLength();
     496        2430 :     for( ; (pcChar != pcEnd) && (*pcChar != 0); ++pcChar )
     497             :     {
     498        2298 :         sal_Unicode cChar = *pcChar;
     499        2298 :         switch( eState )
     500             :         {
     501             :             case STATE_TEXT:
     502             :             {
     503         690 :                 switch( cChar )
     504             :                 {
     505             :                     case '&':           // new token
     506         360 :                         appendText();
     507         360 :                         eState = STATE_TOKEN;
     508         360 :                     break;
     509             :                     case '\n':          // line break
     510           0 :                         appendText();
     511           0 :                         appendLineBreak();
     512           0 :                     break;
     513             :                     default:
     514         330 :                         maBuffer.append( cChar );
     515             :                 }
     516             :             }
     517         690 :             break;
     518             : 
     519             :             case STATE_TOKEN:
     520             :             {
     521             :                 // default: back to text mode, may be changed in specific cases
     522         360 :                 eState = STATE_TEXT;
     523             :                 // ignore case of token codes
     524         360 :                 if( ('a' <= cChar) && (cChar <= 'z') )
     525           0 :                     (cChar -= 'a') += 'A';
     526         360 :                 switch( cChar )
     527             :                 {
     528           0 :                     case '&':   maBuffer.append( cChar );   break;  // the '&' character
     529             : 
     530           0 :                     case 'L':   setNewPortion( HF_LEFT );   break;  // left portion
     531         132 :                     case 'C':   setNewPortion( HF_CENTER ); break;  // center portion
     532           0 :                     case 'R':   setNewPortion( HF_RIGHT );  break;  // right portion
     533             : 
     534             :                     case 'P':   // page number
     535          66 :                         appendField( createField( maPageNumberService ) );
     536          66 :                     break;
     537             :                     case 'N':   // total page count
     538           0 :                         appendField( createField( maPageCountService ) );
     539           0 :                     break;
     540             :                     case 'A':   // current sheet name
     541          66 :                         appendField( createField( maSheetNameService ) );
     542          66 :                     break;
     543             : 
     544             :                     case 'F':   // file name
     545             :                     {
     546           0 :                         Reference<text::XTextContent> xContent = createField( maFileNameService );
     547           0 :                         PropertySet aPropSet( xContent );
     548           0 :                         aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::NAME_AND_EXT );
     549           0 :                         appendField( xContent );
     550             :                     }
     551           0 :                     break;
     552             :                     case 'Z':   // file path (without file name), OOXML, BIFF12, and BIFF8 only
     553           0 :                         if( (getFilterType() == FILTER_OOXML) || ((getFilterType() == FILTER_BIFF) && (getBiff() == BIFF8)) )
     554             :                         {
     555           0 :                             Reference<text::XTextContent> xContent = createField( maFileNameService );
     556           0 :                             PropertySet aPropSet( xContent );
     557             :                             // FilenameDisplayFormat::PATH not supported by Calc
     558           0 :                             aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::FULL );
     559           0 :                             appendField( xContent );
     560             :                             /*  path only is not supported -- if we find a '&Z&F'
     561             :                                 combination for path/name, skip the '&F' part */
     562           0 :                             if( (pcChar + 2 < pcEnd) && (pcChar[ 1 ] == '&') && ((pcChar[ 2 ] == 'f') || (pcChar[ 2 ] == 'F')) )
     563           0 :                                 pcChar += 2;
     564             :                         }
     565           0 :                     break;
     566             :                     case 'D':   // date
     567             :                     {
     568           0 :                         Reference<text::XTextContent> xContent = createField( maDateTimeService );
     569           0 :                         PropertySet aPropSet( xContent );
     570           0 :                         aPropSet.setProperty( PROP_IsDate, true );
     571           0 :                         appendField( xContent );
     572             :                     }
     573           0 :                     break;
     574             :                     case 'T':   // time
     575             :                     {
     576           0 :                         Reference<text::XTextContent> xContent = createField( maDateTimeService );
     577           0 :                         PropertySet aPropSet( xContent );
     578           0 :                         aPropSet.setProperty( PROP_IsDate, false );
     579           0 :                         appendField( xContent );
     580             :                     }
     581           0 :                     break;
     582             : 
     583             :                     case 'B':   // bold
     584           0 :                         setAttributes();
     585           0 :                         maFontModel.mbBold = !maFontModel.mbBold;
     586           0 :                     break;
     587             :                     case 'I':   // italic
     588           0 :                         setAttributes();
     589           0 :                         maFontModel.mbItalic = !maFontModel.mbItalic;
     590           0 :                     break;
     591             :                     case 'U':   // underline
     592           0 :                         setAttributes();
     593           0 :                         maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_single) ? XML_none : XML_single;
     594           0 :                     break;
     595             :                     case 'E':   // double underline
     596           0 :                         setAttributes();
     597           0 :                         maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_double) ? XML_none : XML_double;
     598           0 :                     break;
     599             :                     case 'S':   // strikeout
     600           0 :                         setAttributes();
     601           0 :                         maFontModel.mbStrikeout = !maFontModel.mbStrikeout;
     602           0 :                     break;
     603             :                     case 'X':   // superscript
     604           0 :                         setAttributes();
     605           0 :                         maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_superscript) ? XML_baseline : XML_superscript;
     606           0 :                     break;
     607             :                     case 'Y':   // subsrcipt
     608           0 :                         setAttributes();
     609           0 :                         maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_subscript) ? XML_baseline : XML_subscript;
     610           0 :                     break;
     611             :                     case 'O':   // outlined
     612           0 :                         setAttributes();
     613           0 :                         maFontModel.mbOutline = !maFontModel.mbOutline;
     614           0 :                     break;
     615             :                     case 'H':   // shadow
     616           0 :                         setAttributes();
     617           0 :                         maFontModel.mbShadow = !maFontModel.mbShadow;
     618           0 :                     break;
     619             : 
     620             :                     case 'K':   // text color (not in BIFF)
     621           0 :                         if( (getFilterType() == FILTER_OOXML) && (pcChar + 6 < pcEnd) )
     622             :                         {
     623           0 :                             setAttributes();
     624             :                             // eat the following 6 characters
     625           0 :                             convertFontColor( OUString( pcChar + 1, 6 ) );
     626           0 :                             pcChar += 6;
     627             :                         }
     628           0 :                     break;
     629             : 
     630             :                     case '\"':  // font name
     631          48 :                         aFontName.setLength( 0 );
     632          48 :                         aFontStyle.setLength( 0 );
     633          48 :                         eState = STATE_FONTNAME;
     634          48 :                     break;
     635             :                     default:
     636          48 :                         if( ('0' <= cChar) && (cChar <= '9') )    // font size
     637             :                         {
     638          48 :                             nFontHeight = cChar - '0';
     639          48 :                             eState = STATE_FONTHEIGHT;
     640             :                         }
     641             :                 }
     642             :             }
     643         360 :             break;
     644             : 
     645             :             case STATE_FONTNAME:
     646             :             {
     647         768 :                 switch( cChar )
     648             :                 {
     649             :                     case '\"':
     650           0 :                         setAttributes();
     651           0 :                         convertFontName( aFontName.makeStringAndClear() );
     652           0 :                         eState = STATE_TEXT;
     653           0 :                     break;
     654             :                     case ',':
     655          48 :                         eState = STATE_FONTSTYLE;
     656          48 :                     break;
     657             :                     default:
     658         720 :                         aFontName.append( cChar );
     659             :                 }
     660             :             }
     661         768 :             break;
     662             : 
     663             :             case STATE_FONTSTYLE:
     664             :             {
     665         384 :                 switch( cChar )
     666             :                 {
     667             :                     case '\"':
     668          48 :                         setAttributes();
     669          48 :                         convertFontName( aFontName.makeStringAndClear() );
     670          48 :                         convertFontStyle( aFontStyle.makeStringAndClear() );
     671          48 :                         eState = STATE_TEXT;
     672          48 :                     break;
     673             :                     default:
     674         336 :                         aFontStyle.append( cChar );
     675             :                 }
     676             :             }
     677         384 :             break;
     678             : 
     679             :             case STATE_FONTHEIGHT:
     680             :             {
     681          96 :                 if( ('0' <= cChar) && (cChar <= '9') )
     682             :                 {
     683          96 :                     if( nFontHeight >= 0 )
     684             :                     {
     685          48 :                         nFontHeight *= 10;
     686          48 :                         nFontHeight += (cChar - '0');
     687          48 :                         if( nFontHeight > 1000 )
     688           0 :                             nFontHeight = -1;
     689             :                     }
     690             :                 }
     691             :                 else
     692             :                 {
     693          48 :                     if( nFontHeight > 0 )
     694             :                     {
     695          48 :                         setAttributes();
     696          48 :                         maFontModel.mfHeight = nFontHeight;
     697             :                     }
     698          48 :                     --pcChar;
     699          48 :                     eState = STATE_TEXT;
     700             :                 }
     701             :             }
     702          96 :             break;
     703             :         }
     704             :     }
     705             : 
     706             :     // finalize
     707         132 :     finalizePortion();
     708         132 :     maPortions[ HF_LEFT   ].mfTotalHeight += getCurrHeight( HF_LEFT );
     709         132 :     maPortions[ HF_CENTER ].mfTotalHeight += getCurrHeight( HF_CENTER );
     710         132 :     maPortions[ HF_RIGHT  ].mfTotalHeight += getCurrHeight( HF_RIGHT );
     711             : 
     712         132 :     return ::std::max( maPortions[ HF_LEFT ].mfTotalHeight,
     713         396 :         ::std::max( maPortions[ HF_CENTER ].mfTotalHeight, maPortions[ HF_RIGHT ].mfTotalHeight ) );
     714             : }
     715             : 
     716             : // private --------------------------------------------------------------------
     717             : 
     718         396 : double HeaderFooterParser::getCurrHeight( HFPortionId ePortion ) const
     719             : {
     720         396 :     double fMaxHt = maPortions[ ePortion ].mfCurrHeight;
     721         396 :     return (fMaxHt == 0.0) ? maFontModel.mfHeight : fMaxHt;
     722             : }
     723             : 
     724           0 : double HeaderFooterParser::getCurrHeight() const
     725             : {
     726           0 :     return getCurrHeight( meCurrPortion );
     727             : }
     728             : 
     729         198 : void HeaderFooterParser::updateCurrHeight( HFPortionId ePortion )
     730             : {
     731         198 :     double& rfMaxHt = maPortions[ ePortion ].mfCurrHeight;
     732         198 :     rfMaxHt = ::std::max( rfMaxHt, maFontModel.mfHeight );
     733         198 : }
     734             : 
     735         198 : void HeaderFooterParser::updateCurrHeight()
     736             : {
     737         198 :     updateCurrHeight( meCurrPortion );
     738         198 : }
     739             : 
     740         228 : void HeaderFooterParser::setAttributes()
     741             : {
     742         228 :     Reference<text::XTextRange> xRange( getStartPos(), UNO_QUERY );
     743         228 :     getEndPos()->gotoRange( xRange, sal_False );
     744         228 :     getEndPos()->gotoEnd( sal_True );
     745         228 :     if( !getEndPos()->isCollapsed() )
     746             :     {
     747         132 :         Font aFont( *this, maFontModel );
     748         132 :         aFont.finalizeImport();
     749         264 :         PropertySet aPropSet( getEndPos() );
     750         132 :         aFont.writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT );
     751         132 :         getStartPos()->gotoEnd( sal_False );
     752         264 :         getEndPos()->gotoEnd( sal_False );
     753         228 :     }
     754         228 : }
     755             : 
     756         492 : void HeaderFooterParser::appendText()
     757             : {
     758         492 :     if( !maBuffer.isEmpty() )
     759             :     {
     760          66 :         getEndPos()->gotoEnd( sal_False );
     761          66 :         getEndPos()->setString( maBuffer.makeStringAndClear() );
     762          66 :         updateCurrHeight();
     763             :     }
     764         492 : }
     765             : 
     766           0 : void HeaderFooterParser::appendLineBreak()
     767             : {
     768           0 :     getEndPos()->gotoEnd( sal_False );
     769           0 :     getEndPos()->setString( OUString( '\n' ) );
     770           0 :     getPortion().mfTotalHeight += getCurrHeight();
     771           0 :     getPortion().mfCurrHeight = 0;
     772           0 : }
     773             : 
     774         132 : Reference<text::XTextContent> HeaderFooterParser::createField( const OUString& rServiceName ) const
     775             : {
     776         132 :     Reference<text::XTextContent> xContent;
     777             :     try
     778             :     {
     779         132 :         xContent.set( getBaseFilter().getModelFactory()->createInstance( rServiceName ), UNO_QUERY_THROW );
     780             :     }
     781           0 :     catch( Exception& )
     782             :     {
     783             :         OSL_FAIL( OStringBuffer( "HeaderFooterParser::createField - error while creating text field \"" ).
     784             :             append( OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ) ).
     785             :             append( '"' ).getStr() );
     786             :     }
     787         132 :     return xContent;
     788             : }
     789             : 
     790         132 : void HeaderFooterParser::appendField( const Reference<text::XTextContent>& rxContent )
     791             : {
     792         132 :     getEndPos()->gotoEnd( sal_False );
     793             :     try
     794             :     {
     795         132 :         Reference<text::XTextRange> xRange( getEndPos(), UNO_QUERY_THROW );
     796         132 :         getPortion().mxText->insertTextContent( xRange, rxContent, sal_False );
     797         132 :         updateCurrHeight();
     798             :     }
     799           0 :     catch( Exception& )
     800             :     {
     801             :     }
     802         132 : }
     803             : 
     804          48 : void HeaderFooterParser::convertFontName( const OUString& rName )
     805             : {
     806          48 :     if( !rName.isEmpty() )
     807             :     {
     808             :         // single dash is document default font
     809          48 :         if( (rName.getLength() == 1) && (rName[ 0 ] == '-') )
     810           0 :             maFontModel.maName = getStyles().getDefaultFontModel().maName;
     811             :         else
     812          48 :             maFontModel.maName = rName;
     813             :     }
     814          48 : }
     815             : 
     816          48 : void HeaderFooterParser::convertFontStyle( const OUString& rStyle )
     817             : {
     818          48 :     maFontModel.mbBold = maFontModel.mbItalic = false;
     819          48 :     sal_Int32 nPos = 0;
     820          48 :     sal_Int32 nLen = rStyle.getLength();
     821         144 :     while( (0 <= nPos) && (nPos < nLen) )
     822             :     {
     823          48 :         OString aToken = OUStringToOString( rStyle.getToken( 0, ' ', nPos ), RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase();
     824          48 :         if( !aToken.isEmpty() )
     825             :         {
     826          48 :             if( maBoldNames.count( aToken ) > 0 )
     827           0 :                 maFontModel.mbBold = true;
     828          48 :             else if( maItalicNames.count( aToken ) > 0 )
     829           0 :                 maFontModel.mbItalic = true;
     830             :         }
     831          48 :     }
     832          48 : }
     833             : 
     834           0 : void HeaderFooterParser::convertFontColor( const OUString& rColor )
     835             : {
     836             :     OSL_ENSURE( rColor.getLength() == 6, "HeaderFooterParser::convertFontColor - invalid font color code" );
     837           0 :     if( (rColor[ 2 ] == '+') || (rColor[ 2 ] == '-') )
     838             :         // theme color: TTSNNN (TT = decimal theme index, S = +/-, NNN = decimal tint/shade in percent)
     839             :         maFontModel.maColor.setTheme(
     840             :             rColor.copy( 0, 2 ).toInt32(),
     841           0 :             static_cast< double >( rColor.copy( 2 ).toInt32() ) / 100.0 );
     842             :     else
     843             :         // RGB color: RRGGBB
     844           0 :         maFontModel.maColor.setRgb( rColor.toUInt32( 16 ) );
     845           0 : }
     846             : 
     847         132 : void HeaderFooterParser::finalizePortion()
     848             : {
     849         132 :     appendText();
     850         132 :     setAttributes();
     851         132 : }
     852             : 
     853         132 : void HeaderFooterParser::setNewPortion( HFPortionId ePortion )
     854             : {
     855         132 :     if( ePortion != meCurrPortion )
     856             :     {
     857           0 :         finalizePortion();
     858           0 :         meCurrPortion = ePortion;
     859           0 :         maFontModel = getStyles().getDefaultFontModel();
     860             :     }
     861         132 : }
     862             : 
     863         256 : PageSettingsConverter::HFHelperData::HFHelperData( sal_Int32 nLeftPropId, sal_Int32 nRightPropId ) :
     864             :     mnLeftPropId( nLeftPropId ),
     865             :     mnRightPropId( nRightPropId ),
     866             :     mnHeight( 0 ),
     867             :     mnBodyDist( 0 ),
     868             :     mbHasContent( false ),
     869             :     mbShareOddEven( false ),
     870         256 :     mbDynamicHeight( false )
     871             : {
     872         256 : }
     873             : 
     874         128 : PageSettingsConverter::PageSettingsConverter( const WorkbookHelper& rHelper ) :
     875             :     WorkbookHelper( rHelper ),
     876         128 :     mxHFParser( new HeaderFooterParser( rHelper ) ),
     877             :     maHeaderData( PROP_LeftPageHeaderContent, PROP_RightPageHeaderContent ),
     878         256 :     maFooterData( PROP_LeftPageFooterContent, PROP_RightPageFooterContent )
     879             : {
     880         128 : }
     881             : 
     882         256 : PageSettingsConverter::~PageSettingsConverter()
     883             : {
     884         256 : }
     885             : 
     886         260 : void PageSettingsConverter::writePageSettingsProperties(
     887             :         PropertySet& rPropSet, const PageSettingsModel& rModel, WorksheetType eSheetType )
     888             : {
     889             :     // special handling for chart sheets
     890         260 :     bool bChartSheet = eSheetType == SHEETTYPE_CHARTSHEET;
     891             : 
     892             :     // printout scaling
     893         260 :     if( bChartSheet )
     894             :     {
     895             :         // always fit chart sheet to 1 page
     896           0 :         rPropSet.setProperty< sal_Int16 >( PROP_ScaleToPages, 1 );
     897             :     }
     898         260 :     else if( rModel.mbFitToPages )
     899             :     {
     900             :         // fit to number of pages
     901           0 :         rPropSet.setProperty( PROP_ScaleToPagesX, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToWidth, 0, 1000 ) );
     902           0 :         rPropSet.setProperty( PROP_ScaleToPagesY, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToHeight, 0, 1000 ) );
     903             :     }
     904             :     else
     905             :     {
     906             :         // scale may be 0 which indicates uninitialized
     907         260 :         sal_Int16 nScale = (rModel.mbValidSettings && (rModel.mnScale > 0)) ? getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnScale, 10, 400 ) : 100;
     908         260 :         rPropSet.setProperty( PROP_PageScale, nScale );
     909             :     }
     910             : 
     911             :     // paper orientation
     912         260 :     bool bLandscape = rModel.mnOrientation == XML_landscape;
     913             :     // default orientation for current sheet type (chart sheets default to landscape)
     914         260 :     if( bChartSheet && ( !rModel.mbValidSettings || (rModel.mnOrientation == XML_default) ) )
     915           0 :         bLandscape = true;
     916             : 
     917             :     // paper size
     918         260 :     if( !rModel.mbValidSettings )
     919             :     {
     920         152 :         awt::Size aSize;
     921         152 :         bool bValid = false;
     922             : 
     923         152 :         if( (0 < rModel.mnPaperSize) )
     924             :         {
     925         138 :             const msfilter::util::ApiPaperSize& rPaperSize = msfilter::util::PaperSizeConv::getApiSizeForMSPaperSizeIndex(  rModel.mnPaperSize );
     926         138 :             aSize = awt::Size( rPaperSize.mnWidth, rPaperSize.mnHeight );
     927         138 :             bValid = ( rPaperSize.mnWidth != 0 && rPaperSize.mnHeight != 0 );
     928             :         }
     929         152 :         if( rModel.mnPaperWidth > 0 && rModel.mnPaperHeight > 0 )
     930             :         {
     931           0 :             aSize = awt::Size( rModel.mnPaperWidth, rModel.mnPaperHeight );
     932           0 :             bValid = true;
     933             :         }
     934             : 
     935         152 :         if( bValid )
     936             :         {
     937         138 :             if( bLandscape )
     938           0 :                 ::std::swap( aSize.Width, aSize.Height );
     939         138 :             rPropSet.setProperty( PROP_Size, aSize );
     940             :         }
     941             :     }
     942             : 
     943             :     // header/footer
     944         260 :     convertHeaderFooterData( rPropSet, maHeaderData, rModel.maOddHeader, rModel.maEvenHeader, rModel.mbUseEvenHF, rModel.mfTopMargin,    rModel.mfHeaderMargin );
     945         260 :     convertHeaderFooterData( rPropSet, maFooterData, rModel.maOddFooter, rModel.maEvenFooter, rModel.mbUseEvenHF, rModel.mfBottomMargin, rModel.mfFooterMargin );
     946             : 
     947             :     // write all properties to property set
     948         260 :     const UnitConverter& rUnitConv = getUnitConverter();
     949         260 :     PropertyMap aPropMap;
     950         260 :     aPropMap.setProperty( PROP_IsLandscape, bLandscape);
     951         260 :     aPropMap.setProperty( PROP_FirstPageNumber, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mbUseFirstPage ? rModel.mnFirstPage : 0, 0, 9999 ));
     952         260 :     aPropMap.setProperty( PROP_PrintDownFirst, (rModel.mnPageOrder == XML_downThenOver));
     953         260 :     aPropMap.setProperty( PROP_PrintAnnotations, (rModel.mnCellComments == XML_asDisplayed));
     954         260 :     aPropMap.setProperty( PROP_CenterHorizontally, rModel.mbHorCenter);
     955         260 :     aPropMap.setProperty( PROP_CenterVertically, rModel.mbVerCenter);
     956         260 :     aPropMap.setProperty( PROP_PrintGrid, (!bChartSheet && rModel.mbPrintGrid));     // no gridlines in chart sheets
     957         260 :     aPropMap.setProperty( PROP_PrintHeaders, (!bChartSheet && rModel.mbPrintHeadings)); // no column/row headings in chart sheets
     958         260 :     aPropMap.setProperty( PROP_LeftMargin, rUnitConv.scaleToMm100( rModel.mfLeftMargin, UNIT_INCH ));
     959         260 :     aPropMap.setProperty( PROP_RightMargin, rUnitConv.scaleToMm100( rModel.mfRightMargin, UNIT_INCH ));
     960             :     // #i23296# In Calc, "TopMargin" property is distance to top of header if enabled
     961         260 :     aPropMap.setProperty( PROP_TopMargin, rUnitConv.scaleToMm100( maHeaderData.mbHasContent ? rModel.mfHeaderMargin : rModel.mfTopMargin, UNIT_INCH ));
     962             :     // #i23296# In Calc, "BottomMargin" property is distance to bottom of footer if enabled
     963         260 :     aPropMap.setProperty( PROP_BottomMargin, rUnitConv.scaleToMm100( maFooterData.mbHasContent ? rModel.mfFooterMargin : rModel.mfBottomMargin, UNIT_INCH ));
     964         260 :     aPropMap.setProperty( PROP_HeaderIsOn, maHeaderData.mbHasContent);
     965         260 :     aPropMap.setProperty( PROP_HeaderIsShared, maHeaderData.mbShareOddEven);
     966         260 :     aPropMap.setProperty( PROP_HeaderIsDynamicHeight, maHeaderData.mbDynamicHeight);
     967         260 :     aPropMap.setProperty( PROP_HeaderHeight, maHeaderData.mnHeight);
     968         260 :     aPropMap.setProperty( PROP_HeaderBodyDistance, maHeaderData.mnBodyDist);
     969         260 :     aPropMap.setProperty( PROP_FooterIsOn, maFooterData.mbHasContent);
     970         260 :     aPropMap.setProperty( PROP_FooterIsShared, maFooterData.mbShareOddEven);
     971         260 :     aPropMap.setProperty( PROP_FooterIsDynamicHeight, maFooterData.mbDynamicHeight);
     972         260 :     aPropMap.setProperty( PROP_FooterHeight, maFooterData.mnHeight);
     973         260 :     aPropMap.setProperty( PROP_FooterBodyDistance, maFooterData.mnBodyDist);
     974             :     // background image
     975         260 :     if( !rModel.maGraphicUrl.isEmpty() )
     976             :     {
     977           0 :         aPropMap.setProperty( PROP_BackGraphicURL, rModel.maGraphicUrl);
     978           0 :         aPropMap.setProperty( PROP_BackGraphicLocation, ::com::sun::star::style::GraphicLocation_TILED);
     979             :     }
     980             : 
     981         260 :     rPropSet.setProperties( aPropMap );
     982         260 : }
     983             : 
     984         520 : void PageSettingsConverter::convertHeaderFooterData(
     985             :         PropertySet& rPropSet, HFHelperData& orHFData,
     986             :         const OUString& rOddContent, const OUString& rEvenContent, bool bUseEvenContent,
     987             :         double fPageMargin, double fContentMargin )
     988             : {
     989         520 :     bool bHasOddContent  = !rOddContent.isEmpty();
     990         520 :     bool bHasEvenContent = bUseEvenContent && !rEvenContent.isEmpty();
     991             : 
     992         520 :     sal_Int32 nOddHeight  = bHasOddContent  ? writeHeaderFooter( rPropSet, orHFData.mnRightPropId, rOddContent  ) : 0;
     993         520 :     sal_Int32 nEvenHeight = bHasEvenContent ? writeHeaderFooter( rPropSet, orHFData.mnLeftPropId,  rEvenContent ) : 0;
     994             : 
     995         520 :     orHFData.mnHeight = 750;
     996         520 :     orHFData.mnBodyDist = 250;
     997         520 :     orHFData.mbHasContent = bHasOddContent || bHasEvenContent;
     998         520 :     orHFData.mbShareOddEven = !bUseEvenContent;
     999         520 :     orHFData.mbDynamicHeight = true;
    1000             : 
    1001         520 :     if( orHFData.mbHasContent )
    1002             :     {
    1003             :         // use maximum height of odd/even header/footer
    1004         132 :         orHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight );
    1005             :         /*  Calc contains distance between bottom of header and top of page
    1006             :             body in "HeaderBodyDistance" property, and distance between bottom
    1007             :             of page body and top of footer in "FooterBodyDistance" property */
    1008         132 :         orHFData.mnBodyDist = getUnitConverter().scaleToMm100( fPageMargin - fContentMargin, UNIT_INCH ) - orHFData.mnHeight;
    1009             :         /*  #i23296# Distance less than 0 means, header or footer overlays page
    1010             :             body. As this is not possible in Calc, set fixed header or footer
    1011             :             height (crop header/footer) to get correct top position of page body. */
    1012         132 :         orHFData.mbDynamicHeight = orHFData.mnBodyDist >= 0;
    1013             :         /*  "HeaderHeight" property is in fact distance from top of header to
    1014             :             top of page body (including "HeaderBodyDistance").
    1015             :             "FooterHeight" property is in fact distance from bottom of page
    1016             :             body to bottom of footer (including "FooterBodyDistance"). */
    1017         132 :         orHFData.mnHeight += orHFData.mnBodyDist;
    1018             :         // negative body distance not allowed
    1019         132 :         orHFData.mnBodyDist = ::std::max< sal_Int32 >( orHFData.mnBodyDist, 0 );
    1020             :     }
    1021         520 : }
    1022             : 
    1023         132 : sal_Int32 PageSettingsConverter::writeHeaderFooter(
    1024             :         PropertySet& rPropSet, sal_Int32 nPropId, const OUString& rContent )
    1025             : {
    1026             :     OSL_ENSURE( !rContent.isEmpty(), "PageSettingsConverter::writeHeaderFooter - empty h/f string found" );
    1027         132 :     sal_Int32 nHeight = 0;
    1028         132 :     if( !rContent.isEmpty() )
    1029             :     {
    1030         132 :         Reference<sheet::XHeaderFooterContent> xHFContent(rPropSet.getAnyProperty(nPropId), UNO_QUERY);
    1031         132 :         if( xHFContent.is() )
    1032             :         {
    1033         132 :             double fTotalHeight = mxHFParser->parse( xHFContent, rContent );
    1034         132 :             rPropSet.setProperty( nPropId, xHFContent );
    1035         132 :             nHeight = getUnitConverter().scaleToMm100( fTotalHeight, UNIT_POINT );
    1036         132 :         }
    1037             :     }
    1038         132 :     return nHeight;
    1039             : }
    1040             : 
    1041             : } // namespace xls
    1042          48 : } // namespace oox
    1043             : 
    1044             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10