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 "xipage.hxx"
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"
33 : #include "attrib.hxx"
34 : #include "xistream.hxx"
35 : #include "xihelper.hxx"
36 : #include "xiescher.hxx"
37 :
38 : // Page settings ==============================================================
39 :
40 144 : XclImpPageSettings::XclImpPageSettings( const XclImpRoot& rRoot ) :
41 144 : XclImpRoot( rRoot )
42 : {
43 144 : Initialize();
44 144 : }
45 :
46 560 : void XclImpPageSettings::Initialize()
47 : {
48 560 : maData.SetDefaults();
49 560 : mbValidPaper = false;
50 560 : }
51 :
52 416 : void XclImpPageSettings::ReadSetup( XclImpStream& rStrm )
53 : {
54 : OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF4 );
55 416 : if( GetBiff() < EXC_BIFF4 )
56 416 : return;
57 :
58 : // BIFF4 - BIFF8
59 : sal_uInt16 nFlags;
60 416 : rStrm >> maData.mnPaperSize >> maData.mnScaling >> maData.mnStartPage
61 832 : >> maData.mnFitToWidth >> maData.mnFitToHeight >> nFlags;
62 :
63 416 : mbValidPaper = maData.mbValid = !::get_flag( nFlags, EXC_SETUP_INVALID );
64 416 : maData.mbPrintInRows = ::get_flag( nFlags, EXC_SETUP_INROWS );
65 416 : maData.mbPortrait = ::get_flag( nFlags, EXC_SETUP_PORTRAIT );
66 416 : maData.mbBlackWhite = ::get_flag( nFlags, EXC_SETUP_BLACKWHITE );
67 416 : maData.mbManualStart = true;
68 :
69 : // new in BIFF5 - BIFF8
70 416 : if( GetBiff() >= EXC_BIFF5 )
71 : {
72 416 : rStrm >> maData.mnHorPrintRes >> maData.mnVerPrintRes
73 832 : >> maData.mfHeaderMargin >> maData.mfFooterMargin >> maData.mnCopies;
74 :
75 416 : maData.mbDraftQuality = ::get_flag( nFlags, EXC_SETUP_DRAFT );
76 416 : maData.mbPrintNotes = ::get_flag( nFlags, EXC_SETUP_PRINTNOTES );
77 416 : maData.mbManualStart = ::get_flag( nFlags, EXC_SETUP_STARTPAGE );
78 : }
79 : }
80 :
81 712 : void XclImpPageSettings::ReadMargin( XclImpStream& rStrm )
82 : {
83 712 : switch( rStrm.GetRecId() )
84 : {
85 178 : case EXC_ID_LEFTMARGIN: rStrm >> maData.mfLeftMargin; break;
86 178 : case EXC_ID_RIGHTMARGIN: rStrm >> maData.mfRightMargin; break;
87 178 : case EXC_ID_TOPMARGIN: rStrm >> maData.mfTopMargin; break;
88 178 : case EXC_ID_BOTTOMMARGIN: rStrm >> maData.mfBottomMargin; break;
89 : default: OSL_FAIL( "XclImpPageSettings::ReadMargin - unknown record" );
90 : }
91 712 : }
92 :
93 832 : void XclImpPageSettings::ReadCenter( XclImpStream& rStrm )
94 : {
95 : OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF3 ); // read it anyway
96 832 : bool bCenter = (rStrm.ReaduInt16() != 0);
97 832 : switch( rStrm.GetRecId() )
98 : {
99 416 : case EXC_ID_HCENTER: maData.mbHorCenter = bCenter; break;
100 416 : case EXC_ID_VCENTER: maData.mbVerCenter = bCenter; break;
101 : default: OSL_FAIL( "XclImpPageSettings::ReadCenter - unknown record" );
102 : }
103 832 : }
104 :
105 830 : void XclImpPageSettings::ReadHeaderFooter( XclImpStream& rStrm )
106 : {
107 830 : OUString aString;
108 830 : if( rStrm.GetRecLeft() )
109 100 : aString = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString();
110 :
111 830 : switch( rStrm.GetRecId() )
112 : {
113 414 : case EXC_ID_HEADER: maData.maHeader = aString; break;
114 416 : case EXC_ID_FOOTER: maData.maFooter = aString; break;
115 : default: OSL_FAIL( "XclImpPageSettings::ReadHeaderFooter - unknown record" );
116 830 : }
117 830 : }
118 :
119 4 : void XclImpPageSettings::ReadPageBreaks( XclImpStream& rStrm )
120 : {
121 4 : ScfUInt16Vec* pVec = 0;
122 4 : switch( rStrm.GetRecId() )
123 : {
124 2 : case EXC_ID_HORPAGEBREAKS: pVec = &maData.maHorPageBreaks; break;
125 2 : case EXC_ID_VERPAGEBREAKS: pVec = &maData.maVerPageBreaks; break;
126 : default: OSL_FAIL( "XclImpPageSettings::ReadPageBreaks - unknown record" );
127 : }
128 :
129 4 : if( pVec )
130 : {
131 4 : bool bIgnore = GetBiff() == EXC_BIFF8; // ignore start/end columns or rows in BIFF8
132 :
133 : sal_uInt16 nCount, nBreak;
134 4 : rStrm >> nCount;
135 4 : pVec->clear();
136 4 : pVec->reserve( nCount );
137 :
138 8 : while( nCount-- )
139 : {
140 0 : rStrm >> nBreak;
141 0 : if( nBreak )
142 0 : pVec->push_back( nBreak );
143 0 : if( bIgnore )
144 0 : rStrm.Ignore( 4 );
145 : }
146 : }
147 4 : }
148 :
149 412 : void XclImpPageSettings::ReadPrintHeaders( XclImpStream& rStrm )
150 : {
151 412 : maData.mbPrintHeadings = (rStrm.ReaduInt16() != 0);
152 412 : }
153 :
154 414 : void XclImpPageSettings::ReadPrintGridLines( XclImpStream& rStrm )
155 : {
156 414 : maData.mbPrintGrid = (rStrm.ReaduInt16() != 0);
157 414 : }
158 :
159 0 : void XclImpPageSettings::ReadImgData( XclImpStream& rStrm )
160 : {
161 0 : Graphic aGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
162 0 : if( aGraphic.GetType() != GRAPHIC_NONE )
163 0 : maData.mxBrushItem.reset( new SvxBrushItem( aGraphic, GPOS_TILED, ATTR_BACKGROUND ) );
164 0 : }
165 :
166 0 : void XclImpPageSettings::SetPaperSize( sal_uInt16 nXclPaperSize, bool bPortrait )
167 : {
168 0 : maData.mnPaperSize = nXclPaperSize;
169 0 : maData.mbPortrait = bPortrait;
170 0 : mbValidPaper = true;
171 0 : }
172 :
173 : namespace {
174 :
175 4160 : void lclPutMarginItem( SfxItemSet& rItemSet, sal_uInt16 nRecId, double fMarginInch )
176 : {
177 4160 : sal_uInt16 nMarginTwips = XclTools::GetTwipsFromInch( fMarginInch );
178 4160 : switch( nRecId )
179 : {
180 : case EXC_ID_TOPMARGIN:
181 : case EXC_ID_BOTTOMMARGIN:
182 : {
183 1664 : SvxULSpaceItem aItem( GETITEM( rItemSet, SvxULSpaceItem, ATTR_ULSPACE ) );
184 1664 : if( nRecId == EXC_ID_TOPMARGIN )
185 832 : aItem.SetUpperValue( nMarginTwips );
186 : else
187 832 : aItem.SetLowerValue( nMarginTwips );
188 1664 : rItemSet.Put( aItem );
189 : }
190 1664 : break;
191 : case EXC_ID_LEFTMARGIN:
192 : case EXC_ID_RIGHTMARGIN:
193 : {
194 2496 : SvxLRSpaceItem aItem( GETITEM( rItemSet, SvxLRSpaceItem, ATTR_LRSPACE ) );
195 2496 : if( nRecId == EXC_ID_LEFTMARGIN )
196 1248 : aItem.SetLeftValue( nMarginTwips );
197 : else
198 1248 : aItem.SetRightValue( nMarginTwips );
199 2496 : rItemSet.Put( aItem );
200 : }
201 2496 : break;
202 : default:
203 : OSL_FAIL( "XclImpPageSettings::SetMarginItem - unknown record id" );
204 : }
205 4160 : }
206 :
207 : } // namespace
208 :
209 416 : void XclImpPageSettings::Finalize()
210 : {
211 416 : ScDocument& rDoc = GetDoc();
212 416 : SCTAB nScTab = GetCurrScTab();
213 :
214 : // *** create page style sheet ***
215 :
216 416 : OUStringBuffer aStyleName;
217 416 : aStyleName.appendAscii("PageStyle_");
218 :
219 832 : OUString aTableName;
220 416 : if( GetDoc().GetName( nScTab, aTableName ) )
221 416 : aStyleName.append(aTableName);
222 : else
223 0 : aStyleName.append(static_cast<sal_Int32>(nScTab+1));
224 :
225 : ScStyleSheet& rStyleSheet = ScfTools::MakePageStyleSheet(
226 416 : GetStyleSheetPool(), aStyleName.makeStringAndClear(), false);
227 :
228 416 : SfxItemSet& rItemSet = rStyleSheet.GetItemSet();
229 :
230 : // *** page settings ***
231 :
232 416 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_TOPDOWN, !maData.mbPrintInRows ), true );
233 416 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HORCENTER, maData.mbHorCenter ), true );
234 416 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_VERCENTER, maData.mbVerCenter ), true );
235 416 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HEADERS, maData.mbPrintHeadings ), true );
236 416 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_GRID, maData.mbPrintGrid ), true );
237 416 : ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_NOTES, maData.mbPrintNotes ), true );
238 :
239 416 : sal_uInt16 nStartPage = maData.mbManualStart ? maData.mnStartPage : 0;
240 416 : ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, nStartPage ), true );
241 :
242 416 : if( maData.mxBrushItem.get() )
243 0 : rItemSet.Put( *maData.mxBrushItem );
244 :
245 416 : if( mbValidPaper )
246 : {
247 170 : SvxPageItem aPageItem( GETITEM( rItemSet, SvxPageItem, ATTR_PAGE ) );
248 170 : aPageItem.SetLandscape( !maData.mbPortrait );
249 170 : rItemSet.Put( aPageItem );
250 170 : ScfTools::PutItem( rItemSet, SvxSizeItem( ATTR_PAGE_SIZE, maData.GetScPaperSize() ), true );
251 : }
252 :
253 416 : if( maData.mbFitToPages )
254 2 : rItemSet.Put( ScPageScaleToItem( maData.mnFitToWidth, maData.mnFitToHeight ) );
255 414 : else if( maData.mbValid )
256 168 : rItemSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, maData.mnScaling ) );
257 :
258 : // *** margin preparations ***
259 :
260 416 : double fLeftMargin = maData.mfLeftMargin;
261 416 : double fRightMargin = maData.mfRightMargin;
262 416 : double fTopMargin = maData.mfTopMargin;
263 416 : double fBottomMargin = maData.mfBottomMargin;
264 : // distances between header/footer and page area
265 416 : double fHeaderHeight = 0.0;
266 416 : double fHeaderDist = 0.0;
267 416 : double fFooterHeight = 0.0;
268 416 : double fFooterDist = 0.0;
269 : // in Calc, "header/footer left/right margin" is X distance between header/footer and page margin
270 416 : double fHdrLeftMargin = maData.mfHdrLeftMargin - maData.mfLeftMargin;
271 416 : double fHdrRightMargin = maData.mfHdrRightMargin - maData.mfRightMargin;
272 416 : double fFtrLeftMargin = maData.mfFtrLeftMargin - maData.mfLeftMargin;
273 416 : double fFtrRightMargin = maData.mfFtrRightMargin - maData.mfRightMargin;
274 :
275 : // *** header and footer ***
276 :
277 832 : XclImpHFConverter aHFConv( GetRoot() );
278 :
279 : // header
280 416 : bool bHasHeader = !maData.maHeader.isEmpty();
281 832 : SvxSetItem aHdrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_HEADERSET ) );
282 416 : SfxItemSet& rHdrItemSet = aHdrSetItem.GetItemSet();
283 416 : rHdrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasHeader ) );
284 416 : if( bHasHeader )
285 : {
286 44 : aHFConv.ParseString( maData.maHeader );
287 44 : aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERLEFT );
288 44 : aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERRIGHT );
289 : // #i23296# In Calc, "top margin" is distance to header
290 44 : fTopMargin = maData.mfHeaderMargin;
291 : // Calc uses distance between header and sheet data area
292 44 : fHeaderHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() );
293 44 : fHeaderDist = maData.mfTopMargin - maData.mfHeaderMargin - fHeaderHeight;
294 : }
295 416 : if( fHeaderDist < 0.0 )
296 : {
297 : /* #i23296# Header overlays sheet data:
298 : -> set fixed header height to get correct sheet data position. */
299 4 : ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true );
300 : // shrink header height
301 4 : long nHdrHeight = XclTools::GetTwipsFromInch( fHeaderHeight + fHeaderDist );
302 4 : ScfTools::PutItem( rHdrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nHdrHeight ) ), true );
303 4 : lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, 0.0 );
304 : }
305 : else
306 : {
307 : // use dynamic header height
308 412 : ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true );
309 412 : lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, fHeaderDist );
310 : }
311 416 : lclPutMarginItem( rHdrItemSet, EXC_ID_LEFTMARGIN, fHdrLeftMargin );
312 416 : lclPutMarginItem( rHdrItemSet, EXC_ID_RIGHTMARGIN, fHdrRightMargin );
313 416 : rItemSet.Put( aHdrSetItem );
314 :
315 : // footer
316 416 : bool bHasFooter = !maData.maFooter.isEmpty();
317 832 : SvxSetItem aFtrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_FOOTERSET ) );
318 416 : SfxItemSet& rFtrItemSet = aFtrSetItem.GetItemSet();
319 416 : rFtrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasFooter ) );
320 416 : if( bHasFooter )
321 : {
322 52 : aHFConv.ParseString( maData.maFooter );
323 52 : aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERLEFT );
324 52 : aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERRIGHT );
325 : // #i23296# In Calc, "bottom margin" is distance to footer
326 52 : fBottomMargin = maData.mfFooterMargin;
327 : // Calc uses distance between footer and sheet data area
328 52 : fFooterHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() );
329 52 : fFooterDist = maData.mfBottomMargin - maData.mfFooterMargin - fFooterHeight;
330 : }
331 416 : if( fFooterDist < 0.0 )
332 : {
333 : /* #i23296# Footer overlays sheet data:
334 : -> set fixed footer height to get correct sheet data end position. */
335 4 : ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true );
336 : // shrink footer height
337 4 : long nFtrHeight = XclTools::GetTwipsFromInch( fFooterHeight + fFooterDist );
338 4 : ScfTools::PutItem( rFtrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nFtrHeight ) ), true );
339 4 : lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, 0.0 );
340 : }
341 : else
342 : {
343 : // use dynamic footer height
344 412 : ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true );
345 412 : lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, fFooterDist );
346 : }
347 416 : lclPutMarginItem( rFtrItemSet, EXC_ID_LEFTMARGIN, fFtrLeftMargin );
348 416 : lclPutMarginItem( rFtrItemSet, EXC_ID_RIGHTMARGIN, fFtrRightMargin );
349 416 : rItemSet.Put( aFtrSetItem );
350 :
351 : // *** set final margins ***
352 :
353 416 : lclPutMarginItem( rItemSet, EXC_ID_LEFTMARGIN, fLeftMargin );
354 416 : lclPutMarginItem( rItemSet, EXC_ID_RIGHTMARGIN, fRightMargin );
355 416 : lclPutMarginItem( rItemSet, EXC_ID_TOPMARGIN, fTopMargin );
356 416 : lclPutMarginItem( rItemSet, EXC_ID_BOTTOMMARGIN, fBottomMargin );
357 :
358 : // *** put style sheet into document ***
359 :
360 416 : rDoc.SetPageStyle( nScTab, rStyleSheet.GetName() );
361 :
362 : // *** page breaks ***
363 :
364 416 : ScfUInt16Vec::const_iterator aIt, aEnd;
365 :
366 416 : for( aIt = maData.maHorPageBreaks.begin(), aEnd = maData.maHorPageBreaks.end(); aIt != aEnd; ++aIt )
367 : {
368 0 : SCROW nScRow = static_cast< SCROW >( *aIt );
369 0 : if( nScRow <= MAXROW )
370 0 : rDoc.SetRowBreak(nScRow, nScTab, false, true);
371 : }
372 :
373 416 : for( aIt = maData.maVerPageBreaks.begin(), aEnd = maData.maVerPageBreaks.end(); aIt != aEnd; ++aIt )
374 : {
375 0 : SCCOL nScCol = static_cast< SCCOL >( *aIt );
376 0 : if( nScCol <= MAXCOL )
377 0 : rDoc.SetColBreak(nScCol, nScTab, false, true);
378 416 : }
379 464 : }
380 :
381 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|