merge the formfield patch from ooo-build
[ooovba.git] / oox / source / xls / pagesettings.cxx
blob956dec51f27e6c3c6ddf9bbc82bc06b794638547
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pagesettings.cxx,v $
10 * $Revision: 1.5.4.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/xls/pagesettings.hxx"
32 #include <set>
33 #include <algorithm>
34 #include <rtl/strbuf.hxx>
35 #include <rtl/ustrbuf.hxx>
36 #include <com/sun/star/awt/Size.hpp>
37 #include <com/sun/star/container/XNamed.hpp>
38 #include <com/sun/star/sheet/XHeaderFooterContent.hpp>
39 #include <com/sun/star/style/GraphicLocation.hpp>
40 #include <com/sun/star/text/FilenameDisplayFormat.hpp>
41 #include <com/sun/star/text/XText.hpp>
42 #include <com/sun/star/text/XTextContent.hpp>
43 #include <com/sun/star/text/XTextCursor.hpp>
44 #include "properties.hxx"
45 #include "oox/helper/attributelist.hxx"
46 #include "oox/helper/graphichelper.hxx"
47 #include "oox/helper/propertymap.hxx"
48 #include "oox/helper/propertyset.hxx"
49 #include "oox/helper/recordinputstream.hxx"
50 #include "oox/core/xmlfilterbase.hxx"
51 #include "oox/xls/biffinputstream.hxx"
52 #include "oox/xls/excelhandlers.hxx"
53 #include "oox/xls/stylesbuffer.hxx"
54 #include "oox/xls/unitconverter.hxx"
56 using ::rtl::OString;
57 using ::rtl::OStringBuffer;
58 using ::rtl::OUString;
59 using ::rtl::OUStringBuffer;
60 using ::com::sun::star::uno::Exception;
61 using ::com::sun::star::uno::Reference;
62 using ::com::sun::star::uno::UNO_QUERY;
63 using ::com::sun::star::uno::UNO_QUERY_THROW;
64 using ::com::sun::star::container::XNamed;
65 using ::com::sun::star::lang::XMultiServiceFactory;
66 using ::com::sun::star::awt::Size;
67 using ::com::sun::star::sheet::XHeaderFooterContent;
68 using ::com::sun::star::style::XStyle;
69 using ::com::sun::star::text::XText;
70 using ::com::sun::star::text::XTextCursor;
71 using ::com::sun::star::text::XTextContent;
72 using ::com::sun::star::text::XTextRange;
73 using ::oox::core::Relations;
75 namespace oox {
76 namespace xls {
78 // ============================================================================
80 namespace {
82 const double OOX_MARGIN_DEFAULT_LR = 0.748; /// Left/right default margin in inches.
83 const double OOX_MARGIN_DEFAULT_TB = 0.984; /// Top/bottom default margin in inches.
84 const double OOX_MARGIN_DEFAULT_HF = 0.512; /// Header/footer default margin in inches.
86 const sal_uInt16 OOBIN_PRINTOPT_HORCENTER = 0x0001;
87 const sal_uInt16 OOBIN_PRINTOPT_VERCENTER = 0x0002;
88 const sal_uInt16 OOBIN_PRINTOPT_PRINTHEADING = 0x0004;
89 const sal_uInt16 OOBIN_PRINTOPT_PRINTGRID = 0x0008;
91 const sal_uInt16 OOBIN_HEADERFOOTER_DIFFEVEN = 0x0001;
92 const sal_uInt16 OOBIN_HEADERFOOTER_DIFFFIRST = 0x0002;
93 const sal_uInt16 OOBIN_HEADERFOOTER_SCALEDOC = 0x0004;
94 const sal_uInt16 OOBIN_HEADERFOOTER_ALIGNMARGIN = 0x0008;
96 const sal_uInt16 OOBIN_PAGESETUP_INROWS = 0x0001;
97 const sal_uInt16 OOBIN_PAGESETUP_LANDSCAPE = 0x0002;
98 const sal_uInt16 OOBIN_PAGESETUP_INVALID = 0x0004;
99 const sal_uInt16 OOBIN_PAGESETUP_BLACKWHITE = 0x0008;
100 const sal_uInt16 OOBIN_PAGESETUP_DRAFTQUALITY = 0x0010;
101 const sal_uInt16 OOBIN_PAGESETUP_PRINTNOTES = 0x0020;
102 const sal_uInt16 OOBIN_PAGESETUP_DEFAULTORIENT = 0x0040;
103 const sal_uInt16 OOBIN_PAGESETUP_USEFIRSTPAGE = 0x0080;
104 const sal_uInt16 OOBIN_PAGESETUP_NOTES_END = 0x0100; // different to BIFF flag
106 const sal_uInt16 OOBIN_CHARTPAGESETUP_LANDSCAPE = 0x0001;
107 const sal_uInt16 OOBIN_CHARTPAGESETUP_INVALID = 0x0002;
108 const sal_uInt16 OOBIN_CHARTPAGESETUP_BLACKWHITE = 0x0004;
109 const sal_uInt16 OOBIN_CHARTPAGESETUP_DEFAULTORIENT = 0x0008;
110 const sal_uInt16 OOBIN_CHARTPAGESETUP_USEFIRSTPAGE = 0x0010;
111 const sal_uInt16 OOBIN_CHARTPAGESETUP_DRAFTQUALITY = 0x0020;
113 const sal_uInt16 BIFF_PAGESETUP_INROWS = 0x0001;
114 const sal_uInt16 BIFF_PAGESETUP_PORTRAIT = 0x0002;
115 const sal_uInt16 BIFF_PAGESETUP_INVALID = 0x0004;
116 const sal_uInt16 BIFF_PAGESETUP_BLACKWHITE = 0x0008;
117 const sal_uInt16 BIFF_PAGESETUP_DRAFTQUALITY = 0x0010;
118 const sal_uInt16 BIFF_PAGESETUP_PRINTNOTES = 0x0020;
119 const sal_uInt16 BIFF_PAGESETUP_DEFAULTORIENT = 0x0040;
120 const sal_uInt16 BIFF_PAGESETUP_USEFIRSTPAGE = 0x0080;
121 const sal_uInt16 BIFF_PAGESETUP_NOTES_END = 0x0200;
123 } // namespace
125 // ============================================================================
127 PageSettingsModel::PageSettingsModel() :
128 mfLeftMargin( OOX_MARGIN_DEFAULT_LR ),
129 mfRightMargin( OOX_MARGIN_DEFAULT_LR ),
130 mfTopMargin( OOX_MARGIN_DEFAULT_TB ),
131 mfBottomMargin( OOX_MARGIN_DEFAULT_TB ),
132 mfHeaderMargin( OOX_MARGIN_DEFAULT_HF ),
133 mfFooterMargin( OOX_MARGIN_DEFAULT_HF ),
134 mnPaperSize( 1 ),
135 mnCopies( 1 ),
136 mnScale( 100 ),
137 mnFirstPage( 1 ),
138 mnFitToWidth( 1 ),
139 mnFitToHeight( 1 ),
140 mnHorPrintRes( 600 ),
141 mnVerPrintRes( 600 ),
142 mnOrientation( XML_default ),
143 mnPageOrder( XML_downThenOver ),
144 mnCellComments( XML_none ),
145 mnPrintErrors( XML_displayed ),
146 mbUseEvenHF( false ),
147 mbUseFirstHF( false ),
148 mbValidSettings( true ),
149 mbUseFirstPage( false ),
150 mbBlackWhite( false ),
151 mbDraftQuality( false ),
152 mbFitToPages( false ),
153 mbHorCenter( false ),
154 mbVerCenter( false ),
155 mbPrintGrid( false ),
156 mbPrintHeadings( false )
160 void PageSettingsModel::setBinPrintErrors( sal_uInt8 nPrintErrors )
162 static const sal_Int32 spnErrorIds[] = { XML_displayed, XML_none, XML_dash, XML_NA };
163 mnPrintErrors = STATIC_ARRAY_SELECT( spnErrorIds, nPrintErrors, XML_none );
166 // ============================================================================
168 PageSettings::PageSettings( const WorksheetHelper& rHelper ) :
169 WorksheetHelper( rHelper )
173 void PageSettings::importPrintOptions( const AttributeList& rAttribs )
175 maModel.mbHorCenter = rAttribs.getBool( XML_horizontalCentered, false );
176 maModel.mbVerCenter = rAttribs.getBool( XML_verticalCentered, false );
177 maModel.mbPrintGrid = rAttribs.getBool( XML_gridLines, false );
178 maModel.mbPrintHeadings = rAttribs.getBool( XML_headings, false );
181 void PageSettings::importPageMargins( const AttributeList& rAttribs )
183 maModel.mfLeftMargin = rAttribs.getDouble( XML_left, OOX_MARGIN_DEFAULT_LR );
184 maModel.mfRightMargin = rAttribs.getDouble( XML_right, OOX_MARGIN_DEFAULT_LR );
185 maModel.mfTopMargin = rAttribs.getDouble( XML_top, OOX_MARGIN_DEFAULT_TB );
186 maModel.mfBottomMargin = rAttribs.getDouble( XML_bottom, OOX_MARGIN_DEFAULT_TB );
187 maModel.mfHeaderMargin = rAttribs.getDouble( XML_header, OOX_MARGIN_DEFAULT_HF );
188 maModel.mfFooterMargin = rAttribs.getDouble( XML_footer, OOX_MARGIN_DEFAULT_HF );
191 void PageSettings::importPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
193 maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
194 maModel.mnPaperSize = rAttribs.getInteger( XML_paperSize, 1 );
195 maModel.mnCopies = rAttribs.getInteger( XML_copies, 1 );
196 maModel.mnScale = rAttribs.getInteger( XML_scale, 100 );
197 maModel.mnFirstPage = rAttribs.getInteger( XML_firstPageNumber, 1 );
198 maModel.mnFitToWidth = rAttribs.getInteger( XML_fitToWidth, 1 );
199 maModel.mnFitToHeight = rAttribs.getInteger( XML_fitToHeight, 1 );
200 maModel.mnHorPrintRes = rAttribs.getInteger( XML_horizontalDpi, 600 );
201 maModel.mnVerPrintRes = rAttribs.getInteger( XML_verticalDpi, 600 );
202 maModel.mnOrientation = rAttribs.getToken( XML_orientation, XML_default );
203 maModel.mnPageOrder = rAttribs.getToken( XML_pageOrder, XML_downThenOver );
204 maModel.mnCellComments = rAttribs.getToken( XML_cellComments, XML_none );
205 maModel.mnPrintErrors = rAttribs.getToken( XML_errors, XML_displayed );
206 maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true );
207 maModel.mbUseFirstPage = rAttribs.getBool( XML_useFirstPageNumber, false );
208 maModel.mbBlackWhite = rAttribs.getBool( XML_blackAndWhite, false );
209 maModel.mbDraftQuality = rAttribs.getBool( XML_draft, false );
212 void PageSettings::importChartPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
214 maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
215 maModel.mnPaperSize = rAttribs.getInteger( XML_paperSize, 1 );
216 maModel.mnCopies = rAttribs.getInteger( XML_copies, 1 );
217 maModel.mnFirstPage = rAttribs.getInteger( XML_firstPageNumber, 1 );
218 maModel.mnHorPrintRes = rAttribs.getInteger( XML_horizontalDpi, 600 );
219 maModel.mnVerPrintRes = rAttribs.getInteger( XML_verticalDpi, 600 );
220 maModel.mnOrientation = rAttribs.getToken( XML_orientation, XML_default );
221 maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true );
222 maModel.mbUseFirstPage = rAttribs.getBool( XML_useFirstPageNumber, false );
223 maModel.mbBlackWhite = rAttribs.getBool( XML_blackAndWhite, false );
224 maModel.mbDraftQuality = rAttribs.getBool( XML_draft, false );
227 void PageSettings::importHeaderFooter( const AttributeList& rAttribs )
229 maModel.mbUseEvenHF = rAttribs.getBool( XML_differentOddEven, false );
230 maModel.mbUseFirstHF = rAttribs.getBool( XML_differentFirst, false );
233 void PageSettings::importHeaderFooterCharacters( const OUString& rChars, sal_Int32 nElement )
235 switch( nElement )
237 case XLS_TOKEN( oddHeader ): maModel.maOddHeader += rChars; break;
238 case XLS_TOKEN( oddFooter ): maModel.maOddFooter += rChars; break;
239 case XLS_TOKEN( evenHeader ): maModel.maEvenHeader += rChars; break;
240 case XLS_TOKEN( evenFooter ): maModel.maEvenFooter += rChars; break;
241 case XLS_TOKEN( firstHeader ): maModel.maFirstHeader += rChars; break;
242 case XLS_TOKEN( firstFooter ): maModel.maFirstFooter += rChars; break;
246 void PageSettings::importPicture( const Relations& rRelations, const AttributeList& rAttribs )
248 importPictureData( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
251 void PageSettings::importPageMargins( RecordInputStream& rStrm )
253 rStrm >> maModel.mfLeftMargin >> maModel.mfRightMargin
254 >> maModel.mfTopMargin >> maModel.mfBottomMargin
255 >> maModel.mfHeaderMargin >> maModel.mfFooterMargin;
258 void PageSettings::importPrintOptions( RecordInputStream& rStrm )
260 sal_uInt16 nFlags;
261 rStrm >> nFlags;
262 maModel.mbHorCenter = getFlag( nFlags, OOBIN_PRINTOPT_HORCENTER );
263 maModel.mbVerCenter = getFlag( nFlags, OOBIN_PRINTOPT_VERCENTER );
264 maModel.mbPrintGrid = getFlag( nFlags, OOBIN_PRINTOPT_PRINTGRID );
265 maModel.mbPrintHeadings = getFlag( nFlags, OOBIN_PRINTOPT_PRINTHEADING );
268 void PageSettings::importPageSetup( const Relations& rRelations, RecordInputStream& rStrm )
270 OUString aRelId;
271 sal_uInt16 nFlags;
272 rStrm >> maModel.mnPaperSize >> maModel.mnScale
273 >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
274 >> maModel.mnCopies >> maModel.mnFirstPage
275 >> maModel.mnFitToWidth >> maModel.mnFitToHeight
276 >> nFlags >> aRelId;
277 maModel.setBinPrintErrors( extractValue< sal_uInt8 >( nFlags, 9, 2 ) );
278 maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( aRelId );
279 maModel.mnOrientation = getFlagValue( nFlags, OOBIN_PAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, OOBIN_PAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
280 maModel.mnPageOrder = getFlagValue( nFlags, OOBIN_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
281 maModel.mnCellComments = getFlagValue( nFlags, OOBIN_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, OOBIN_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
282 maModel.mbValidSettings = !getFlag( nFlags, OOBIN_PAGESETUP_INVALID );
283 maModel.mbUseFirstPage = getFlag( nFlags, OOBIN_PAGESETUP_USEFIRSTPAGE );
284 maModel.mbBlackWhite = getFlag( nFlags, OOBIN_PAGESETUP_BLACKWHITE );
285 maModel.mbDraftQuality = getFlag( nFlags, OOBIN_PAGESETUP_DRAFTQUALITY );
288 void PageSettings::importChartPageSetup( const Relations& rRelations, RecordInputStream& rStrm )
290 OUString aRelId;
291 sal_uInt16 nFirstPage, nFlags;
292 rStrm >> maModel.mnPaperSize >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
293 >> maModel.mnCopies >> nFirstPage >> nFlags >> aRelId;
294 maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( aRelId );
295 maModel.mnFirstPage = nFirstPage; // 16-bit in CHARTPAGESETUP
296 maModel.mnOrientation = getFlagValue( nFlags, OOBIN_CHARTPAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, OOBIN_CHARTPAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
297 maModel.mbValidSettings = !getFlag( nFlags, OOBIN_CHARTPAGESETUP_INVALID );
298 maModel.mbUseFirstPage = getFlag( nFlags, OOBIN_CHARTPAGESETUP_USEFIRSTPAGE );
299 maModel.mbBlackWhite = getFlag( nFlags, OOBIN_CHARTPAGESETUP_BLACKWHITE );
300 maModel.mbDraftQuality = getFlag( nFlags, OOBIN_CHARTPAGESETUP_DRAFTQUALITY );
303 void PageSettings::importHeaderFooter( RecordInputStream& rStrm )
305 sal_uInt16 nFlags;
306 rStrm >> nFlags
307 >> maModel.maOddHeader >> maModel.maOddFooter
308 >> maModel.maEvenHeader >> maModel.maEvenFooter
309 >> maModel.maFirstHeader >> maModel.maFirstFooter;
310 maModel.mbUseEvenHF = getFlag( nFlags, OOBIN_HEADERFOOTER_DIFFEVEN );
311 maModel.mbUseFirstHF = getFlag( nFlags, OOBIN_HEADERFOOTER_DIFFFIRST );
314 void PageSettings::importPicture( const Relations& rRelations, RecordInputStream& rStrm )
316 importPictureData( rRelations, rStrm.readString() );
319 void PageSettings::importLeftMargin( BiffInputStream& rStrm )
321 rStrm >> maModel.mfLeftMargin;
324 void PageSettings::importRightMargin( BiffInputStream& rStrm )
326 rStrm >> maModel.mfRightMargin;
329 void PageSettings::importTopMargin( BiffInputStream& rStrm )
331 rStrm >> maModel.mfTopMargin;
334 void PageSettings::importBottomMargin( BiffInputStream& rStrm )
336 rStrm >> maModel.mfBottomMargin;
339 void PageSettings::importPageSetup( BiffInputStream& rStrm )
341 sal_uInt16 nPaperSize, nScale, nFirstPage, nFitToWidth, nFitToHeight, nFlags;
342 rStrm >> nPaperSize >> nScale >> nFirstPage >> nFitToWidth >> nFitToHeight >> nFlags;
344 maModel.mnPaperSize = nPaperSize; // equal in BIFF and OOX
345 maModel.mnScale = nScale;
346 maModel.mnFirstPage = nFirstPage;
347 maModel.mnFitToWidth = nFitToWidth;
348 maModel.mnFitToHeight = nFitToHeight;
349 maModel.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_PORTRAIT, XML_portrait, XML_landscape );
350 maModel.mnPageOrder = getFlagValue( nFlags, BIFF_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
351 maModel.mbValidSettings = !getFlag( nFlags, BIFF_PAGESETUP_INVALID );
352 maModel.mbUseFirstPage = true;
353 maModel.mbBlackWhite = getFlag( nFlags, BIFF_PAGESETUP_BLACKWHITE );
355 if( getBiff() >= BIFF5 )
357 sal_uInt16 nHorPrintRes, nVerPrintRes, nCopies;
358 rStrm >> nHorPrintRes >> nVerPrintRes >> maModel.mfHeaderMargin >> maModel.mfFooterMargin >> nCopies;
360 maModel.mnCopies = nCopies;
361 maModel.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_DEFAULTORIENT, XML_default, maModel.mnOrientation );
362 maModel.mnHorPrintRes = nHorPrintRes;
363 maModel.mnVerPrintRes = nVerPrintRes;
364 maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, XML_asDisplayed, XML_none );
365 maModel.mbUseFirstPage = getFlag( nFlags, BIFF_PAGESETUP_USEFIRSTPAGE );
366 maModel.mbDraftQuality = getFlag( nFlags, BIFF_PAGESETUP_DRAFTQUALITY );
368 if( getBiff() == BIFF8 )
370 maModel.setBinPrintErrors( extractValue< sal_uInt8 >( nFlags, 10, 2 ) );
371 maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
376 void PageSettings::importHorCenter( BiffInputStream& rStrm )
378 maModel.mbHorCenter = rStrm.readuInt16() != 0;
381 void PageSettings::importVerCenter( BiffInputStream& rStrm )
383 maModel.mbVerCenter = rStrm.readuInt16() != 0;
386 void PageSettings::importPrintHeaders( BiffInputStream& rStrm )
388 maModel.mbPrintHeadings = rStrm.readuInt16() != 0;
391 void PageSettings::importPrintGridLines( BiffInputStream& rStrm )
393 maModel.mbPrintGrid = rStrm.readuInt16() != 0;
396 void PageSettings::importHeader( BiffInputStream& rStrm )
398 if( rStrm.getRemaining() > 0 )
399 maModel.maOddHeader = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
400 else
401 maModel.maOddHeader = OUString();
404 void PageSettings::importFooter( BiffInputStream& rStrm )
406 if( rStrm.getRemaining() > 0 )
407 maModel.maOddFooter = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
408 else
409 maModel.maOddFooter = OUString();
412 void PageSettings::importPicture( BiffInputStream& rStrm )
414 StreamDataSequence aPictureData;
415 BiffHelper::importImgData( aPictureData, rStrm, getBiff() );
416 maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importGraphicObject( aPictureData );
419 void PageSettings::setFitToPagesMode( bool bFitToPages )
421 maModel.mbFitToPages = bFitToPages;
424 void PageSettings::finalizeImport()
426 OUStringBuffer aStyleNameBuffer( CREATE_OUSTRING( "PageStyle_" ) );
427 Reference< XNamed > xSheetName( getSheet(), UNO_QUERY );
428 if( xSheetName.is() )
429 aStyleNameBuffer.append( xSheetName->getName() );
430 else
431 aStyleNameBuffer.append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) );
432 OUString aStyleName = aStyleNameBuffer.makeStringAndClear();
434 Reference< XStyle > xStyle = createStyleObject( aStyleName, true );
435 PropertySet aStyleProps( xStyle );
436 getPageSettingsConverter().writePageSettingsProperties( aStyleProps, maModel, getSheetType() );
438 PropertySet aSheetProps( getSheet() );
439 aSheetProps.setProperty( PROP_PageStyle, aStyleName );
442 void PageSettings::importPictureData( const Relations& rRelations, const OUString& rRelId )
444 OUString aPicturePath = rRelations.getFragmentPathFromRelId( rRelId );
445 if( aPicturePath.getLength() > 0 )
446 maModel.maGraphicUrl = getBaseFilter().importEmbeddedGraphicObject( aPicturePath );
449 // ============================================================================
450 // ============================================================================
452 enum HFPortionId
454 HF_LEFT,
455 HF_CENTER,
456 HF_RIGHT,
457 HF_COUNT
460 // ----------------------------------------------------------------------------
462 struct HFPortionInfo
464 Reference< XText > mxText; /// XText interface of this portion.
465 Reference< XTextCursor > mxStart; /// Start position of current text range for formatting.
466 Reference< XTextCursor > mxEnd; /// End position of current text range for formatting.
467 double mfTotalHeight; /// Sum of heights of previous lines in points.
468 double mfCurrHeight; /// Height of the current text line in points.
470 bool initialize( const Reference< XText >& rxText );
473 bool HFPortionInfo::initialize( const Reference< XText >& rxText )
475 mfTotalHeight = mfCurrHeight = 0.0;
476 mxText = rxText;
477 if( mxText.is() )
479 mxStart = mxText->createTextCursor();
480 mxEnd = mxText->createTextCursor();
482 bool bRet = mxText.is() && mxStart.is() && mxEnd.is();
483 OSL_ENSURE( bRet, "HFPortionInfo::initialize - missing interfaces" );
484 return bRet;
487 // ============================================================================
489 class HeaderFooterParser : public WorkbookHelper
491 public:
492 explicit HeaderFooterParser( const WorkbookHelper& rHelper );
494 /** Parses the passed string and creates the header/footer contents.
495 @returns The total height of the converted header or footer in points. */
496 double parse(
497 const Reference< XHeaderFooterContent >& rxContext,
498 const OUString& rData );
500 private:
501 /** Returns the current edit engine text object. */
502 inline HFPortionInfo& getPortion() { return maPortions[ meCurrPortion ]; }
503 /** Returns the start cursor of the current text range. */
504 inline const Reference< XTextCursor >& getStartPos() { return getPortion().mxStart; }
505 /** Returns the end cursor of the current text range. */
506 inline const Reference< XTextCursor >& getEndPos() { return getPortion().mxEnd; }
508 /** Returns the current line height of the specified portion. */
509 double getCurrHeight( HFPortionId ePortion ) const;
510 /** Returns the current line height. */
511 double getCurrHeight() const;
513 /** Updates the current line height of the specified portion, using the current font size. */
514 void updateCurrHeight( HFPortionId ePortion );
515 /** Updates the current line height, using the current font size. */
516 void updateCurrHeight();
518 /** Sets the font attributes at the current selection. */
519 void setAttributes();
520 /** Appends and clears internal string buffer. */
521 void appendText();
522 /** Appends a line break and adjusts internal text height data. */
523 void appendLineBreak();
525 /** Creates a text field from the passed service name. */
526 Reference< XTextContent > createField( const OUString& rServiceName ) const;
527 /** Appends the passed text field. */
528 void appendField( const Reference< XTextContent >& rxContent );
530 /** Sets the passed font name if it is valid. */
531 void convertFontName( const OUString& rStyle );
532 /** Converts a font style given as string. */
533 void convertFontStyle( const OUString& rStyle );
534 /** Converts a font color given as string. */
535 void convertFontColor( const OUString& rColor );
537 /** Finalizes current portion: sets font attributes and updates text height data. */
538 void finalizePortion();
539 /** Changes current header/footer portion. */
540 void setNewPortion( HFPortionId ePortion );
542 private:
543 typedef ::std::vector< HFPortionInfo > HFPortionInfoVec;
544 typedef ::std::set< OString > OStringSet;
546 const OUString maPageNumberService;
547 const OUString maPageCountService;
548 const OUString maSheetNameService;
549 const OUString maFileNameService;
550 const OUString maDateTimeService;
551 const OStringSet maBoldNames; /// All names for bold font style in lowercase UTF-8.
552 const OStringSet maItalicNames; /// All names for italic font style in lowercase UTF-8.
553 HFPortionInfoVec maPortions;
554 HFPortionId meCurrPortion; /// Identifier of current H/F portion.
555 OUStringBuffer maBuffer; /// Text data to append to current text range.
556 FontModel maFontModel; /// Font attributes of current text range.
559 // ----------------------------------------------------------------------------
561 namespace {
563 // different names for bold font style (lowercase)
564 static const sal_Char* const sppcBoldNames[] =
566 "bold",
567 "fett", // German 'bold'
568 "demibold",
569 "halbfett", // German 'demibold'
570 "black",
571 "heavy"
574 // different names for italic font style (lowercase)
575 static const sal_Char* const sppcItalicNames[] =
577 "italic",
578 "kursiv", // German 'italic'
579 "oblique",
580 "schr\303\204g", // German 'oblique' with uppercase A umlaut
581 "schr\303\244g" // German 'oblique' with lowercase A umlaut
584 } // namespace
586 // ----------------------------------------------------------------------------
588 HeaderFooterParser::HeaderFooterParser( const WorkbookHelper& rHelper ) :
589 WorkbookHelper( rHelper ),
590 maPageNumberService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageNumber" ) ),
591 maPageCountService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageCount" ) ),
592 maSheetNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.SheetName" ) ),
593 maFileNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.FileName" ) ),
594 maDateTimeService( CREATE_OUSTRING( "com.sun.star.text.TextField.DateTime" ) ),
595 maBoldNames( sppcBoldNames, STATIC_ARRAY_END( sppcBoldNames ) ),
596 maItalicNames( sppcItalicNames, STATIC_ARRAY_END( sppcItalicNames ) ),
597 maPortions( static_cast< size_t >( HF_COUNT ) ),
598 meCurrPortion( HF_CENTER )
602 double HeaderFooterParser::parse( const Reference< XHeaderFooterContent >& rxContext, const OUString& rData )
604 if( !rxContext.is() || (rData.getLength() == 0) ||
605 !maPortions[ HF_LEFT ].initialize( rxContext->getLeftText() ) ||
606 !maPortions[ HF_CENTER ].initialize( rxContext->getCenterText() ) ||
607 !maPortions[ HF_RIGHT ].initialize( rxContext->getRightText() ) )
608 return 0.0;
610 meCurrPortion = HF_CENTER;
611 maBuffer.setLength( 0 );
612 maFontModel = getStyles().getDefaultFontModel();
613 OUStringBuffer aFontName; // current font name
614 OUStringBuffer aFontStyle; // current font style
615 sal_Int32 nFontHeight = 0; // current font height
617 /** State of the parser. */
618 enum
620 STATE_TEXT, /// Literal text data.
621 STATE_TOKEN, /// Control token following a '&' character.
622 STATE_FONTNAME, /// Font name ('&' is followed by '"', reads until next '"' or ',').
623 STATE_FONTSTYLE, /// Font style name (font part after ',', reads until next '"').
624 STATE_FONTHEIGHT /// Font height ('&' is followed by num. digits, reads until non-digit).
626 eState = STATE_TEXT;
628 const sal_Unicode* pcChar = rData.getStr();
629 const sal_Unicode* pcEnd = pcChar + rData.getLength();
630 for( ; (pcChar != pcEnd) && (*pcChar != 0); ++pcChar )
632 sal_Unicode cChar = *pcChar;
633 switch( eState )
635 case STATE_TEXT:
637 switch( cChar )
639 case '&': // new token
640 appendText();
641 eState = STATE_TOKEN;
642 break;
643 case '\n': // line break
644 appendText();
645 appendLineBreak();
646 break;
647 default:
648 maBuffer.append( cChar );
651 break;
653 case STATE_TOKEN:
655 // default: back to text mode, may be changed in specific cases
656 eState = STATE_TEXT;
657 // ignore case of token codes
658 if( ('a' <= cChar) && (cChar <= 'z') )
659 (cChar -= 'a') += 'A';
660 switch( cChar )
662 case '&': maBuffer.append( cChar ); break; // the '&' character
664 case 'L': setNewPortion( HF_LEFT ); break; // left portion
665 case 'C': setNewPortion( HF_CENTER ); break; // center portion
666 case 'R': setNewPortion( HF_RIGHT ); break; // right portion
668 case 'P': // page number
669 appendField( createField( maPageNumberService ) );
670 break;
671 case 'N': // total page count
672 appendField( createField( maPageCountService ) );
673 break;
674 case 'A': // current sheet name
675 appendField( createField( maSheetNameService ) );
676 break;
678 case 'F': // file name
680 Reference< XTextContent > xContent = createField( maFileNameService );
681 PropertySet aPropSet( xContent );
682 aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::NAME_AND_EXT );
683 appendField( xContent );
685 break;
686 case 'Z': // file path (without file name), BIFF8 and OOX only
687 if( (getFilterType() == FILTER_OOX) || ((getFilterType() == FILTER_BIFF) && (getBiff() == BIFF8)) )
689 Reference< XTextContent > xContent = createField( maFileNameService );
690 PropertySet aPropSet( xContent );
691 // FilenameDisplayFormat::PATH not supported by Calc
692 aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::FULL );
693 appendField( xContent );
694 /* path only is not supported -- if we find a '&Z&F'
695 combination for path/name, skip the '&F' part */
696 if( (pcChar + 2 < pcEnd) && (pcChar[ 1 ] == '&') && ((pcChar[ 2 ] == 'f') || (pcChar[ 2 ] == 'F')) )
697 pcChar += 2;
699 break;
700 case 'D': // date
702 Reference< XTextContent > xContent = createField( maDateTimeService );
703 PropertySet aPropSet( xContent );
704 aPropSet.setProperty( PROP_IsDate, true );
705 appendField( xContent );
707 break;
708 case 'T': // time
710 Reference< XTextContent > xContent = createField( maDateTimeService );
711 PropertySet aPropSet( xContent );
712 aPropSet.setProperty( PROP_IsDate, false );
713 appendField( xContent );
715 break;
717 case 'B': // bold
718 setAttributes();
719 maFontModel.mbBold = !maFontModel.mbBold;
720 break;
721 case 'I': // italic
722 setAttributes();
723 maFontModel.mbItalic = !maFontModel.mbItalic;
724 break;
725 case 'U': // underline
726 setAttributes();
727 maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_single) ? XML_none : XML_single;
728 break;
729 case 'E': // double underline
730 setAttributes();
731 maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_double) ? XML_none : XML_double;
732 break;
733 case 'S': // strikeout
734 setAttributes();
735 maFontModel.mbStrikeout = !maFontModel.mbStrikeout;
736 break;
737 case 'X': // superscript
738 setAttributes();
739 maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_superscript) ? XML_baseline : XML_superscript;
740 break;
741 case 'Y': // subsrcipt
742 setAttributes();
743 maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_subscript) ? XML_baseline : XML_subscript;
744 break;
745 case 'O': // outlined
746 setAttributes();
747 maFontModel.mbOutline = !maFontModel.mbOutline;
748 break;
749 case 'H': // shadow
750 setAttributes();
751 maFontModel.mbShadow = !maFontModel.mbShadow;
752 break;
754 case 'K': // text color (not in BIFF)
755 if( (getFilterType() == FILTER_OOX) && (pcChar + 6 < pcEnd) )
757 setAttributes();
758 // eat the following 6 characters
759 convertFontColor( OUString( pcChar + 1, 6 ) );
760 pcChar += 6;
762 break;
764 case '\"': // font name
765 aFontName.setLength( 0 );
766 aFontStyle.setLength( 0 );
767 eState = STATE_FONTNAME;
768 break;
769 default:
770 if( ('0' <= cChar) && (cChar <= '9') ) // font size
772 nFontHeight = cChar - '0';
773 eState = STATE_FONTHEIGHT;
777 break;
779 case STATE_FONTNAME:
781 switch( cChar )
783 case '\"':
784 setAttributes();
785 convertFontName( aFontName.makeStringAndClear() );
786 eState = STATE_TEXT;
787 break;
788 case ',':
789 eState = STATE_FONTSTYLE;
790 break;
791 default:
792 aFontName.append( cChar );
795 break;
797 case STATE_FONTSTYLE:
799 switch( cChar )
801 case '\"':
802 setAttributes();
803 convertFontName( aFontName.makeStringAndClear() );
804 convertFontStyle( aFontStyle.makeStringAndClear() );
805 eState = STATE_TEXT;
806 break;
807 default:
808 aFontStyle.append( cChar );
811 break;
813 case STATE_FONTHEIGHT:
815 if( ('0' <= cChar) && (cChar <= '9') )
817 if( nFontHeight >= 0 )
819 nFontHeight *= 10;
820 nFontHeight += (cChar - '0');
821 if( nFontHeight > 1000 )
822 nFontHeight = -1;
825 else
827 if( nFontHeight > 0 )
829 setAttributes();
830 maFontModel.mfHeight = nFontHeight;
832 --pcChar;
833 eState = STATE_TEXT;
836 break;
840 // finalize
841 finalizePortion();
842 maPortions[ HF_LEFT ].mfTotalHeight += getCurrHeight( HF_LEFT );
843 maPortions[ HF_CENTER ].mfTotalHeight += getCurrHeight( HF_CENTER );
844 maPortions[ HF_RIGHT ].mfTotalHeight += getCurrHeight( HF_RIGHT );
846 return ::std::max( maPortions[ HF_LEFT ].mfTotalHeight,
847 ::std::max( maPortions[ HF_CENTER ].mfTotalHeight, maPortions[ HF_RIGHT ].mfTotalHeight ) );
850 // private --------------------------------------------------------------------
852 double HeaderFooterParser::getCurrHeight( HFPortionId ePortion ) const
854 double fMaxHt = maPortions[ ePortion ].mfCurrHeight;
855 return (fMaxHt == 0.0) ? maFontModel.mfHeight : fMaxHt;
858 double HeaderFooterParser::getCurrHeight() const
860 return getCurrHeight( meCurrPortion );
863 void HeaderFooterParser::updateCurrHeight( HFPortionId ePortion )
865 double& rfMaxHt = maPortions[ ePortion ].mfCurrHeight;
866 rfMaxHt = ::std::max( rfMaxHt, maFontModel.mfHeight );
869 void HeaderFooterParser::updateCurrHeight()
871 updateCurrHeight( meCurrPortion );
874 void HeaderFooterParser::setAttributes()
876 Reference< XTextRange > xRange( getStartPos(), UNO_QUERY );
877 getEndPos()->gotoRange( xRange, sal_False );
878 getEndPos()->gotoEnd( sal_True );
879 if( !getEndPos()->isCollapsed() )
881 Font aFont( *this, maFontModel );
882 aFont.finalizeImport();
883 PropertySet aPropSet( getEndPos() );
884 aFont.writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT );
885 getStartPos()->gotoEnd( sal_False );
886 getEndPos()->gotoEnd( sal_False );
890 void HeaderFooterParser::appendText()
892 if( maBuffer.getLength() > 0 )
894 getEndPos()->gotoEnd( sal_False );
895 getEndPos()->setString( maBuffer.makeStringAndClear() );
896 updateCurrHeight();
900 void HeaderFooterParser::appendLineBreak()
902 getEndPos()->gotoEnd( sal_False );
903 getEndPos()->setString( OUString( sal_Unicode( '\n' ) ) );
904 getPortion().mfTotalHeight += getCurrHeight();
905 getPortion().mfCurrHeight = 0;
908 Reference< XTextContent > HeaderFooterParser::createField( const OUString& rServiceName ) const
910 Reference< XTextContent > xContent;
913 Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW );
914 xContent.set( xFactory->createInstance( rServiceName ), UNO_QUERY_THROW );
916 catch( Exception& )
918 OSL_ENSURE( false,
919 OStringBuffer( "HeaderFooterParser::createField - error while creating text field \"" ).
920 append( OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ) ).
921 append( '"' ).getStr() );
923 return xContent;
926 void HeaderFooterParser::appendField( const Reference< XTextContent >& rxContent )
928 getEndPos()->gotoEnd( sal_False );
931 Reference< XTextRange > xRange( getEndPos(), UNO_QUERY_THROW );
932 getPortion().mxText->insertTextContent( xRange, rxContent, sal_False );
933 updateCurrHeight();
935 catch( Exception& )
940 void HeaderFooterParser::convertFontName( const OUString& rName )
942 if( rName.getLength() > 0 )
944 // single dash is document default font
945 if( (rName.getLength() == 1) && (rName[ 0 ] == '-') )
946 maFontModel.maName = getStyles().getDefaultFontModel().maName;
947 else
948 maFontModel.maName = rName;
952 void HeaderFooterParser::convertFontStyle( const OUString& rStyle )
954 maFontModel.mbBold = maFontModel.mbItalic = false;
955 sal_Int32 nPos = 0;
956 sal_Int32 nLen = rStyle.getLength();
957 while( (0 <= nPos) && (nPos < nLen) )
959 OString aToken = OUStringToOString( rStyle.getToken( 0, ' ', nPos ), RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase();
960 if( aToken.getLength() > 0 )
962 if( maBoldNames.count( aToken ) > 0 )
963 maFontModel.mbBold = true;
964 else if( maItalicNames.count( aToken ) > 0 )
965 maFontModel.mbItalic = true;
970 void HeaderFooterParser::convertFontColor( const OUString& rColor )
972 OSL_ENSURE( rColor.getLength() == 6, "HeaderFooterParser::convertFontColor - invalid font color code" );
973 if( (rColor[ 2 ] == '+') || (rColor[ 2 ] == '-') )
974 // theme color: TTSNNN (TT = decimal theme index, S = +/-, NNN = decimal tint/shade in percent)
975 maFontModel.maColor.setTheme(
976 rColor.copy( 0, 2 ).toInt32(),
977 static_cast< double >( rColor.copy( 2 ).toInt32() ) / 100.0 );
978 else
979 // RGB color: RRGGBB
980 maFontModel.maColor.setRgb( rColor.toInt32( 16 ) );
983 void HeaderFooterParser::finalizePortion()
985 appendText();
986 setAttributes();
989 void HeaderFooterParser::setNewPortion( HFPortionId ePortion )
991 if( ePortion != meCurrPortion )
993 finalizePortion();
994 meCurrPortion = ePortion;
995 maFontModel = getStyles().getDefaultFontModel();
999 // ============================================================================
1001 namespace {
1003 /** Paper size in 1/100 millimeters. */
1004 struct ApiPaperSize
1006 sal_Int32 mnWidth;
1007 sal_Int32 mnHeight;
1010 #define IN2MM100( v ) static_cast< sal_Int32 >( (v) * 2540.0 + 0.5 )
1011 #define MM2MM100( v ) static_cast< sal_Int32 >( (v) * 100.0 + 0.5 )
1013 static const ApiPaperSize spPaperSizeTable[] =
1015 { 0, 0 }, // 0 - (undefined)
1016 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 1 - Letter paper
1017 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 2 - Letter small paper
1018 { IN2MM100( 11 ), IN2MM100( 17 ) }, // 3 - Tabloid paper
1019 { IN2MM100( 17 ), IN2MM100( 11 ) }, // 4 - Ledger paper
1020 { IN2MM100( 8.5 ), IN2MM100( 14 ) }, // 5 - Legal paper
1021 { IN2MM100( 5.5 ), IN2MM100( 8.5 ) }, // 6 - Statement paper
1022 { IN2MM100( 7.25 ), IN2MM100( 10.5 ) }, // 7 - Executive paper
1023 { MM2MM100( 297 ), MM2MM100( 420 ) }, // 8 - A3 paper
1024 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 9 - A4 paper
1025 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 10 - A4 small paper
1026 { MM2MM100( 148 ), MM2MM100( 210 ) }, // 11 - A5 paper
1027 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 12 - B4 paper
1028 { MM2MM100( 176 ), MM2MM100( 250 ) }, // 13 - B5 paper
1029 { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 14 - Folio paper
1030 { MM2MM100( 215 ), MM2MM100( 275 ) }, // 15 - Quarto paper
1031 { IN2MM100( 10 ), IN2MM100( 14 ) }, // 16 - Standard paper
1032 { IN2MM100( 11 ), IN2MM100( 17 ) }, // 17 - Standard paper
1033 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 18 - Note paper
1034 { IN2MM100( 3.875 ), IN2MM100( 8.875 ) }, // 19 - #9 envelope
1035 { IN2MM100( 4.125 ), IN2MM100( 9.5 ) }, // 20 - #10 envelope
1036 { IN2MM100( 4.5 ), IN2MM100( 10.375 ) }, // 21 - #11 envelope
1037 { IN2MM100( 4.75 ), IN2MM100( 11 ) }, // 22 - #12 envelope
1038 { IN2MM100( 5 ), IN2MM100( 11.5 ) }, // 23 - #14 envelope
1039 { IN2MM100( 17 ), IN2MM100( 22 ) }, // 24 - C paper
1040 { IN2MM100( 22 ), IN2MM100( 34 ) }, // 25 - D paper
1041 { IN2MM100( 34 ), IN2MM100( 44 ) }, // 26 - E paper
1042 { MM2MM100( 110 ), MM2MM100( 220 ) }, // 27 - DL envelope
1043 { MM2MM100( 162 ), MM2MM100( 229 ) }, // 28 - C5 envelope
1044 { MM2MM100( 324 ), MM2MM100( 458 ) }, // 29 - C3 envelope
1045 { MM2MM100( 229 ), MM2MM100( 324 ) }, // 30 - C4 envelope
1046 { MM2MM100( 114 ), MM2MM100( 162 ) }, // 31 - C6 envelope
1047 { MM2MM100( 114 ), MM2MM100( 229 ) }, // 32 - C65 envelope
1048 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 33 - B4 envelope
1049 { MM2MM100( 176 ), MM2MM100( 250 ) }, // 34 - B5 envelope
1050 { MM2MM100( 176 ), MM2MM100( 125 ) }, // 35 - B6 envelope
1051 { MM2MM100( 110 ), MM2MM100( 230 ) }, // 36 - Italy envelope
1052 { IN2MM100( 3.875 ), IN2MM100( 7.5 ) }, // 37 - Monarch envelope
1053 { IN2MM100( 3.625 ), IN2MM100( 6.5 ) }, // 38 - 6 3/4 envelope
1054 { IN2MM100( 14.875 ), IN2MM100( 11 ) }, // 39 - US standard fanfold
1055 { IN2MM100( 8.5 ), IN2MM100( 12 ) }, // 40 - German standard fanfold
1056 { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 41 - German legal fanfold
1057 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 42 - ISO B4
1058 { MM2MM100( 200 ), MM2MM100( 148 ) }, // 43 - Japanese double postcard
1059 { IN2MM100( 9 ), IN2MM100( 11 ) }, // 44 - Standard paper
1060 { IN2MM100( 10 ), IN2MM100( 11 ) }, // 45 - Standard paper
1061 { IN2MM100( 15 ), IN2MM100( 11 ) }, // 46 - Standard paper
1062 { MM2MM100( 220 ), MM2MM100( 220 ) }, // 47 - Invite envelope
1063 { 0, 0 }, // 48 - (undefined)
1064 { 0, 0 }, // 49 - (undefined)
1065 { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 50 - Letter extra paper
1066 { IN2MM100( 9.275 ), IN2MM100( 15 ) }, // 51 - Legal extra paper
1067 { IN2MM100( 11.69 ), IN2MM100( 18 ) }, // 52 - Tabloid extra paper
1068 { MM2MM100( 236 ), MM2MM100( 322 ) }, // 53 - A4 extra paper
1069 { IN2MM100( 8.275 ), IN2MM100( 11 ) }, // 54 - Letter transverse paper
1070 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 55 - A4 transverse paper
1071 { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 56 - Letter extra transverse paper
1072 { MM2MM100( 227 ), MM2MM100( 356 ) }, // 57 - SuperA/SuperA/A4 paper
1073 { MM2MM100( 305 ), MM2MM100( 487 ) }, // 58 - SuperB/SuperB/A3 paper
1074 { IN2MM100( 8.5 ), IN2MM100( 12.69 ) }, // 59 - Letter plus paper
1075 { MM2MM100( 210 ), MM2MM100( 330 ) }, // 60 - A4 plus paper
1076 { MM2MM100( 148 ), MM2MM100( 210 ) }, // 61 - A5 transverse paper
1077 { MM2MM100( 182 ), MM2MM100( 257 ) }, // 62 - JIS B5 transverse paper
1078 { MM2MM100( 322 ), MM2MM100( 445 ) }, // 63 - A3 extra paper
1079 { MM2MM100( 174 ), MM2MM100( 235 ) }, // 64 - A5 extra paper
1080 { MM2MM100( 201 ), MM2MM100( 276 ) }, // 65 - ISO B5 extra paper
1081 { MM2MM100( 420 ), MM2MM100( 594 ) }, // 66 - A2 paper
1082 { MM2MM100( 297 ), MM2MM100( 420 ) }, // 67 - A3 transverse paper
1083 { MM2MM100( 322 ), MM2MM100( 445 ) } // 68 - A3 extra transverse paper
1086 } // namespace
1088 // ----------------------------------------------------------------------------
1090 PageSettingsConverter::HFHelperData::HFHelperData( sal_Int32 nLeftPropId, sal_Int32 nRightPropId ) :
1091 mnLeftPropId( nLeftPropId ),
1092 mnRightPropId( nRightPropId ),
1093 mnHeight( 0 ),
1094 mnBodyDist( 0 ),
1095 mbHasContent( false ),
1096 mbShareOddEven( false ),
1097 mbDynamicHeight( false )
1101 // ----------------------------------------------------------------------------
1103 PageSettingsConverter::PageSettingsConverter( const WorkbookHelper& rHelper ) :
1104 WorkbookHelper( rHelper ),
1105 mxHFParser( new HeaderFooterParser( rHelper ) ),
1106 maHeaderData( PROP_LeftPageHeaderContent, PROP_RightPageHeaderContent ),
1107 maFooterData( PROP_LeftPageFooterContent, PROP_RightPageFooterContent )
1111 PageSettingsConverter::~PageSettingsConverter()
1115 void PageSettingsConverter::writePageSettingsProperties(
1116 PropertySet& rPropSet, const PageSettingsModel& rModel, WorksheetType eSheetType )
1118 // special handling for chart sheets
1119 bool bChartSheet = eSheetType == SHEETTYPE_CHARTSHEET;
1121 // printout scaling
1122 if( bChartSheet )
1124 // always fit chart sheet to 1 page
1125 rPropSet.setProperty< sal_Int16 >( PROP_ScaleToPages, 1 );
1127 else if( rModel.mbFitToPages )
1129 // fit to number of pages
1130 rPropSet.setProperty( PROP_ScaleToPagesX, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToWidth, 0, 1000 ) );
1131 rPropSet.setProperty( PROP_ScaleToPagesY, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToHeight, 0, 1000 ) );
1133 else
1135 // scale may be 0 which indicates uninitialized
1136 sal_Int16 nScale = (rModel.mbValidSettings && (rModel.mnScale > 0)) ? getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnScale, 10, 400 ) : 100;
1137 rPropSet.setProperty( PROP_PageScale, nScale );
1140 // paper orientation
1141 bool bLandscape = rModel.mnOrientation == XML_landscape;
1142 // default orientation for current sheet type (chart sheets default to landscape)
1143 if( !rModel.mbValidSettings || (rModel.mnOrientation == XML_default) )
1144 bLandscape = bChartSheet;
1146 // paper size
1147 if( rModel.mbValidSettings && (0 < rModel.mnPaperSize) && (rModel.mnPaperSize < static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( spPaperSizeTable ) )) )
1149 const ApiPaperSize& rPaperSize = spPaperSizeTable[ rModel.mnPaperSize ];
1150 Size aSize( rPaperSize.mnWidth, rPaperSize.mnHeight );
1151 if( bLandscape )
1152 ::std::swap( aSize.Width, aSize.Height );
1153 rPropSet.setProperty( PROP_Size, aSize );
1156 // header/footer
1157 convertHeaderFooterData( rPropSet, maHeaderData, rModel.maOddHeader, rModel.maEvenHeader, rModel.mbUseEvenHF, rModel.mfTopMargin, rModel.mfHeaderMargin );
1158 convertHeaderFooterData( rPropSet, maFooterData, rModel.maOddFooter, rModel.maEvenFooter, rModel.mbUseEvenHF, rModel.mfBottomMargin, rModel.mfFooterMargin );
1160 // write all properties to property set
1161 const UnitConverter& rUnitConv = getUnitConverter();
1162 PropertyMap aPropMap;
1163 aPropMap[ PROP_IsLandscape ] <<= bLandscape;
1164 aPropMap[ PROP_FirstPageNumber ] <<= getLimitedValue< sal_Int16, sal_Int32 >( rModel.mbUseFirstPage ? rModel.mnFirstPage : 0, 0, 9999 );
1165 aPropMap[ PROP_PrintDownFirst ] <<= (rModel.mnPageOrder == XML_downThenOver);
1166 aPropMap[ PROP_PrintAnnotations ] <<= (rModel.mnCellComments == XML_asDisplayed);
1167 aPropMap[ PROP_CenterHorizontally ] <<= rModel.mbHorCenter;
1168 aPropMap[ PROP_CenterVertically ] <<= rModel.mbVerCenter;
1169 aPropMap[ PROP_PrintGrid ] <<= (!bChartSheet && rModel.mbPrintGrid); // no gridlines in chart sheets
1170 aPropMap[ PROP_PrintHeaders ] <<= (!bChartSheet && rModel.mbPrintHeadings); // no column/row headings in chart sheets
1171 aPropMap[ PROP_LeftMargin ] <<= rUnitConv.scaleToMm100( rModel.mfLeftMargin, UNIT_INCH );
1172 aPropMap[ PROP_RightMargin ] <<= rUnitConv.scaleToMm100( rModel.mfRightMargin, UNIT_INCH );
1173 // #i23296# In Calc, "TopMargin" property is distance to top of header if enabled
1174 aPropMap[ PROP_TopMargin ] <<= rUnitConv.scaleToMm100( maHeaderData.mbHasContent ? rModel.mfHeaderMargin : rModel.mfTopMargin, UNIT_INCH );
1175 // #i23296# In Calc, "BottomMargin" property is distance to bottom of footer if enabled
1176 aPropMap[ PROP_BottomMargin ] <<= rUnitConv.scaleToMm100( maFooterData.mbHasContent ? rModel.mfFooterMargin : rModel.mfBottomMargin, UNIT_INCH );
1177 aPropMap[ PROP_HeaderIsOn ] <<= maHeaderData.mbHasContent;
1178 aPropMap[ PROP_HeaderIsShared ] <<= maHeaderData.mbShareOddEven;
1179 aPropMap[ PROP_HeaderIsDynamicHeight ] <<= maHeaderData.mbDynamicHeight;
1180 aPropMap[ PROP_HeaderHeight ] <<= maHeaderData.mnHeight;
1181 aPropMap[ PROP_HeaderBodyDistance ] <<= maHeaderData.mnBodyDist;
1182 aPropMap[ PROP_FooterIsOn ] <<= maFooterData.mbHasContent;
1183 aPropMap[ PROP_FooterIsShared ] <<= maFooterData.mbShareOddEven;
1184 aPropMap[ PROP_FooterIsDynamicHeight ] <<= maFooterData.mbDynamicHeight;
1185 aPropMap[ PROP_FooterHeight ] <<= maFooterData.mnHeight;
1186 aPropMap[ PROP_FooterBodyDistance ] <<= maFooterData.mnBodyDist;
1187 // background image
1188 if( rModel.maGraphicUrl.getLength() > 0 )
1190 aPropMap[ PROP_BackGraphicURL ] <<= rModel.maGraphicUrl;
1191 aPropMap[ PROP_BackGraphicLocation ] <<= ::com::sun::star::style::GraphicLocation_TILED;
1194 rPropSet.setProperties( aPropMap );
1197 void PageSettingsConverter::convertHeaderFooterData(
1198 PropertySet& rPropSet, HFHelperData& orHFData,
1199 const OUString rOddContent, const OUString rEvenContent, bool bUseEvenContent,
1200 double fPageMargin, double fContentMargin )
1202 bool bHasOddContent = rOddContent.getLength() > 0;
1203 bool bHasEvenContent = bUseEvenContent && (rEvenContent.getLength() > 0);
1205 sal_Int32 nOddHeight = bHasOddContent ? writeHeaderFooter( rPropSet, orHFData.mnRightPropId, rOddContent ) : 0;
1206 sal_Int32 nEvenHeight = bHasEvenContent ? writeHeaderFooter( rPropSet, orHFData.mnLeftPropId, rEvenContent ) : 0;
1208 orHFData.mnHeight = 750;
1209 orHFData.mnBodyDist = 250;
1210 orHFData.mbHasContent = bHasOddContent || bHasEvenContent;
1211 orHFData.mbShareOddEven = !bUseEvenContent;
1212 orHFData.mbDynamicHeight = true;
1214 if( orHFData.mbHasContent )
1216 // use maximum height of odd/even header/footer
1217 orHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight );
1218 /* Calc contains distance between bottom of header and top of page
1219 body in "HeaderBodyDistance" property, and distance between bottom
1220 of page body and top of footer in "FooterBodyDistance" property */
1221 orHFData.mnBodyDist = getUnitConverter().scaleToMm100( fPageMargin - fContentMargin, UNIT_INCH ) - orHFData.mnHeight;
1222 /* #i23296# Distance less than 0 means, header or footer overlays page
1223 body. As this is not possible in Calc, set fixed header or footer
1224 height (crop header/footer) to get correct top position of page body. */
1225 orHFData.mbDynamicHeight = orHFData.mnBodyDist >= 0;
1226 /* "HeaderHeight" property is in fact distance from top of header to
1227 top of page body (including "HeaderBodyDistance").
1228 "FooterHeight" property is in fact distance from bottom of page
1229 body to bottom of footer (including "FooterBodyDistance"). */
1230 orHFData.mnHeight += orHFData.mnBodyDist;
1231 // negative body distance not allowed
1232 orHFData.mnBodyDist = ::std::max< sal_Int32 >( orHFData.mnBodyDist, 0 );
1236 sal_Int32 PageSettingsConverter::writeHeaderFooter(
1237 PropertySet& rPropSet, sal_Int32 nPropId, const OUString& rContent )
1239 OSL_ENSURE( rContent.getLength() > 0, "PageSettingsConverter::writeHeaderFooter - empty h/f string found" );
1240 sal_Int32 nHeight = 0;
1241 if( rContent.getLength() > 0 )
1243 Reference< XHeaderFooterContent > xHFContent;
1244 if( rPropSet.getProperty( xHFContent, nPropId ) && xHFContent.is() )
1246 double fTotalHeight = mxHFParser->parse( xHFContent, rContent );
1247 rPropSet.setProperty( nPropId, xHFContent );
1248 nHeight = getUnitConverter().scaleToMm100( fTotalHeight, UNIT_POINT );
1251 return nHeight;
1254 // ============================================================================
1256 } // namespace xls
1257 } // namespace oox