xref: /trunk/main/oox/source/xls/viewsettings.cxx (revision ca5ec200)
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 #include "oox/xls/viewsettings.hxx"
25 
26 #include <com/sun/star/awt/Point.hpp>
27 #include <com/sun/star/awt/Size.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/container/XIndexContainer.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/document/XViewDataSupplier.hpp>
32 #include <comphelper/mediadescriptor.hxx>
33 #include "oox/core/filterbase.hxx"
34 #include "oox/helper/attributelist.hxx"
35 #include "oox/helper/containerhelper.hxx"
36 #include "oox/helper/propertymap.hxx"
37 #include "oox/helper/propertyset.hxx"
38 #include "oox/xls/addressconverter.hxx"
39 #include "oox/xls/biffinputstream.hxx"
40 #include "oox/xls/unitconverter.hxx"
41 #include "oox/xls/workbooksettings.hxx"
42 #include "oox/xls/worksheetbuffer.hxx"
43 
44 namespace oox {
45 namespace xls {
46 
47 // ============================================================================
48 
49 using namespace ::com::sun::star::awt;
50 using namespace ::com::sun::star::container;
51 using namespace ::com::sun::star::document;
52 using namespace ::com::sun::star::table;
53 using namespace ::com::sun::star::uno;
54 
55 using ::oox::core::FilterBase;
56 using ::rtl::OUString;
57 
58 // ============================================================================
59 
60 namespace {
61 
62 const sal_Int32 OOX_BOOKVIEW_TABBARRATIO_DEF        = 600;      /// Default tabbar ratio.
63 const sal_Int32 OOX_SHEETVIEW_NORMALZOOM_DEF        = 100;      /// Default zoom for normal view.
64 const sal_Int32 OOX_SHEETVIEW_SHEETLAYZOOM_DEF      = 60;       /// Default zoom for pagebreak preview.
65 const sal_Int32 OOX_SHEETVIEW_PAGELAYZOOM_DEF       = 100;      /// Default zoom for page layout view.
66 
67 const sal_uInt8 BIFF12_PANE_FROZEN                  = 0x01;
68 const sal_uInt8 BIFF12_PANE_FROZENNOSPLIT           = 0x02;
69 
70 const sal_uInt16 BIFF12_SHEETVIEW_WINPROTECTED      = 0x0001;
71 const sal_uInt16 BIFF12_SHEETVIEW_SHOWFORMULAS      = 0x0002;
72 const sal_uInt16 BIFF12_SHEETVIEW_SHOWGRID          = 0x0004;
73 const sal_uInt16 BIFF12_SHEETVIEW_SHOWHEADINGS      = 0x0008;
74 const sal_uInt16 BIFF12_SHEETVIEW_SHOWZEROS         = 0x0010;
75 const sal_uInt16 BIFF12_SHEETVIEW_RIGHTTOLEFT       = 0x0020;
76 const sal_uInt16 BIFF12_SHEETVIEW_SELECTED          = 0x0040;
77 const sal_uInt16 BIFF12_SHEETVIEW_SHOWRULER         = 0x0080;
78 const sal_uInt16 BIFF12_SHEETVIEW_SHOWOUTLINE       = 0x0100;
79 const sal_uInt16 BIFF12_SHEETVIEW_DEFGRIDCOLOR      = 0x0200;
80 const sal_uInt16 BIFF12_SHEETVIEW_SHOWWHITESPACE    = 0x0400;
81 
82 const sal_uInt16 BIFF12_CHARTSHEETVIEW_SELECTED     = 0x0001;
83 const sal_uInt16 BIFF12_CHARTSHEETVIEW_ZOOMTOFIT    = 0x0002;
84 
85 const sal_uInt8 BIFF12_WBVIEW_HIDDEN                = 0x01;
86 const sal_uInt8 BIFF12_WBVIEW_MINIMIZED             = 0x02;
87 const sal_uInt8 BIFF12_WBVIEW_SHOWHORSCROLL         = 0x08;
88 const sal_uInt8 BIFF12_WBVIEW_SHOWVERSCROLL         = 0x10;
89 const sal_uInt8 BIFF12_WBVIEW_SHOWTABBAR            = 0x20;
90 const sal_uInt8 BIFF12_WBVIEW_AUTOFILTERGROUP       = 0x40;
91 
92 const sal_uInt8 BIFF_PANE_BOTTOMRIGHT               = 0;        /// Bottom-right pane.
93 const sal_uInt8 BIFF_PANE_TOPRIGHT                  = 1;        /// Right, or top-right pane.
94 const sal_uInt8 BIFF_PANE_BOTTOMLEFT                = 2;        /// Bottom, or bottom-left pane.
95 const sal_uInt8 BIFF_PANE_TOPLEFT                   = 3;        /// Single, top, left, or top-left pane.
96 
97 const sal_uInt16 BIFF_WINDOW1_HIDDEN                = 0x0001;
98 const sal_uInt16 BIFF_WINDOW1_MINIMIZED             = 0x0002;
99 const sal_uInt16 BIFF_WINDOW1_SHOWHORSCROLL         = 0x0008;
100 const sal_uInt16 BIFF_WINDOW1_SHOWVERSCROLL         = 0x0010;
101 const sal_uInt16 BIFF_WINDOW1_SHOWTABBAR            = 0x0020;
102 
103 const sal_uInt16 BIFF_WINDOW2_SHOWFORMULAS          = 0x0001;
104 const sal_uInt16 BIFF_WINDOW2_SHOWGRID              = 0x0002;
105 const sal_uInt16 BIFF_WINDOW2_SHOWHEADINGS          = 0x0004;
106 const sal_uInt16 BIFF_WINDOW2_FROZEN                = 0x0008;
107 const sal_uInt16 BIFF_WINDOW2_SHOWZEROS             = 0x0010;
108 const sal_uInt16 BIFF_WINDOW2_DEFGRIDCOLOR          = 0x0020;
109 const sal_uInt16 BIFF_WINDOW2_RIGHTTOLEFT           = 0x0040;
110 const sal_uInt16 BIFF_WINDOW2_SHOWOUTLINE           = 0x0080;
111 const sal_uInt16 BIFF_WINDOW2_FROZENNOSPLIT         = 0x0100;
112 const sal_uInt16 BIFF_WINDOW2_SELECTED              = 0x0200;
113 const sal_uInt16 BIFF_WINDOW2_DISPLAYED             = 0x0400;
114 const sal_uInt16 BIFF_WINDOW2_PAGEBREAKMODE         = 0x0800;
115 
116 // Attention: view settings in Calc do not use com.sun.star.view.DocumentZoomType!
117 const sal_Int16 API_ZOOMTYPE_PERCENT                = 0;        /// Zoom value in percent.
118 
119 const sal_Int32 API_ZOOMVALUE_MIN                   = 20;       /// Minimum zoom in Calc.
120 const sal_Int32 API_ZOOMVALUE_MAX                   = 400;      /// Maximum zoom in Calc.
121 
122 // no predefined constants for split mode
123 const sal_Int16 API_SPLITMODE_NONE                  = 0;        /// No splits in window.
124 const sal_Int16 API_SPLITMODE_SPLIT                 = 1;        /// Window is split.
125 const sal_Int16 API_SPLITMODE_FREEZE                = 2;        /// Window has frozen panes.
126 
127 // no predefined constants for pane idetifiers
128 const sal_Int16 API_SPLITPANE_TOPLEFT               = 0;        /// Top-left, or top pane.
129 const sal_Int16 API_SPLITPANE_TOPRIGHT              = 1;        /// Top-right pane.
130 const sal_Int16 API_SPLITPANE_BOTTOMLEFT            = 2;        /// Bottom-left, bottom, left, or single pane.
131 const sal_Int16 API_SPLITPANE_BOTTOMRIGHT           = 3;        /// Bottom-right, or right pane.
132 
133 // ----------------------------------------------------------------------------
134 
135 /** Returns the OOXML pane identifier from the passed BIFF pane id. */
lclGetOoxPaneId(sal_Int32 nBiffPaneId,sal_Int32 nDefaultPaneId)136 sal_Int32 lclGetOoxPaneId( sal_Int32 nBiffPaneId, sal_Int32 nDefaultPaneId )
137 {
138     static const sal_Int32 spnPaneIds[] = { XML_bottomRight, XML_topRight, XML_bottomLeft, XML_topLeft };
139     return STATIC_ARRAY_SELECT( spnPaneIds, nBiffPaneId, nDefaultPaneId );
140 }
141 
142 } // namespace
143 
144 // ============================================================================
145 
PaneSelectionModel()146 PaneSelectionModel::PaneSelectionModel() :
147     mnActiveCellId( 0 )
148 {
149 }
150 
151 // ----------------------------------------------------------------------------
152 
SheetViewModel()153 SheetViewModel::SheetViewModel() :
154     mnWorkbookViewId( 0 ),
155     mnViewType( XML_normal ),
156     mnActivePaneId( XML_topLeft ),
157     mnPaneState( XML_split ),
158     mfSplitX( 0.0 ),
159     mfSplitY( 0.0 ),
160     mnCurrentZoom( 0 ),
161     mnNormalZoom( 0 ),
162     mnSheetLayoutZoom( 0 ),
163     mnPageLayoutZoom( 0 ),
164     mbSelected( false ),
165     mbRightToLeft( false ),
166     mbDefGridColor( true ),
167     mbShowFormulas( false ),
168     mbShowGrid( true ),
169     mbShowHeadings( true ),
170     mbShowZeros( true ),
171     mbShowOutline( true ),
172     mbZoomToFit( false )
173 {
174     maGridColor.setIndexed( OOX_COLOR_WINDOWTEXT );
175 }
176 
isPageBreakPreview() const177 bool SheetViewModel::isPageBreakPreview() const
178 {
179     return mnViewType == XML_pageBreakPreview;
180 }
181 
getNormalZoom() const182 sal_Int32 SheetViewModel::getNormalZoom() const
183 {
184     const sal_Int32& rnZoom = isPageBreakPreview() ? mnNormalZoom : mnCurrentZoom;
185     sal_Int32 nZoom = (rnZoom > 0) ? rnZoom : OOX_SHEETVIEW_NORMALZOOM_DEF;
186     return getLimitedValue< sal_Int32 >( nZoom, API_ZOOMVALUE_MIN, API_ZOOMVALUE_MAX );
187 }
188 
getPageBreakZoom() const189 sal_Int32 SheetViewModel::getPageBreakZoom() const
190 {
191     const sal_Int32& rnZoom = isPageBreakPreview() ? mnCurrentZoom : mnSheetLayoutZoom;
192     sal_Int32 nZoom = (rnZoom > 0) ? rnZoom : OOX_SHEETVIEW_SHEETLAYZOOM_DEF;
193     return getLimitedValue< sal_Int32 >( nZoom, API_ZOOMVALUE_MIN, API_ZOOMVALUE_MAX );
194 }
195 
getGridColor(const FilterBase & rFilter) const196 sal_Int32 SheetViewModel::getGridColor( const FilterBase& rFilter ) const
197 {
198     return mbDefGridColor ? API_RGB_TRANSPARENT : maGridColor.getColor( rFilter.getGraphicHelper() );
199 }
200 
getPaneSelection(sal_Int32 nPaneId) const201 const PaneSelectionModel* SheetViewModel::getPaneSelection( sal_Int32 nPaneId ) const
202 {
203     return maPaneSelMap.get( nPaneId ).get();
204 }
205 
getActiveSelection() const206 const PaneSelectionModel* SheetViewModel::getActiveSelection() const
207 {
208     return getPaneSelection( mnActivePaneId );
209 }
210 
createPaneSelection(sal_Int32 nPaneId)211 PaneSelectionModel& SheetViewModel::createPaneSelection( sal_Int32 nPaneId )
212 {
213     PaneSelectionModelMap::mapped_type& rxPaneSel = maPaneSelMap[ nPaneId ];
214     if( !rxPaneSel )
215         rxPaneSel.reset( new PaneSelectionModel );
216     return *rxPaneSel;
217 }
218 
219 // ----------------------------------------------------------------------------
220 
SheetViewSettings(const WorksheetHelper & rHelper)221 SheetViewSettings::SheetViewSettings( const WorksheetHelper& rHelper ) :
222     WorksheetHelper( rHelper )
223 {
224 }
225 
importSheetView(const AttributeList & rAttribs)226 void SheetViewSettings::importSheetView( const AttributeList& rAttribs )
227 {
228     SheetViewModel& rModel = *createSheetView();
229     rModel.maGridColor.setIndexed( rAttribs.getInteger( XML_colorId, OOX_COLOR_WINDOWTEXT ) );
230     rModel.maFirstPos        = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_topLeftCell, OUString() ), getSheetIndex(), false );
231     rModel.mnWorkbookViewId  = rAttribs.getToken( XML_workbookViewId, 0 );
232     rModel.mnViewType        = rAttribs.getToken( XML_view, XML_normal );
233     rModel.mnCurrentZoom     = rAttribs.getInteger( XML_zoomScale, 100 );
234     rModel.mnNormalZoom      = rAttribs.getInteger( XML_zoomScaleNormal, 0 );
235     rModel.mnSheetLayoutZoom = rAttribs.getInteger( XML_zoomScaleSheetLayoutView, 0 );
236     rModel.mnPageLayoutZoom  = rAttribs.getInteger( XML_zoomScalePageLayoutView, 0 );
237     rModel.mbSelected        = rAttribs.getBool( XML_tabSelected, false );
238     rModel.mbRightToLeft     = rAttribs.getBool( XML_rightToLeft, false );
239     rModel.mbDefGridColor    = rAttribs.getBool( XML_defaultGridColor, true );
240     rModel.mbShowFormulas    = rAttribs.getBool( XML_showFormulas, false );
241     rModel.mbShowGrid        = rAttribs.getBool( XML_showGridLines, true );
242     rModel.mbShowHeadings    = rAttribs.getBool( XML_showRowColHeaders, true );
243     rModel.mbShowZeros       = rAttribs.getBool( XML_showZeros, true );
244     rModel.mbShowOutline     = rAttribs.getBool( XML_showOutlineSymbols, true );
245 }
246 
importPane(const AttributeList & rAttribs)247 void SheetViewSettings::importPane( const AttributeList& rAttribs )
248 {
249     OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing sheet view model" );
250     if( !maSheetViews.empty() )
251     {
252         SheetViewModel& rModel = *maSheetViews.back();
253         rModel.maSecondPos    = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_topLeftCell, OUString() ), getSheetIndex(), false );
254         rModel.mnActivePaneId = rAttribs.getToken( XML_activePane, XML_topLeft );
255         rModel.mnPaneState    = rAttribs.getToken( XML_state, XML_split );
256         rModel.mfSplitX       = rAttribs.getDouble( XML_xSplit, 0.0 );
257         rModel.mfSplitY       = rAttribs.getDouble( XML_ySplit, 0.0 );
258     }
259 }
260 
importSelection(const AttributeList & rAttribs)261 void SheetViewSettings::importSelection( const AttributeList& rAttribs )
262 {
263     OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importSelection - missing sheet view model" );
264     if( !maSheetViews.empty() )
265     {
266         // pane this selection belongs to
267         sal_Int32 nPaneId = rAttribs.getToken( XML_pane, XML_topLeft );
268         PaneSelectionModel& rSelData = maSheetViews.back()->createPaneSelection( nPaneId );
269         // cursor position
270         rSelData.maActiveCell = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_activeCell, OUString() ), getSheetIndex(), false );
271         rSelData.mnActiveCellId = rAttribs.getInteger( XML_activeCellId, 0 );
272         // selection
273         rSelData.maSelection.clear();
274         getAddressConverter().convertToCellRangeList( rSelData.maSelection, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), false );
275     }
276 }
277 
importChartSheetView(const AttributeList & rAttribs)278 void SheetViewSettings::importChartSheetView( const AttributeList& rAttribs )
279 {
280     SheetViewModel& rModel = *createSheetView();
281     rModel.mnWorkbookViewId = rAttribs.getToken( XML_workbookViewId, 0 );
282     rModel.mnCurrentZoom    = rAttribs.getInteger( XML_zoomScale, 100 );
283     rModel.mbSelected       = rAttribs.getBool( XML_tabSelected, false );
284     rModel.mbZoomToFit      = rAttribs.getBool( XML_zoomToFit, false );
285 }
286 
importSheetView(SequenceInputStream & rStrm)287 void SheetViewSettings::importSheetView( SequenceInputStream& rStrm )
288 {
289     SheetViewModel& rModel = *createSheetView();
290     sal_uInt16 nFlags;
291     sal_Int32 nViewType;
292     BinAddress aFirstPos;
293     rStrm >> nFlags >> nViewType >> aFirstPos;
294     rModel.maGridColor.importColorId( rStrm );
295     rModel.mnCurrentZoom = rStrm.readuInt16();
296     rModel.mnNormalZoom = rStrm.readuInt16();
297     rModel.mnSheetLayoutZoom = rStrm.readuInt16();
298     rModel.mnPageLayoutZoom = rStrm.readuInt16();
299     rStrm >> rModel.mnWorkbookViewId;
300 
301     rModel.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
302     static const sal_Int32 spnViewTypes[] = { XML_normal, XML_pageBreakPreview, XML_pageLayout };
303     rModel.mnViewType = STATIC_ARRAY_SELECT( spnViewTypes, nViewType, XML_normal );
304     rModel.mbSelected     = getFlag( nFlags, BIFF12_SHEETVIEW_SELECTED );
305     rModel.mbRightToLeft  = getFlag( nFlags, BIFF12_SHEETVIEW_RIGHTTOLEFT );
306     rModel.mbDefGridColor = getFlag( nFlags, BIFF12_SHEETVIEW_DEFGRIDCOLOR );
307     rModel.mbShowFormulas = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWFORMULAS );
308     rModel.mbShowGrid     = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWGRID );
309     rModel.mbShowHeadings = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWHEADINGS );
310     rModel.mbShowZeros    = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWZEROS );
311     rModel.mbShowOutline  = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWOUTLINE );
312 }
313 
importPane(SequenceInputStream & rStrm)314 void SheetViewSettings::importPane( SequenceInputStream& rStrm )
315 {
316     OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing sheet view model" );
317     if( !maSheetViews.empty() )
318     {
319         SheetViewModel& rModel = *maSheetViews.back();
320 
321         BinAddress aSecondPos;
322         sal_Int32 nActivePaneId;
323         sal_uInt8 nFlags;
324         rStrm >> rModel.mfSplitX >> rModel.mfSplitY >> aSecondPos >> nActivePaneId >> nFlags;
325 
326         rModel.maSecondPos    = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false );
327         rModel.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft );
328         rModel.mnPaneState    = getFlagValue( nFlags, BIFF12_PANE_FROZEN, getFlagValue( nFlags, BIFF12_PANE_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split );
329     }
330 }
331 
importSelection(SequenceInputStream & rStrm)332 void SheetViewSettings::importSelection( SequenceInputStream& rStrm )
333 {
334     OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importSelection - missing sheet view model" );
335     if( !maSheetViews.empty() )
336     {
337         // pane this selection belongs to
338         sal_Int32 nPaneId = rStrm.readInt32();
339         PaneSelectionModel& rPaneSel = maSheetViews.back()->createPaneSelection( lclGetOoxPaneId( nPaneId, -1 ) );
340         // cursor position
341         BinAddress aActiveCell;
342         rStrm >> aActiveCell >> rPaneSel.mnActiveCellId;
343         rPaneSel.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false );
344         // selection
345         BinRangeList aSelection;
346         rStrm >> aSelection;
347         rPaneSel.maSelection.clear();
348         getAddressConverter().convertToCellRangeList( rPaneSel.maSelection, aSelection, getSheetIndex(), false );
349     }
350 }
351 
importChartSheetView(SequenceInputStream & rStrm)352 void SheetViewSettings::importChartSheetView( SequenceInputStream& rStrm )
353 {
354     SheetViewModel& rModel = *createSheetView();
355     sal_uInt16 nFlags;
356     rStrm >> nFlags >> rModel.mnCurrentZoom >> rModel.mnWorkbookViewId;
357 
358     rModel.mbSelected  = getFlag( nFlags, BIFF12_CHARTSHEETVIEW_SELECTED );
359     rModel.mbZoomToFit = getFlag( nFlags, BIFF12_CHARTSHEETVIEW_ZOOMTOFIT );
360 }
361 
importWindow2(BiffInputStream & rStrm)362 void SheetViewSettings::importWindow2( BiffInputStream& rStrm )
363 {
364     OSL_ENSURE( maSheetViews.empty(), "SheetViewSettings::importWindow2 - multiple WINDOW2 records" );
365     SheetViewModel& rModel = *createSheetView();
366     if( getBiff() == BIFF2 )
367     {
368         rModel.mbShowFormulas = rStrm.readuInt8() != 0;
369         rModel.mbShowGrid = rStrm.readuInt8() != 0;
370         rModel.mbShowHeadings = rStrm.readuInt8() != 0;
371         rModel.mnPaneState = (rStrm.readuInt8() == 0) ? XML_split : XML_frozen;
372         rModel.mbShowZeros = rStrm.readuInt8() != 0;
373         BinAddress aFirstPos;
374         rStrm >> aFirstPos;
375         rModel.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
376         rModel.mbDefGridColor = rStrm.readuInt8() != 0;
377         rModel.maGridColor.importColorRgb( rStrm );
378     }
379     else
380     {
381         sal_uInt16 nFlags;
382         BinAddress aFirstPos;
383         rStrm >> nFlags >> aFirstPos;
384 
385         rModel.maFirstPos     = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
386         rModel.mnPaneState    = getFlagValue( nFlags, BIFF_WINDOW2_FROZEN, getFlagValue( nFlags, BIFF_WINDOW2_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split );
387         rModel.mbSelected     = getFlag( nFlags, BIFF_WINDOW2_SELECTED );
388         rModel.mbRightToLeft  = getFlag( nFlags, BIFF_WINDOW2_RIGHTTOLEFT );
389         rModel.mbDefGridColor = getFlag( nFlags, BIFF_WINDOW2_DEFGRIDCOLOR );
390         rModel.mbShowFormulas = getFlag( nFlags, BIFF_WINDOW2_SHOWFORMULAS );
391         rModel.mbShowGrid     = getFlag( nFlags, BIFF_WINDOW2_SHOWGRID );
392         rModel.mbShowHeadings = getFlag( nFlags, BIFF_WINDOW2_SHOWHEADINGS );
393         rModel.mbShowZeros    = getFlag( nFlags, BIFF_WINDOW2_SHOWZEROS );
394         rModel.mbShowOutline  = getFlag( nFlags, BIFF_WINDOW2_SHOWOUTLINE );
395 
396         if( getBiff() == BIFF8 )
397         {
398             rModel.mnViewType = getFlagValue( nFlags, BIFF_WINDOW2_PAGEBREAKMODE, XML_pageBreakPreview, XML_normal );
399 
400             rModel.maGridColor.importColorId( rStrm );
401             // zoom data not included in chart sheets
402             if( (getSheetType() != SHEETTYPE_CHARTSHEET) && (rStrm.getRemaining() >= 6) )
403             {
404                 rStrm.skip( 2 );
405                 sal_uInt16 nPageZoom, nNormalZoom;
406                 rStrm >> nPageZoom >> nNormalZoom;
407                 rModel.mnSheetLayoutZoom = nPageZoom;
408                 rModel.mnNormalZoom = nNormalZoom;
409             }
410         }
411         else
412         {
413             rModel.maGridColor.importColorRgb( rStrm );
414         }
415     }
416 }
417 
importPane(BiffInputStream & rStrm)418 void SheetViewSettings::importPane( BiffInputStream& rStrm )
419 {
420     OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing leading WINDOW2 record" );
421     if( !maSheetViews.empty() )
422     {
423         sal_uInt8 nActivePaneId;
424         sal_uInt16 nSplitX, nSplitY;
425         BinAddress aSecondPos;
426         rStrm >> nSplitX >> nSplitY >> aSecondPos >> nActivePaneId;
427 
428         SheetViewModel& rModel = *maSheetViews.back();
429         rModel.mfSplitX = nSplitX;
430         rModel.mfSplitY = nSplitY;
431         rModel.maSecondPos = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false );
432         rModel.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft );
433     }
434 }
435 
importScl(BiffInputStream & rStrm)436 void SheetViewSettings::importScl( BiffInputStream& rStrm )
437 {
438     OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importScl - missing leading WINDOW2 record" );
439     if( !maSheetViews.empty() )
440     {
441         sal_uInt16 nNum, nDenom;
442         rStrm >> nNum >> nDenom;
443         OSL_ENSURE( nDenom > 0, "SheetViewSettings::importScl - invalid denominator" );
444         if( nDenom > 0 )
445             maSheetViews.back()->mnCurrentZoom = getLimitedValue< sal_Int32, sal_uInt16 >( (nNum * 100) / nDenom, 10, 400 );
446     }
447 }
448 
importSelection(BiffInputStream & rStrm)449 void SheetViewSettings::importSelection( BiffInputStream& rStrm )
450 {
451     OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing leading WINDOW2 record" );
452     if( !maSheetViews.empty() )
453     {
454         // pane this selection belongs to
455         sal_uInt8 nPaneId = rStrm.readuInt8();
456         PaneSelectionModel& rPaneSel = maSheetViews.back()->createPaneSelection( lclGetOoxPaneId( nPaneId, -1 ) );
457         // cursor position
458         BinAddress aActiveCell;
459         sal_uInt16 nActiveCellId;
460         rStrm >> aActiveCell >> nActiveCellId;
461         rPaneSel.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false );
462         rPaneSel.mnActiveCellId = nActiveCellId;
463         // selection
464         rPaneSel.maSelection.clear();
465         BinRangeList aSelection;
466         aSelection.read( rStrm, false );
467         getAddressConverter().convertToCellRangeList( rPaneSel.maSelection, aSelection, getSheetIndex(), false );
468     }
469 }
470 
finalizeImport()471 void SheetViewSettings::finalizeImport()
472 {
473     // force creation of sheet view model to get the Excel defaults
474     SheetViewModelRef xModel = maSheetViews.empty() ? createSheetView() : maSheetViews.front();
475 
476     // #i59590# #158194# special handling for chart sheets (Excel ignores some settings in chart sheets)
477     if( getSheetType() == SHEETTYPE_CHARTSHEET )
478     {
479         xModel->maPaneSelMap.clear();
480         xModel->maFirstPos = xModel->maSecondPos = CellAddress( getSheetIndex(), 0, 0 );
481         xModel->mnViewType = XML_normal;
482         xModel->mnActivePaneId = XML_topLeft;
483         xModel->mnPaneState = XML_split;
484         xModel->mfSplitX = xModel->mfSplitY = 0.0;
485         xModel->mbRightToLeft = false;
486         xModel->mbDefGridColor = true;
487         xModel->mbShowFormulas = false;
488         xModel->mbShowGrid = true;
489         xModel->mbShowHeadings = true;
490         xModel->mbShowZeros = true;
491         xModel->mbShowOutline = true;
492     }
493 
494     // sheet selected (active sheet must be selected)
495     bool bSelected = xModel->mbSelected || (getSheetIndex() == getViewSettings().getActiveCalcSheet());
496 
497     // visible area and current cursor position (selection not supported via API)
498     CellAddress aFirstPos = xModel->maFirstPos;
499     const PaneSelectionModel* pPaneSel = xModel->getActiveSelection();
500     CellAddress aCursor = pPaneSel ? pPaneSel->maActiveCell : aFirstPos;
501 
502     // freeze/split position default
503     sal_Int16 nHSplitMode = API_SPLITMODE_NONE;
504     sal_Int16 nVSplitMode = API_SPLITMODE_NONE;
505     sal_Int32 nHSplitPos = 0;
506     sal_Int32 nVSplitPos = 0;
507     // active pane default
508     sal_Int16 nActivePane = API_SPLITPANE_BOTTOMLEFT;
509 
510     // freeze/split position
511     if( (xModel->mnPaneState == XML_frozen) || (xModel->mnPaneState == XML_frozenSplit) )
512     {
513         /*  Frozen panes: handle split position as row/column positions.
514             #i35812# Excel uses number of visible rows/columns in the
515                 frozen area (rows/columns scolled outside are not incuded),
516                 Calc uses absolute position of first unfrozen row/column. */
517         const CellAddress& rMaxApiPos = getAddressConverter().getMaxApiAddress();
518         if( (xModel->mfSplitX >= 1.0) && (xModel->maFirstPos.Column + xModel->mfSplitX <= rMaxApiPos.Column) )
519             nHSplitPos = static_cast< sal_Int32 >( xModel->maFirstPos.Column + xModel->mfSplitX );
520         nHSplitMode = (nHSplitPos > 0) ? API_SPLITMODE_FREEZE : API_SPLITMODE_NONE;
521         if( (xModel->mfSplitY >= 1.0) && (xModel->maFirstPos.Row + xModel->mfSplitY <= rMaxApiPos.Row) )
522             nVSplitPos = static_cast< sal_Int32 >( xModel->maFirstPos.Row + xModel->mfSplitY );
523         nVSplitMode = (nVSplitPos > 0) ? API_SPLITMODE_FREEZE : API_SPLITMODE_NONE;
524     }
525     else if( xModel->mnPaneState == XML_split )
526     {
527         // split window: view settings API uses twips...
528         nHSplitPos = getLimitedValue< sal_Int32, double >( xModel->mfSplitX + 0.5, 0, SAL_MAX_INT32 );
529         nHSplitMode = (nHSplitPos > 0) ? API_SPLITMODE_SPLIT : API_SPLITMODE_NONE;
530         nVSplitPos = getLimitedValue< sal_Int32, double >( xModel->mfSplitY + 0.5, 0, SAL_MAX_INT32 );
531         nVSplitMode = (nVSplitPos > 0) ? API_SPLITMODE_SPLIT : API_SPLITMODE_NONE;
532     }
533 
534     // active pane
535     switch( xModel->mnActivePaneId )
536     {
537         // no horizontal split -> always use left panes
538         // no vertical split -> always use *bottom* panes
539         case XML_topLeft:
540             nActivePane = (nVSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMLEFT : API_SPLITPANE_TOPLEFT;
541         break;
542         case XML_topRight:
543             nActivePane = (nHSplitMode == API_SPLITMODE_NONE) ?
544                 ((nVSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMLEFT : API_SPLITPANE_TOPLEFT) :
545                 ((nVSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMRIGHT : API_SPLITPANE_TOPRIGHT);
546         break;
547         case XML_bottomLeft:
548             nActivePane = API_SPLITPANE_BOTTOMLEFT;
549         break;
550         case XML_bottomRight:
551             nActivePane = (nHSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMLEFT : API_SPLITPANE_BOTTOMRIGHT;
552         break;
553     }
554 
555     // write the sheet view settings into the property sequence
556     PropertyMap aPropMap;
557     aPropMap[ PROP_TableSelected ]                <<= bSelected;
558     aPropMap[ PROP_CursorPositionX ]              <<= aCursor.Column;
559     aPropMap[ PROP_CursorPositionY ]              <<= aCursor.Row;
560     aPropMap[ PROP_HorizontalSplitMode ]          <<= nHSplitMode;
561     aPropMap[ PROP_VerticalSplitMode ]            <<= nVSplitMode;
562     aPropMap[ PROP_HorizontalSplitPositionTwips ] <<= nHSplitPos;
563     aPropMap[ PROP_VerticalSplitPositionTwips ]   <<= nVSplitPos;
564     aPropMap[ PROP_ActiveSplitRange ]             <<= nActivePane;
565     aPropMap[ PROP_PositionLeft ]                 <<= aFirstPos.Column;
566     aPropMap[ PROP_PositionTop ]                  <<= aFirstPos.Row;
567     aPropMap[ PROP_PositionRight ]                <<= xModel->maSecondPos.Column;
568     aPropMap[ PROP_PositionBottom ]               <<= ((nVSplitPos > 0) ? xModel->maSecondPos.Row : xModel->maFirstPos.Row);
569     aPropMap[ PROP_ZoomType ]                     <<= API_ZOOMTYPE_PERCENT;
570     aPropMap[ PROP_ZoomValue ]                    <<= static_cast< sal_Int16 >( xModel->getNormalZoom() );
571     aPropMap[ PROP_PageViewZoomValue ]            <<= static_cast< sal_Int16 >( xModel->getPageBreakZoom() );
572     aPropMap[ PROP_GridColor ]                    <<= xModel->getGridColor( getBaseFilter() );
573     aPropMap[ PROP_ShowPageBreakPreview ]         <<= xModel->isPageBreakPreview();
574     aPropMap[ PROP_ShowFormulas ]                 <<= xModel->mbShowFormulas;
575     aPropMap[ PROP_ShowGrid ]                     <<= xModel->mbShowGrid;
576     aPropMap[ PROP_HasColumnRowHeaders ]          <<= xModel->mbShowHeadings;
577     aPropMap[ PROP_ShowZeroValues ]               <<= xModel->mbShowZeros;
578     aPropMap[ PROP_IsOutlineSymbolsSet ]          <<= xModel->mbShowOutline;
579 
580     // store sheet view settings in global view settings object
581     getViewSettings().setSheetViewSettings( getSheetIndex(), xModel, Any( aPropMap.makePropertyValueSequence() ) );
582 }
583 
isSheetRightToLeft() const584 bool SheetViewSettings::isSheetRightToLeft() const
585 {
586     return !maSheetViews.empty() && maSheetViews.front()->mbRightToLeft;
587 }
588 
589 // private --------------------------------------------------------------------
590 
createSheetView()591 SheetViewModelRef SheetViewSettings::createSheetView()
592 {
593     SheetViewModelRef xModel( new SheetViewModel );
594     maSheetViews.push_back( xModel );
595     return xModel;
596 }
597 
598 // ============================================================================
599 
WorkbookViewModel()600 WorkbookViewModel::WorkbookViewModel() :
601     mnWinX( 0 ),
602     mnWinY( 0 ),
603     mnWinWidth( 0 ),
604     mnWinHeight( 0 ),
605     mnActiveSheet( 0 ),
606     mnFirstVisSheet( 0 ),
607     mnTabBarWidth( OOX_BOOKVIEW_TABBARRATIO_DEF ),
608     mnVisibility( XML_visible ),
609     mbShowTabBar( true ),
610     mbShowHorScroll( true ),
611     mbShowVerScroll( true ),
612     mbMinimized( false )
613 {
614 }
615 
616 // ----------------------------------------------------------------------------
617 
ViewSettings(const WorkbookHelper & rHelper)618 ViewSettings::ViewSettings( const WorkbookHelper& rHelper ) :
619     WorkbookHelper( rHelper ),
620     mbValidOleSize( false )
621 {
622 }
623 
importWorkbookView(const AttributeList & rAttribs)624 void ViewSettings::importWorkbookView( const AttributeList& rAttribs )
625 {
626     WorkbookViewModel& rModel = createWorkbookView();
627     rModel.mnWinX          = rAttribs.getInteger( XML_xWindow, 0 );
628     rModel.mnWinY          = rAttribs.getInteger( XML_yWindow, 0 );
629     rModel.mnWinWidth      = rAttribs.getInteger( XML_windowWidth, 0 );
630     rModel.mnWinHeight     = rAttribs.getInteger( XML_windowHeight, 0 );
631     rModel.mnActiveSheet   = rAttribs.getInteger( XML_activeTab, 0 );
632     rModel.mnFirstVisSheet = rAttribs.getInteger( XML_firstSheet, 0 );
633     rModel.mnTabBarWidth   = rAttribs.getInteger( XML_tabRatio, 600 );
634     rModel.mnVisibility    = rAttribs.getToken( XML_visibility, XML_visible );
635     rModel.mbShowTabBar    = rAttribs.getBool( XML_showSheetTabs, true );
636     rModel.mbShowHorScroll = rAttribs.getBool( XML_showHorizontalScroll, true );
637     rModel.mbShowVerScroll = rAttribs.getBool( XML_showVerticalScroll, true );
638     rModel.mbMinimized     = rAttribs.getBool( XML_minimized, false );
639 }
640 
importOleSize(const AttributeList & rAttribs)641 void ViewSettings::importOleSize( const AttributeList& rAttribs )
642 {
643     OUString aRange = rAttribs.getString( XML_ref, OUString() );
644     mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aRange, 0, true, false );
645 }
646 
importWorkbookView(SequenceInputStream & rStrm)647 void ViewSettings::importWorkbookView( SequenceInputStream& rStrm )
648 {
649     WorkbookViewModel& rModel = createWorkbookView();
650     sal_uInt8 nFlags;
651     rStrm >> rModel.mnWinX >> rModel.mnWinY >> rModel.mnWinWidth >> rModel.mnWinHeight >> rModel.mnTabBarWidth >> rModel.mnFirstVisSheet >> rModel.mnActiveSheet >> nFlags;
652     rModel.mnVisibility    = getFlagValue( nFlags, BIFF12_WBVIEW_HIDDEN, XML_hidden, XML_visible );
653     rModel.mbShowTabBar    = getFlag( nFlags, BIFF12_WBVIEW_SHOWTABBAR );
654     rModel.mbShowHorScroll = getFlag( nFlags, BIFF12_WBVIEW_SHOWHORSCROLL );
655     rModel.mbShowVerScroll = getFlag( nFlags, BIFF12_WBVIEW_SHOWVERSCROLL );
656     rModel.mbMinimized     = getFlag( nFlags, BIFF12_WBVIEW_MINIMIZED );
657 }
658 
importOleSize(SequenceInputStream & rStrm)659 void ViewSettings::importOleSize( SequenceInputStream& rStrm )
660 {
661     BinRange aBinRange;
662     rStrm >> aBinRange;
663     mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aBinRange, 0, true, false );
664 }
665 
importWindow1(BiffInputStream & rStrm)666 void ViewSettings::importWindow1( BiffInputStream& rStrm )
667 {
668     sal_uInt16 nWinX, nWinY, nWinWidth, nWinHeight;
669     rStrm >> nWinX >> nWinY >> nWinWidth >> nWinHeight;
670 
671     // WINDOW1 record occures in every sheet in BIFF4W
672     OSL_ENSURE( maBookViews.empty() || ((getBiff() == BIFF4) && isWorkbookFile()),
673         "ViewSettings::importWindow1 - multiple WINDOW1 records" );
674     WorkbookViewModel& rModel = createWorkbookView();
675     rModel.mnWinX = nWinX;
676     rModel.mnWinY = nWinY;
677     rModel.mnWinWidth = nWinWidth;
678     rModel.mnWinHeight = nWinHeight;
679 
680     if( getBiff() <= BIFF4 )
681     {
682         sal_uInt8 nHidden;
683         rStrm >> nHidden;
684         rModel.mnVisibility = (nHidden == 0) ? XML_visible : XML_hidden;
685     }
686     else
687     {
688         sal_uInt16 nFlags, nActiveTab, nFirstVisTab, nSelectCnt, nTabBarWidth;
689         rStrm >> nFlags >> nActiveTab >> nFirstVisTab >> nSelectCnt >> nTabBarWidth;
690 
691         rModel.mnActiveSheet = nActiveTab;
692         rModel.mnFirstVisSheet = nFirstVisTab;
693         rModel.mnTabBarWidth = nTabBarWidth;
694         rModel.mnVisibility = getFlagValue( nFlags, BIFF_WINDOW1_HIDDEN, XML_hidden, XML_visible );
695         rModel.mbMinimized = getFlag( nFlags, BIFF_WINDOW1_MINIMIZED );
696         rModel.mbShowHorScroll = getFlag( nFlags, BIFF_WINDOW1_SHOWHORSCROLL );
697         rModel.mbShowVerScroll = getFlag( nFlags, BIFF_WINDOW1_SHOWVERSCROLL );
698         rModel.mbShowTabBar = getFlag( nFlags, BIFF_WINDOW1_SHOWTABBAR );
699     }
700 }
701 
importOleSize(BiffInputStream & rStrm)702 void ViewSettings::importOleSize( BiffInputStream& rStrm )
703 {
704     rStrm.skip( 2 );
705     BinRange aBinRange;
706     aBinRange.read( rStrm, false );
707     mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aBinRange, 0, true, false );
708 }
709 
setSheetViewSettings(sal_Int16 nSheet,const SheetViewModelRef & rxSheetView,const Any & rProperties)710 void ViewSettings::setSheetViewSettings( sal_Int16 nSheet, const SheetViewModelRef& rxSheetView, const Any& rProperties )
711 {
712     maSheetViews[ nSheet ] = rxSheetView;
713     maSheetProps[ nSheet ] = rProperties;
714 }
715 
setSheetUsedArea(const CellRangeAddress & rUsedArea)716 void ViewSettings::setSheetUsedArea( const CellRangeAddress& rUsedArea )
717 {
718     maSheetUsedAreas[ rUsedArea.Sheet ] = rUsedArea;
719 }
720 
finalizeImport()721 void ViewSettings::finalizeImport()
722 {
723     const WorksheetBuffer& rWorksheets = getWorksheets();
724     if( rWorksheets.getWorksheetCount() <= 0 ) return;
725 
726     // force creation of workbook view model to get the Excel defaults
727     const WorkbookViewModel& rModel = maBookViews.empty() ? createWorkbookView() : *maBookViews.front();
728 
729     // show object mode is part of workbook settings
730     sal_Int16 nShowMode = getWorkbookSettings().getApiShowObjectMode();
731 
732     // view settings for all sheets
733     Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getBaseFilter().getComponentContext() );
734     if( !xSheetsNC.is() ) return;
735     for( SheetPropertiesMap::const_iterator aIt = maSheetProps.begin(), aEnd = maSheetProps.end(); aIt != aEnd; ++aIt )
736         ContainerHelper::insertByName( xSheetsNC, rWorksheets.getCalcSheetName( aIt->first ), aIt->second );
737 
738     // use active sheet to set sheet properties that are document-global in Calc
739     sal_Int16 nActiveSheet = getActiveCalcSheet();
740     SheetViewModelRef& rxActiveSheetView = maSheetViews[ nActiveSheet ];
741     OSL_ENSURE( rxActiveSheetView.get(), "ViewSettings::finalizeImport - missing active sheet view settings" );
742     if( !rxActiveSheetView )
743         rxActiveSheetView.reset( new SheetViewModel );
744 
745     Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getBaseFilter().getComponentContext() );
746     if( xContainer.is() ) try
747     {
748         PropertyMap aPropMap;
749         aPropMap[ PROP_Tables ]                        <<= xSheetsNC;
750         aPropMap[ PROP_ActiveTable ]                   <<= rWorksheets.getCalcSheetName( nActiveSheet );
751         aPropMap[ PROP_HasHorizontalScrollBar ]        <<= rModel.mbShowHorScroll;
752         aPropMap[ PROP_HasVerticalScrollBar ]          <<= rModel.mbShowVerScroll;
753         aPropMap[ PROP_HasSheetTabs ]                  <<= rModel.mbShowTabBar;
754         aPropMap[ PROP_RelativeHorizontalTabbarWidth ] <<= double( rModel.mnTabBarWidth / 1000.0 );
755         aPropMap[ PROP_ShowObjects ]                   <<= nShowMode;
756         aPropMap[ PROP_ShowCharts ]                    <<= nShowMode;
757         aPropMap[ PROP_ShowDrawing ]                   <<= nShowMode;
758         aPropMap[ PROP_GridColor ]                     <<= rxActiveSheetView->getGridColor( getBaseFilter() );
759         aPropMap[ PROP_ShowPageBreakPreview ]          <<= rxActiveSheetView->isPageBreakPreview();
760         aPropMap[ PROP_ShowFormulas ]                  <<= rxActiveSheetView->mbShowFormulas;
761         aPropMap[ PROP_ShowGrid ]                      <<= rxActiveSheetView->mbShowGrid;
762         aPropMap[ PROP_HasColumnRowHeaders ]           <<= rxActiveSheetView->mbShowHeadings;
763         aPropMap[ PROP_ShowZeroValues ]                <<= rxActiveSheetView->mbShowZeros;
764         aPropMap[ PROP_IsOutlineSymbolsSet ]           <<= rxActiveSheetView->mbShowOutline;
765 
766         xContainer->insertByIndex( 0, Any( aPropMap.makePropertyValueSequence() ) );
767         Reference< XIndexAccess > xIAccess( xContainer, UNO_QUERY_THROW );
768         Reference< XViewDataSupplier > xViewDataSuppl( getDocument(), UNO_QUERY_THROW );
769         xViewDataSuppl->setViewData( xIAccess );
770     }
771     catch( Exception& )
772     {
773         OSL_ENSURE( false, "ViewSettings::finalizeImport - cannot create document view settings" );
774     }
775 
776     /*  Set visible area to be used if this document is an embedded OLE object.
777         #i44077# If a new OLE object is inserted from file, there is no OLESIZE
778         record in the Excel file. In this case, use the used area calculated
779         from file contents (used cells and drawing objects). */
780     maOleSize.Sheet = nActiveSheet;
781     const CellRangeAddress* pVisibleArea = mbValidOleSize ?
782         &maOleSize : ContainerHelper::getMapElement( maSheetUsedAreas, nActiveSheet );
783     if( pVisibleArea )
784     {
785         // calculate the visible area in units of 1/100 mm
786         PropertySet aRangeProp( getCellRangeFromDoc( *pVisibleArea ) );
787         Point aPos;
788         Size aSize;
789         if( aRangeProp.getProperty( aPos, PROP_Position ) && aRangeProp.getProperty( aSize, PROP_Size ) )
790         {
791             // set the visible area as sequence of long at the media descriptor
792             Sequence< sal_Int32 > aWinExtent( 4 );
793             aWinExtent[ 0 ] = aPos.X;
794             aWinExtent[ 1 ] = aPos.Y;
795             aWinExtent[ 2 ] = aPos.X + aSize.Width;
796             aWinExtent[ 3 ] = aPos.Y + aSize.Height;
797             getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "WinExtent" ) ] <<= aWinExtent;
798         }
799     }
800 }
801 
getActiveCalcSheet() const802 sal_Int16 ViewSettings::getActiveCalcSheet() const
803 {
804     return maBookViews.empty() ? 0 : ::std::max< sal_Int16 >( getWorksheets().getCalcSheetIndex( maBookViews.front()->mnActiveSheet ), 0 );
805 }
806 
807 // private --------------------------------------------------------------------
808 
createWorkbookView()809 WorkbookViewModel& ViewSettings::createWorkbookView()
810 {
811     WorkbookViewModelRef xModel( new WorkbookViewModel );
812     maBookViews.push_back( xModel );
813     return *xModel;
814 }
815 
816 // ============================================================================
817 
818 } // namespace xls
819 } // namespace oox
820