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