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