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