1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <svl/itemset.hxx>
22 #include <vcl/graph.hxx>
23 #include "scitems.hxx"
24 #include <svl/eitem.hxx>
25 #include <svl/intitem.hxx>
26 #include <svx/pageitem.hxx>
27 #include <editeng/sizeitem.hxx>
28 #include <editeng/lrspitem.hxx>
29 #include <editeng/ulspitem.hxx>
30 #include <editeng/brushitem.hxx>
31 #include "document.hxx"
32 #include "stlsheet.hxx"
34 #include "xistream.hxx"
35 #include "xihelper.hxx"
36 #include "xiescher.hxx"
38 // Page settings ==============================================================
40 XclImpPageSettings::XclImpPageSettings( const XclImpRoot
& rRoot
) :
46 void XclImpPageSettings::Initialize()
52 void XclImpPageSettings::ReadSetup( XclImpStream
& rStrm
)
54 OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF4
);
55 if( GetBiff() < EXC_BIFF4
)
60 rStrm
>> maData
.mnPaperSize
>> maData
.mnScaling
>> maData
.mnStartPage
61 >> maData
.mnFitToWidth
>> maData
.mnFitToHeight
>> nFlags
;
63 mbValidPaper
= maData
.mbValid
= !::get_flag( nFlags
, EXC_SETUP_INVALID
);
64 maData
.mbPrintInRows
= ::get_flag( nFlags
, EXC_SETUP_INROWS
);
65 maData
.mbPortrait
= ::get_flag( nFlags
, EXC_SETUP_PORTRAIT
);
66 maData
.mbBlackWhite
= ::get_flag( nFlags
, EXC_SETUP_BLACKWHITE
);
67 maData
.mbManualStart
= true;
69 // new in BIFF5 - BIFF8
70 if( GetBiff() >= EXC_BIFF5
)
72 rStrm
>> maData
.mnHorPrintRes
>> maData
.mnVerPrintRes
73 >> maData
.mfHeaderMargin
>> maData
.mfFooterMargin
>> maData
.mnCopies
;
75 maData
.mbDraftQuality
= ::get_flag( nFlags
, EXC_SETUP_DRAFT
);
76 maData
.mbPrintNotes
= ::get_flag( nFlags
, EXC_SETUP_PRINTNOTES
);
77 maData
.mbManualStart
= ::get_flag( nFlags
, EXC_SETUP_STARTPAGE
);
81 void XclImpPageSettings::ReadMargin( XclImpStream
& rStrm
)
83 switch( rStrm
.GetRecId() )
85 case EXC_ID_LEFTMARGIN
: rStrm
>> maData
.mfLeftMargin
; break;
86 case EXC_ID_RIGHTMARGIN
: rStrm
>> maData
.mfRightMargin
; break;
87 case EXC_ID_TOPMARGIN
: rStrm
>> maData
.mfTopMargin
; break;
88 case EXC_ID_BOTTOMMARGIN
: rStrm
>> maData
.mfBottomMargin
; break;
89 default: OSL_FAIL( "XclImpPageSettings::ReadMargin - unknown record" );
93 void XclImpPageSettings::ReadCenter( XclImpStream
& rStrm
)
95 OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF3
); // read it anyway
96 bool bCenter
= (rStrm
.ReaduInt16() != 0);
97 switch( rStrm
.GetRecId() )
99 case EXC_ID_HCENTER
: maData
.mbHorCenter
= bCenter
; break;
100 case EXC_ID_VCENTER
: maData
.mbVerCenter
= bCenter
; break;
101 default: OSL_FAIL( "XclImpPageSettings::ReadCenter - unknown record" );
105 void XclImpPageSettings::ReadHeaderFooter( XclImpStream
& rStrm
)
108 if( rStrm
.GetRecLeft() )
109 aString
= (GetBiff() <= EXC_BIFF5
) ? rStrm
.ReadByteString( false ) : rStrm
.ReadUniString();
111 switch( rStrm
.GetRecId() )
113 case EXC_ID_HEADER
: maData
.maHeader
= aString
; break;
114 case EXC_ID_FOOTER
: maData
.maFooter
= aString
; break;
115 default: OSL_FAIL( "XclImpPageSettings::ReadHeaderFooter - unknown record" );
119 void XclImpPageSettings::ReadPageBreaks( XclImpStream
& rStrm
)
121 ScfUInt16Vec
* pVec
= 0;
122 switch( rStrm
.GetRecId() )
124 case EXC_ID_HORPAGEBREAKS
: pVec
= &maData
.maHorPageBreaks
; break;
125 case EXC_ID_VERPAGEBREAKS
: pVec
= &maData
.maVerPageBreaks
; break;
126 default: OSL_FAIL( "XclImpPageSettings::ReadPageBreaks - unknown record" );
131 bool bIgnore
= GetBiff() == EXC_BIFF8
; // ignore start/end columns or rows in BIFF8
133 sal_uInt16 nCount
, nBreak
;
136 pVec
->reserve( nCount
);
142 pVec
->push_back( nBreak
);
149 void XclImpPageSettings::ReadPrintHeaders( XclImpStream
& rStrm
)
151 maData
.mbPrintHeadings
= (rStrm
.ReaduInt16() != 0);
154 void XclImpPageSettings::ReadPrintGridLines( XclImpStream
& rStrm
)
156 maData
.mbPrintGrid
= (rStrm
.ReaduInt16() != 0);
159 void XclImpPageSettings::ReadImgData( XclImpStream
& rStrm
)
161 Graphic aGraphic
= XclImpDrawing::ReadImgData( GetRoot(), rStrm
);
162 if( aGraphic
.GetType() != GRAPHIC_NONE
)
163 maData
.mxBrushItem
.reset( new SvxBrushItem( aGraphic
, GPOS_TILED
, ATTR_BACKGROUND
) );
166 void XclImpPageSettings::SetPaperSize( sal_uInt16 nXclPaperSize
, bool bPortrait
)
168 maData
.mnPaperSize
= nXclPaperSize
;
169 maData
.mbPortrait
= bPortrait
;
173 // ----------------------------------------------------------------------------
177 void lclPutMarginItem( SfxItemSet
& rItemSet
, sal_uInt16 nRecId
, double fMarginInch
)
179 sal_uInt16 nMarginTwips
= XclTools::GetTwipsFromInch( fMarginInch
);
182 case EXC_ID_TOPMARGIN
:
183 case EXC_ID_BOTTOMMARGIN
:
185 SvxULSpaceItem
aItem( GETITEM( rItemSet
, SvxULSpaceItem
, ATTR_ULSPACE
) );
186 if( nRecId
== EXC_ID_TOPMARGIN
)
187 aItem
.SetUpperValue( nMarginTwips
);
189 aItem
.SetLowerValue( nMarginTwips
);
190 rItemSet
.Put( aItem
);
193 case EXC_ID_LEFTMARGIN
:
194 case EXC_ID_RIGHTMARGIN
:
196 SvxLRSpaceItem
aItem( GETITEM( rItemSet
, SvxLRSpaceItem
, ATTR_LRSPACE
) );
197 if( nRecId
== EXC_ID_LEFTMARGIN
)
198 aItem
.SetLeftValue( nMarginTwips
);
200 aItem
.SetRightValue( nMarginTwips
);
201 rItemSet
.Put( aItem
);
205 OSL_FAIL( "XclImpPageSettings::SetMarginItem - unknown record id" );
211 void XclImpPageSettings::Finalize()
213 ScDocument
& rDoc
= GetDoc();
214 SCTAB nScTab
= GetCurrScTab();
216 // *** create page style sheet ***
218 OUStringBuffer aStyleName
;
219 aStyleName
.appendAscii("PageStyle_");
222 if( GetDoc().GetName( nScTab
, aTableName
) )
223 aStyleName
.append(aTableName
);
225 aStyleName
.append(static_cast<sal_Int32
>(nScTab
+1));
227 ScStyleSheet
& rStyleSheet
= ScfTools::MakePageStyleSheet(
228 GetStyleSheetPool(), aStyleName
.makeStringAndClear(), false);
230 SfxItemSet
& rItemSet
= rStyleSheet
.GetItemSet();
232 // *** page settings ***
234 ScfTools::PutItem( rItemSet
, SfxBoolItem( ATTR_PAGE_TOPDOWN
, !maData
.mbPrintInRows
), true );
235 ScfTools::PutItem( rItemSet
, SfxBoolItem( ATTR_PAGE_HORCENTER
, maData
.mbHorCenter
), true );
236 ScfTools::PutItem( rItemSet
, SfxBoolItem( ATTR_PAGE_VERCENTER
, maData
.mbVerCenter
), true );
237 ScfTools::PutItem( rItemSet
, SfxBoolItem( ATTR_PAGE_HEADERS
, maData
.mbPrintHeadings
), true );
238 ScfTools::PutItem( rItemSet
, SfxBoolItem( ATTR_PAGE_GRID
, maData
.mbPrintGrid
), true );
239 ScfTools::PutItem( rItemSet
, SfxBoolItem( ATTR_PAGE_NOTES
, maData
.mbPrintNotes
), true );
241 sal_uInt16 nStartPage
= maData
.mbManualStart
? maData
.mnStartPage
: 0;
242 ScfTools::PutItem( rItemSet
, SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO
, nStartPage
), true );
244 if( maData
.mxBrushItem
.get() )
245 rItemSet
.Put( *maData
.mxBrushItem
);
249 SvxPageItem
aPageItem( GETITEM( rItemSet
, SvxPageItem
, ATTR_PAGE
) );
250 aPageItem
.SetLandscape( !maData
.mbPortrait
);
251 rItemSet
.Put( aPageItem
);
252 ScfTools::PutItem( rItemSet
, SvxSizeItem( ATTR_PAGE_SIZE
, maData
.GetScPaperSize() ), true );
255 if( maData
.mbFitToPages
)
256 rItemSet
.Put( ScPageScaleToItem( maData
.mnFitToWidth
, maData
.mnFitToHeight
) );
257 else if( maData
.mbValid
)
258 rItemSet
.Put( SfxUInt16Item( ATTR_PAGE_SCALE
, maData
.mnScaling
) );
260 // *** margin preparations ***
262 double fLeftMargin
= maData
.mfLeftMargin
;
263 double fRightMargin
= maData
.mfRightMargin
;
264 double fTopMargin
= maData
.mfTopMargin
;
265 double fBottomMargin
= maData
.mfBottomMargin
;
266 // distances between header/footer and page area
267 double fHeaderHeight
= 0.0;
268 double fHeaderDist
= 0.0;
269 double fFooterHeight
= 0.0;
270 double fFooterDist
= 0.0;
271 // in Calc, "header/footer left/right margin" is X distance between header/footer and page margin
272 double fHdrLeftMargin
= maData
.mfHdrLeftMargin
- maData
.mfLeftMargin
;
273 double fHdrRightMargin
= maData
.mfHdrRightMargin
- maData
.mfRightMargin
;
274 double fFtrLeftMargin
= maData
.mfFtrLeftMargin
- maData
.mfLeftMargin
;
275 double fFtrRightMargin
= maData
.mfFtrRightMargin
- maData
.mfRightMargin
;
277 // *** header and footer ***
279 XclImpHFConverter
aHFConv( GetRoot() );
282 bool bHasHeader
= (maData
.maHeader
.Len() != 0);
283 SvxSetItem
aHdrSetItem( GETITEM( rItemSet
, SvxSetItem
, ATTR_PAGE_HEADERSET
) );
284 SfxItemSet
& rHdrItemSet
= aHdrSetItem
.GetItemSet();
285 rHdrItemSet
.Put( SfxBoolItem( ATTR_PAGE_ON
, bHasHeader
) );
288 aHFConv
.ParseString( maData
.maHeader
);
289 aHFConv
.FillToItemSet( rItemSet
, ATTR_PAGE_HEADERLEFT
);
290 aHFConv
.FillToItemSet( rItemSet
, ATTR_PAGE_HEADERRIGHT
);
291 // #i23296# In Calc, "top margin" is distance to header
292 fTopMargin
= maData
.mfHeaderMargin
;
293 // Calc uses distance between header and sheet data area
294 fHeaderHeight
= XclTools::GetInchFromTwips( aHFConv
.GetTotalHeight() );
295 fHeaderDist
= maData
.mfTopMargin
- maData
.mfHeaderMargin
- fHeaderHeight
;
297 if( fHeaderDist
< 0.0 )
299 /* #i23296# Header overlays sheet data:
300 -> set fixed header height to get correct sheet data position. */
301 ScfTools::PutItem( rHdrItemSet
, SfxBoolItem( ATTR_PAGE_DYNAMIC
, false ), true );
302 // shrink header height
303 long nHdrHeight
= XclTools::GetTwipsFromInch( fHeaderHeight
+ fHeaderDist
);
304 ScfTools::PutItem( rHdrItemSet
, SvxSizeItem( ATTR_PAGE_SIZE
, Size( 0, nHdrHeight
) ), true );
305 lclPutMarginItem( rHdrItemSet
, EXC_ID_BOTTOMMARGIN
, 0.0 );
309 // use dynamic header height
310 ScfTools::PutItem( rHdrItemSet
, SfxBoolItem( ATTR_PAGE_DYNAMIC
, true ), true );
311 lclPutMarginItem( rHdrItemSet
, EXC_ID_BOTTOMMARGIN
, fHeaderDist
);
313 lclPutMarginItem( rHdrItemSet
, EXC_ID_LEFTMARGIN
, fHdrLeftMargin
);
314 lclPutMarginItem( rHdrItemSet
, EXC_ID_RIGHTMARGIN
, fHdrRightMargin
);
315 rItemSet
.Put( aHdrSetItem
);
318 bool bHasFooter
= (maData
.maFooter
.Len() != 0);
319 SvxSetItem
aFtrSetItem( GETITEM( rItemSet
, SvxSetItem
, ATTR_PAGE_FOOTERSET
) );
320 SfxItemSet
& rFtrItemSet
= aFtrSetItem
.GetItemSet();
321 rFtrItemSet
.Put( SfxBoolItem( ATTR_PAGE_ON
, bHasFooter
) );
324 aHFConv
.ParseString( maData
.maFooter
);
325 aHFConv
.FillToItemSet( rItemSet
, ATTR_PAGE_FOOTERLEFT
);
326 aHFConv
.FillToItemSet( rItemSet
, ATTR_PAGE_FOOTERRIGHT
);
327 // #i23296# In Calc, "bottom margin" is distance to footer
328 fBottomMargin
= maData
.mfFooterMargin
;
329 // Calc uses distance between footer and sheet data area
330 fFooterHeight
= XclTools::GetInchFromTwips( aHFConv
.GetTotalHeight() );
331 fFooterDist
= maData
.mfBottomMargin
- maData
.mfFooterMargin
- fFooterHeight
;
333 if( fFooterDist
< 0.0 )
335 /* #i23296# Footer overlays sheet data:
336 -> set fixed footer height to get correct sheet data end position. */
337 ScfTools::PutItem( rFtrItemSet
, SfxBoolItem( ATTR_PAGE_DYNAMIC
, false ), true );
338 // shrink footer height
339 long nFtrHeight
= XclTools::GetTwipsFromInch( fFooterHeight
+ fFooterDist
);
340 ScfTools::PutItem( rFtrItemSet
, SvxSizeItem( ATTR_PAGE_SIZE
, Size( 0, nFtrHeight
) ), true );
341 lclPutMarginItem( rFtrItemSet
, EXC_ID_TOPMARGIN
, 0.0 );
345 // use dynamic footer height
346 ScfTools::PutItem( rFtrItemSet
, SfxBoolItem( ATTR_PAGE_DYNAMIC
, true ), true );
347 lclPutMarginItem( rFtrItemSet
, EXC_ID_TOPMARGIN
, fFooterDist
);
349 lclPutMarginItem( rFtrItemSet
, EXC_ID_LEFTMARGIN
, fFtrLeftMargin
);
350 lclPutMarginItem( rFtrItemSet
, EXC_ID_RIGHTMARGIN
, fFtrRightMargin
);
351 rItemSet
.Put( aFtrSetItem
);
353 // *** set final margins ***
355 lclPutMarginItem( rItemSet
, EXC_ID_LEFTMARGIN
, fLeftMargin
);
356 lclPutMarginItem( rItemSet
, EXC_ID_RIGHTMARGIN
, fRightMargin
);
357 lclPutMarginItem( rItemSet
, EXC_ID_TOPMARGIN
, fTopMargin
);
358 lclPutMarginItem( rItemSet
, EXC_ID_BOTTOMMARGIN
, fBottomMargin
);
360 // *** put style sheet into document ***
362 rDoc
.SetPageStyle( nScTab
, rStyleSheet
.GetName() );
364 // *** page breaks ***
366 ScfUInt16Vec::const_iterator aIt
, aEnd
;
368 for( aIt
= maData
.maHorPageBreaks
.begin(), aEnd
= maData
.maHorPageBreaks
.end(); aIt
!= aEnd
; ++aIt
)
370 SCROW nScRow
= static_cast< SCROW
>( *aIt
);
371 if( nScRow
<= MAXROW
)
372 rDoc
.SetRowBreak(nScRow
, nScTab
, false, true);
375 for( aIt
= maData
.maVerPageBreaks
.begin(), aEnd
= maData
.maVerPageBreaks
.end(); aIt
!= aEnd
; ++aIt
)
377 SCCOL nScCol
= static_cast< SCCOL
>( *aIt
);
378 if( nScCol
<= MAXCOL
)
379 rDoc
.SetColBreak(nScCol
, nScTab
, false, true);
383 // ============================================================================
385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */