update dev300-m58
[ooovba.git] / sc / source / filter / excel / xepage.cxx
blobf99b732b79646edc16c7a17b6fddfb4cce4b587d
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: xepage.cxx,v $
10 * $Revision: 1.15.90.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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "xepage.hxx"
35 #include <svtools/itemset.hxx>
36 #include "scitems.hxx"
37 #include <svtools/eitem.hxx>
38 #include <svtools/intitem.hxx>
39 #include <svx/pageitem.hxx>
40 #include <svx/sizeitem.hxx>
41 #include <svx/lrspitem.hxx>
42 #include <svx/ulspitem.hxx>
43 #include <svx/brshitem.hxx>
44 #include "document.hxx"
45 #include "stlpool.hxx"
46 #include "stlsheet.hxx"
47 #include "attrib.hxx"
48 #include "xehelper.hxx"
49 #include "xeescher.hxx"
51 #include <set>
52 #include <limits>
54 #include <oox/core/tokens.hxx>
56 using ::rtl::OString;
57 using ::std::set;
58 using ::std::numeric_limits;
60 // Page settings records ======================================================
62 // Header/footer --------------------------------------------------------------
64 XclExpHeaderFooter::XclExpHeaderFooter( sal_uInt16 nRecId, const String& rHdrString ) :
65 XclExpRecord( nRecId ),
66 maHdrString( rHdrString )
70 void XclExpHeaderFooter::SaveXml( XclExpXmlStream& rStrm )
72 sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
73 sal_Int32 nElement = GetRecId() == EXC_ID_HEADER ? XML_oddHeader : XML_oddFooter;
74 rWorksheet->startElement( nElement, FSEND );
75 rWorksheet->writeEscaped( XclXmlUtils::ToOUString( maHdrString ) );
76 rWorksheet->endElement( nElement );
79 void XclExpHeaderFooter::WriteBody( XclExpStream& rStrm )
81 if( maHdrString.Len() )
83 XclExpString aExString;
84 if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
85 aExString.AssignByte( maHdrString, rStrm.GetRoot().GetTextEncoding(), EXC_STR_8BITLENGTH );
86 else
87 aExString.Assign( maHdrString, EXC_STR_DEFAULT, 255 ); // 16-bit length, but max 255 chars
88 rStrm << aExString;
92 // General page settings ------------------------------------------------------
94 XclExpSetup::XclExpSetup( const XclPageData& rPageData ) :
95 XclExpRecord( EXC_ID_SETUP, 34 ),
96 mrData( rPageData )
100 void XclExpSetup::SaveXml( XclExpXmlStream& rStrm )
102 rStrm.GetCurrentStream()->singleElement( XML_pageSetup,
103 XML_paperSize, OString::valueOf( (sal_Int32) mrData.mnPaperSize ).getStr(),
104 XML_scale, OString::valueOf( (sal_Int32) mrData.mnScaling ).getStr(),
105 XML_firstPageNumber, OString::valueOf( (sal_Int32) mrData.mnStartPage ).getStr(),
106 XML_fitToWidth, OString::valueOf( (sal_Int32) mrData.mnFitToWidth ).getStr(),
107 XML_fitToHeight, OString::valueOf( (sal_Int32) mrData.mnFitToHeight ).getStr(),
108 XML_pageOrder, mrData.mbPrintInRows ? "overThenDown" : "downThenOver",
109 XML_orientation, mrData.mbPortrait ? "portrait" : "landscape", // OOXTODO: "default"?
110 XML_usePrinterDefaults, XclXmlUtils::ToPsz( !mrData.mbValid ),
111 XML_blackAndWhite, XclXmlUtils::ToPsz( mrData.mbBlackWhite ),
112 XML_draft, XclXmlUtils::ToPsz( mrData.mbDraftQuality ),
113 XML_cellComments, mrData.mbPrintNotes ? "atEnd" : "none", // OOXTODO: "asDisplayed"?
114 XML_useFirstPageNumber, XclXmlUtils::ToPsz( mrData.mbManualStart ),
115 // OOXTODO: XML_errors, // == displayed|blank|dash|NA
116 XML_horizontalDpi, OString::valueOf( (sal_Int32) mrData.mnHorPrintRes ).getStr(),
117 XML_verticalDpi, OString::valueOf( (sal_Int32) mrData.mnVerPrintRes ).getStr(),
118 XML_copies, OString::valueOf( (sal_Int32) mrData.mnCopies ).getStr(),
119 // OOXTODO: devMode settings part RelationshipId: FSNS( XML_r, XML_id ),
120 FSEND );
123 void XclExpSetup::WriteBody( XclExpStream& rStrm )
125 XclBiff eBiff = rStrm.GetRoot().GetBiff();
127 sal_uInt16 nFlags = 0;
128 ::set_flag( nFlags, EXC_SETUP_INROWS, mrData.mbPrintInRows );
129 ::set_flag( nFlags, EXC_SETUP_PORTRAIT, mrData.mbPortrait );
130 ::set_flag( nFlags, EXC_SETUP_INVALID, !mrData.mbValid );
131 ::set_flag( nFlags, EXC_SETUP_BLACKWHITE, mrData.mbBlackWhite );
132 if( eBiff >= EXC_BIFF5 )
134 ::set_flag( nFlags, EXC_SETUP_DRAFT, mrData.mbDraftQuality );
135 /* Set the Comments/Notes to "At end of sheet" if Print Notes is true.
136 We don't currently support "as displayed on sheet". Thus this value
137 will be re-interpreted to "At end of sheet". */
138 const sal_uInt16 nNotes = EXC_SETUP_PRINTNOTES | EXC_SETUP_NOTES_END;
139 ::set_flag( nFlags, nNotes, mrData.mbPrintNotes );
140 ::set_flag( nFlags, EXC_SETUP_STARTPAGE, mrData.mbManualStart );
143 rStrm << mrData.mnPaperSize << mrData.mnScaling << mrData.mnStartPage
144 << mrData.mnFitToWidth << mrData.mnFitToHeight << nFlags;
145 if( eBiff >= EXC_BIFF5 )
147 rStrm << mrData.mnHorPrintRes << mrData.mnVerPrintRes
148 << mrData.mfHeaderMargin << mrData.mfFooterMargin << mrData.mnCopies;
152 // Manual page breaks ---------------------------------------------------------
154 XclExpPageBreaks::XclExpPageBreaks( sal_uInt16 nRecId, const ScfUInt16Vec& rPageBreaks, sal_uInt16 nMaxPos ) :
155 XclExpRecord( nRecId ),
156 mrPageBreaks( rPageBreaks ),
157 mnMaxPos( nMaxPos )
161 void XclExpPageBreaks::Save( XclExpStream& rStrm )
163 if( !mrPageBreaks.empty() )
165 SetRecSize( 2 + ((rStrm.GetRoot().GetBiff() <= EXC_BIFF5) ? 2 : 6) * mrPageBreaks.size() );
166 XclExpRecord::Save( rStrm );
170 void XclExpPageBreaks::WriteBody( XclExpStream& rStrm )
172 bool bWriteRange = (rStrm.GetRoot().GetBiff() == EXC_BIFF8);
174 rStrm << static_cast< sal_uInt16 >( mrPageBreaks.size() );
175 for( ScfUInt16Vec::const_iterator aIt = mrPageBreaks.begin(), aEnd = mrPageBreaks.end(); aIt != aEnd; ++aIt )
177 rStrm << *aIt;
178 if( bWriteRange )
179 rStrm << sal_uInt16( 0 ) << mnMaxPos;
183 void XclExpPageBreaks::SaveXml( XclExpXmlStream& rStrm )
185 if( mrPageBreaks.empty() )
186 return;
188 sal_Int32 nElement = GetRecId() == EXC_ID_HORPAGEBREAKS ? XML_rowBreaks : XML_colBreaks;
189 sax_fastparser::FSHelperPtr& pWorksheet = rStrm.GetCurrentStream();
190 OString sNumPageBreaks = OString::valueOf( (sal_Int32) mrPageBreaks.size() );
191 pWorksheet->startElement( nElement,
192 XML_count, sNumPageBreaks.getStr(),
193 XML_manualBreakCount, sNumPageBreaks.getStr(),
194 FSEND );
195 for( ScfUInt16Vec::const_iterator aIt = mrPageBreaks.begin(), aEnd = mrPageBreaks.end(); aIt != aEnd; ++aIt )
197 pWorksheet->singleElement( XML_brk,
198 XML_id, OString::valueOf( (sal_Int32) *aIt ).getStr(),
199 XML_man, "true",
200 XML_max, OString::valueOf( (sal_Int32) mnMaxPos ).getStr(),
201 XML_min, "0",
202 // OOXTODO: XML_pt, "",
203 FSEND );
205 pWorksheet->endElement( nElement );
208 // Page settings ==============================================================
210 XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
211 XclExpRoot( rRoot )
213 ScDocument& rDoc = GetDoc();
214 SCTAB nScTab = GetCurrScTab();
216 if( SfxStyleSheetBase* pStyleSheet = GetStyleSheetPool().Find( rDoc.GetPageStyle( nScTab ), SFX_STYLE_FAMILY_PAGE ) )
218 const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
219 maData.mbValid = true;
221 // *** page settings ***
223 maData.mbPrintInRows = !GETITEMBOOL( rItemSet, ATTR_PAGE_TOPDOWN );
224 maData.mbHorCenter = GETITEMBOOL( rItemSet, ATTR_PAGE_HORCENTER );
225 maData.mbVerCenter = GETITEMBOOL( rItemSet, ATTR_PAGE_VERCENTER );
226 maData.mbPrintHeadings = GETITEMBOOL( rItemSet, ATTR_PAGE_HEADERS );
227 maData.mbPrintGrid = GETITEMBOOL( rItemSet, ATTR_PAGE_GRID );
228 maData.mbPrintNotes = GETITEMBOOL( rItemSet, ATTR_PAGE_NOTES );
230 maData.mnStartPage = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_FIRSTPAGENO, sal_uInt16 );
231 maData.mbManualStart = maData.mnStartPage && (!nScTab || rDoc.NeedPageResetAfterTab( nScTab - 1 ));
233 const SvxLRSpaceItem& rLRItem = GETITEM( rItemSet, SvxLRSpaceItem, ATTR_LRSPACE );
234 maData.mfLeftMargin = XclTools::GetInchFromTwips( rLRItem.GetLeft() );
235 maData.mfRightMargin = XclTools::GetInchFromTwips( rLRItem.GetRight() );
236 const SvxULSpaceItem& rULItem = GETITEM( rItemSet, SvxULSpaceItem, ATTR_ULSPACE );
237 maData.mfTopMargin = XclTools::GetInchFromTwips( rULItem.GetUpper() );
238 maData.mfBottomMargin = XclTools::GetInchFromTwips( rULItem.GetLower() );
240 const SvxPageItem& rPageItem = GETITEM( rItemSet, SvxPageItem, ATTR_PAGE );
241 const SvxSizeItem& rSizeItem = GETITEM( rItemSet, SvxSizeItem, ATTR_PAGE_SIZE );
242 maData.SetScPaperSize( rSizeItem.GetSize(), !rPageItem.IsLandscape() );
244 const ScPageScaleToItem& rScaleToItem = GETITEM( rItemSet, ScPageScaleToItem, ATTR_PAGE_SCALETO );
245 sal_uInt16 nPages = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_SCALETOPAGES, sal_uInt16 );
246 sal_uInt16 nScale = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_SCALE, sal_uInt16 );
248 if( ScfTools::CheckItem( rItemSet, ATTR_PAGE_SCALETO, false ) && rScaleToItem.IsValid() )
250 maData.mnFitToWidth = rScaleToItem.GetWidth();
251 maData.mnFitToHeight = rScaleToItem.GetHeight();
252 maData.mbFitToPages = true;
255 else if( ScfTools::CheckItem( rItemSet, ATTR_PAGE_SCALETOPAGES, false ) && nPages )
257 maData.mnFitToWidth = 1;
258 maData.mnFitToHeight = nPages;
259 maData.mbFitToPages = true;
261 else if( nScale )
263 maData.mnScaling = nScale;
264 maData.mbFitToPages = false;
267 maData.mxBrushItem.reset( new SvxBrushItem( GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND ) ) );
269 // *** header and footer ***
271 XclExpHFConverter aHFConv( GetRoot() );
273 // header
274 const SfxItemSet& rHdrItemSet = GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_HEADERSET ).GetItemSet();
275 if( GETITEMBOOL( rHdrItemSet, ATTR_PAGE_ON ) )
277 const ScPageHFItem& rHFItem = GETITEM( rItemSet, ScPageHFItem, ATTR_PAGE_HEADERRIGHT );
278 aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
279 maData.maHeader = aHFConv.GetHFString();
280 // header height (Excel excludes header from top margin)
281 sal_Int32 nHdrHeight = GETITEMBOOL( rHdrItemSet, ATTR_PAGE_DYNAMIC ) ?
282 // dynamic height: calculate header height, add header <-> sheet area distance
283 (aHFConv.GetTotalHeight() + GETITEM( rHdrItemSet, SvxULSpaceItem, ATTR_ULSPACE ).GetLower()) :
284 // static height: ATTR_PAGE_SIZE already includes header <-> sheet area distance
285 static_cast< sal_Int32 >( GETITEM( rHdrItemSet, SvxSizeItem, ATTR_PAGE_SIZE ).GetSize().Height() );
286 maData.mfHeaderMargin = maData.mfTopMargin;
287 maData.mfTopMargin += XclTools::GetInchFromTwips( nHdrHeight );
290 // footer
291 const SfxItemSet& rFtrItemSet = GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_FOOTERSET ).GetItemSet();
292 if( GETITEMBOOL( rFtrItemSet, ATTR_PAGE_ON ) )
294 const ScPageHFItem& rHFItem = GETITEM( rItemSet, ScPageHFItem, ATTR_PAGE_FOOTERRIGHT );
295 aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
296 maData.maFooter = aHFConv.GetHFString();
297 // footer height (Excel excludes footer from bottom margin)
298 sal_Int32 nFtrHeight = GETITEMBOOL( rFtrItemSet, ATTR_PAGE_DYNAMIC ) ?
299 // dynamic height: calculate footer height, add sheet area <-> footer distance
300 (aHFConv.GetTotalHeight() + GETITEM( rFtrItemSet, SvxULSpaceItem, ATTR_ULSPACE ).GetUpper()) :
301 // static height: ATTR_PAGE_SIZE already includes sheet area <-> footer distance
302 static_cast< sal_Int32 >( GETITEM( rFtrItemSet, SvxSizeItem, ATTR_PAGE_SIZE ).GetSize().Height() );
303 maData.mfFooterMargin = maData.mfBottomMargin;
304 maData.mfBottomMargin += XclTools::GetInchFromTwips( nFtrHeight );
308 // *** page breaks ***
310 set<SCROW> aRowBreaks;
311 rDoc.GetAllRowBreaks(aRowBreaks, nScTab, false, true);
313 SCROW nMaxRow = numeric_limits<sal_uInt16>::max();
314 for (set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end(); itr != itrEnd; ++itr)
316 SCROW nRow = *itr;
317 if (nRow > nMaxRow)
318 break;
320 maData.maHorPageBreaks.push_back(nRow);
323 set<SCCOL> aColBreaks;
324 rDoc.GetAllColBreaks(aColBreaks, nScTab, false, true);
325 for (set<SCCOL>::const_iterator itr = aColBreaks.begin(), itrEnd = aColBreaks.end(); itr != itrEnd; ++itr)
326 maData.maVerPageBreaks.push_back(*itr);
329 static void lcl_WriteHeaderFooter( XclExpXmlStream& rStrm )
331 // OOXTODO: we currently only emit oddHeader/oddFooter elements, and
332 // do not support the first/even/odd page distinction.
333 rStrm.WriteAttributes(
334 // OOXTODO: XML_alignWithMargins,
335 XML_differentFirst, "false", // OOXTODO
336 XML_differentOddEven, "false", // OOXTODO
337 // OOXTODO: XML_scaleWithDoc
338 FSEND );
339 rStrm.GetCurrentStream()->write( ">" );
342 void XclExpPageSettings::Save( XclExpStream& rStrm )
344 XclExpBoolRecord( EXC_ID_PRINTHEADERS, maData.mbPrintHeadings ).Save( rStrm );
345 XclExpBoolRecord( EXC_ID_PRINTGRIDLINES, maData.mbPrintGrid ).Save( rStrm );
346 XclExpBoolRecord( EXC_ID_GRIDSET, true ).Save( rStrm );
347 XclExpPageBreaks( EXC_ID_HORPAGEBREAKS, maData.maHorPageBreaks, static_cast< sal_uInt16 >( GetXclMaxPos().Col() ) ).Save( rStrm );
348 XclExpPageBreaks( EXC_ID_VERPAGEBREAKS, maData.maVerPageBreaks, static_cast< sal_uInt16 >( GetXclMaxPos().Row() ) ).Save( rStrm );
349 XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).Save( rStrm );
350 XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).Save( rStrm );
351 XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter ).Save( rStrm );
352 XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter ).Save( rStrm );
353 XclExpDoubleRecord( EXC_ID_LEFTMARGIN, maData.mfLeftMargin ).Save( rStrm );
354 XclExpDoubleRecord( EXC_ID_RIGHTMARGIN, maData.mfRightMargin ).Save( rStrm );
355 XclExpDoubleRecord( EXC_ID_TOPMARGIN, maData.mfTopMargin ).Save( rStrm );
356 XclExpDoubleRecord( EXC_ID_BOTTOMMARGIN, maData.mfBottomMargin ).Save( rStrm );
357 XclExpSetup( maData ).Save( rStrm );
359 if( (GetBiff() == EXC_BIFF8) && maData.mxBrushItem.get() )
360 if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() )
361 XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ).Save( rStrm );
364 void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm )
366 XclExpXmlStartSingleElementRecord( XML_printOptions ).SaveXml( rStrm );
367 XclExpBoolRecord( EXC_ID_PRINTHEADERS, maData.mbPrintHeadings, XML_headings ).SaveXml( rStrm );
368 XclExpBoolRecord( EXC_ID_PRINTGRIDLINES, maData.mbPrintGrid, XML_gridLines ).SaveXml( rStrm );
369 XclExpBoolRecord( EXC_ID_GRIDSET, true, XML_gridLinesSet ).SaveXml( rStrm );
370 XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter, XML_horizontalCentered ).SaveXml( rStrm );
371 XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter, XML_verticalCentered ).SaveXml( rStrm );
372 XclExpXmlEndSingleElementRecord().SaveXml( rStrm ); // XML_printOptions
374 XclExpXmlStartSingleElementRecord( XML_pageMargins ).SaveXml( rStrm );
375 XclExpDoubleRecord( EXC_ID_LEFTMARGIN, maData.mfLeftMargin ).SetAttribute( XML_left )->SaveXml( rStrm );
376 XclExpDoubleRecord( EXC_ID_RIGHTMARGIN, maData.mfRightMargin ).SetAttribute( XML_right )->SaveXml( rStrm );
377 XclExpDoubleRecord( EXC_ID_TOPMARGIN, maData.mfTopMargin ).SetAttribute( XML_top )->SaveXml( rStrm );
378 XclExpDoubleRecord( EXC_ID_BOTTOMMARGIN, maData.mfBottomMargin ).SetAttribute( XML_bottom )->SaveXml( rStrm );
379 XclExpDoubleRecord( 0, maData.mfHeaderMargin).SetAttribute( XML_header )->SaveXml( rStrm );
380 XclExpDoubleRecord( 0, maData.mfFooterMargin).SetAttribute( XML_footer )->SaveXml( rStrm );
381 XclExpXmlEndSingleElementRecord().SaveXml( rStrm ); // XML_pageMargins
383 XclExpSetup( maData ).SaveXml( rStrm );
385 XclExpXmlStartElementRecord( XML_headerFooter, lcl_WriteHeaderFooter ).SaveXml( rStrm );
386 XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).SaveXml( rStrm );
387 XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).SaveXml( rStrm );
388 XclExpXmlEndElementRecord( XML_headerFooter ).SaveXml( rStrm );
390 XclExpPageBreaks( EXC_ID_HORPAGEBREAKS, maData.maHorPageBreaks,
391 static_cast< sal_uInt16 >( GetXclMaxPos().Col() ) ).SaveXml( rStrm );
392 XclExpPageBreaks( EXC_ID_VERPAGEBREAKS, maData.maVerPageBreaks,
393 static_cast< sal_uInt16 >( GetXclMaxPos().Row() ) ).SaveXml( rStrm );
395 if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() )
396 XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ).SaveXml( rStrm );
399 // ----------------------------------------------------------------------------
401 XclExpChartPageSettings::XclExpChartPageSettings( const XclExpRoot& rRoot ) :
402 XclExpRoot( rRoot )
406 void XclExpChartPageSettings::Save( XclExpStream& rStrm )
408 XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).Save( rStrm );
409 XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).Save( rStrm );
410 XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter ).Save( rStrm );
411 XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter ).Save( rStrm );
412 XclExpSetup( maData ).Save( rStrm );
413 XclExpUInt16Record( EXC_ID_PRINTSIZE, EXC_PRINTSIZE_FULL ).Save( rStrm );
416 // ============================================================================