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