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