1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/xls/worksheetsettings.hxx"
29 
30 #include <com/sun/star/util/XProtectable.hpp>
31 #include "oox/core/filterbase.hxx"
32 #include "oox/helper/attributelist.hxx"
33 #include "oox/xls/biffinputstream.hxx"
34 #include "oox/xls/pagesettings.hxx"
35 #include "oox/xls/workbooksettings.hxx"
36 
37 namespace oox {
38 namespace xls {
39 
40 // ============================================================================
41 
42 using namespace ::com::sun::star::beans;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::util;
45 
46 using ::oox::core::CodecHelper;
47 using ::rtl::OUString;
48 
49 // ============================================================================
50 
51 namespace {
52 
53 const sal_uInt8 BIFF12_SHEETPR_FILTERMODE       = 0x01;
54 const sal_uInt8 BIFF12_SHEETPR_EVAL_CF          = 0x02;
55 
56 const sal_uInt32 BIFF_SHEETEXT_NOTABCOLOR       = 0x7F;
57 
58 const sal_uInt16 BIFF_SHEETPR_DIALOGSHEET       = 0x0010;
59 const sal_uInt16 BIFF_SHEETPR_APPLYSTYLES       = 0x0020;
60 const sal_uInt16 BIFF_SHEETPR_SYMBOLSBELOW      = 0x0040;
61 const sal_uInt16 BIFF_SHEETPR_SYMBOLSRIGHT      = 0x0080;
62 const sal_uInt16 BIFF_SHEETPR_FITTOPAGES        = 0x0100;
63 const sal_uInt16 BIFF_SHEETPR_SKIPEXT           = 0x0200;       // BIFF3-BIFF4
64 
65 const sal_uInt32 BIFF_SHEETPROT_OBJECTS         = 0x00000001;
66 const sal_uInt32 BIFF_SHEETPROT_SCENARIOS       = 0x00000002;
67 const sal_uInt32 BIFF_SHEETPROT_FORMAT_CELLS    = 0x00000004;
68 const sal_uInt32 BIFF_SHEETPROT_FORMAT_COLUMNS  = 0x00000008;
69 const sal_uInt32 BIFF_SHEETPROT_FORMAT_ROWS     = 0x00000010;
70 const sal_uInt32 BIFF_SHEETPROT_INSERT_COLUMNS  = 0x00000020;
71 const sal_uInt32 BIFF_SHEETPROT_INSERT_ROWS     = 0x00000040;
72 const sal_uInt32 BIFF_SHEETPROT_INSERT_HLINKS   = 0x00000080;
73 const sal_uInt32 BIFF_SHEETPROT_DELETE_COLUMNS  = 0x00000100;
74 const sal_uInt32 BIFF_SHEETPROT_DELETE_ROWS     = 0x00000200;
75 const sal_uInt32 BIFF_SHEETPROT_SELECT_LOCKED   = 0x00000400;
76 const sal_uInt32 BIFF_SHEETPROT_SORT            = 0x00000800;
77 const sal_uInt32 BIFF_SHEETPROT_AUTOFILTER      = 0x00001000;
78 const sal_uInt32 BIFF_SHEETPROT_PIVOTTABLES     = 0x00002000;
79 const sal_uInt32 BIFF_SHEETPROT_SELECT_UNLOCKED = 0x00004000;
80 
81 } // namespace
82 
83 // ============================================================================
84 
85 SheetSettingsModel::SheetSettingsModel() :
86     mbFilterMode( false ),
87     mbApplyStyles( false ),
88     mbSummaryBelow( true ),
89     mbSummaryRight( true )
90 {
91 }
92 
93 // ============================================================================
94 
95 SheetProtectionModel::SheetProtectionModel() :
96     mnPasswordHash( 0 ),
97     mbSheet( false ),
98     mbObjects( false ),
99     mbScenarios( false ),
100     mbFormatCells( true ),
101     mbFormatColumns( true ),
102     mbFormatRows( true ),
103     mbInsertColumns( true ),
104     mbInsertRows( true ),
105     mbInsertHyperlinks( true ),
106     mbDeleteColumns( true ),
107     mbDeleteRows( true ),
108     mbSelectLocked( false ),
109     mbSort( true ),
110     mbAutoFilter( true ),
111     mbPivotTables( true ),
112     mbSelectUnlocked( false )
113 {
114 }
115 
116 // ============================================================================
117 
118 WorksheetSettings::WorksheetSettings( const WorksheetHelper& rHelper ) :
119     WorksheetHelper( rHelper ),
120     maPhoneticSett( rHelper )
121 {
122 }
123 
124 void WorksheetSettings::importSheetPr( const AttributeList& rAttribs )
125 {
126     maSheetSettings.maCodeName = rAttribs.getString( XML_codeName, OUString() );
127     maSheetSettings.mbFilterMode = rAttribs.getBool( XML_filterMode, false );
128 }
129 
130 void WorksheetSettings::importChartSheetPr( const AttributeList& rAttribs )
131 {
132     maSheetSettings.maCodeName = rAttribs.getString( XML_codeName, OUString() );
133 }
134 
135 void WorksheetSettings::importTabColor( const AttributeList& rAttribs )
136 {
137     maSheetSettings.maTabColor.importColor( rAttribs );
138 }
139 
140 void WorksheetSettings::importOutlinePr( const AttributeList& rAttribs )
141 {
142     maSheetSettings.mbApplyStyles  = rAttribs.getBool( XML_applyStyles, false );
143     maSheetSettings.mbSummaryBelow = rAttribs.getBool( XML_summaryBelow, true );
144     maSheetSettings.mbSummaryRight = rAttribs.getBool( XML_summaryRight, true );
145 }
146 
147 void WorksheetSettings::importSheetProtection( const AttributeList& rAttribs )
148 {
149     maSheetProt.mnPasswordHash     = CodecHelper::getPasswordHash( rAttribs, XML_password );
150     maSheetProt.mbSheet            = rAttribs.getBool( XML_sheet, false );
151     maSheetProt.mbObjects          = rAttribs.getBool( XML_objects, false );
152     maSheetProt.mbScenarios        = rAttribs.getBool( XML_scenarios, false );
153     maSheetProt.mbFormatCells      = rAttribs.getBool( XML_formatCells, true );
154     maSheetProt.mbFormatColumns    = rAttribs.getBool( XML_formatColumns, true );
155     maSheetProt.mbFormatRows       = rAttribs.getBool( XML_formatRows, true );
156     maSheetProt.mbInsertColumns    = rAttribs.getBool( XML_insertColumns, true );
157     maSheetProt.mbInsertRows       = rAttribs.getBool( XML_insertRows, true );
158     maSheetProt.mbInsertHyperlinks = rAttribs.getBool( XML_insertHyperlinks, true );
159     maSheetProt.mbDeleteColumns    = rAttribs.getBool( XML_deleteColumns, true );
160     maSheetProt.mbDeleteRows       = rAttribs.getBool( XML_deleteRows, true );
161     maSheetProt.mbSelectLocked     = rAttribs.getBool( XML_selectLockedCells, false );
162     maSheetProt.mbSort             = rAttribs.getBool( XML_sort, true );
163     maSheetProt.mbAutoFilter       = rAttribs.getBool( XML_autoFilter, true );
164     maSheetProt.mbPivotTables      = rAttribs.getBool( XML_pivotTables, true );
165     maSheetProt.mbSelectUnlocked   = rAttribs.getBool( XML_selectUnlockedCells, false );
166 }
167 
168 void WorksheetSettings::importChartProtection( const AttributeList& rAttribs )
169 {
170     maSheetProt.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_password );
171     maSheetProt.mbSheet        = rAttribs.getBool( XML_content, false );
172     maSheetProt.mbObjects      = rAttribs.getBool( XML_objects, false );
173 }
174 
175 void WorksheetSettings::importPhoneticPr( const AttributeList& rAttribs )
176 {
177     maPhoneticSett.importPhoneticPr( rAttribs );
178 }
179 
180 void WorksheetSettings::importSheetPr( SequenceInputStream& rStrm )
181 {
182     sal_uInt16 nFlags1;
183     sal_uInt8 nFlags2;
184     rStrm >> nFlags1 >> nFlags2 >> maSheetSettings.maTabColor;
185     rStrm.skip( 8 );    // sync anchor cell
186     rStrm >> maSheetSettings.maCodeName;
187     // sheet settings
188     maSheetSettings.mbFilterMode = getFlag( nFlags2, BIFF12_SHEETPR_FILTERMODE );
189     // outline settings, equal flags in all BIFFs
190     maSheetSettings.mbApplyStyles  = getFlag( nFlags1, BIFF_SHEETPR_APPLYSTYLES );
191     maSheetSettings.mbSummaryRight = getFlag( nFlags1, BIFF_SHEETPR_SYMBOLSRIGHT );
192     maSheetSettings.mbSummaryBelow = getFlag( nFlags1, BIFF_SHEETPR_SYMBOLSBELOW );
193     /*  Fit printout to width/height - for whatever reason, this flag is still
194         stored separated from the page settings */
195     getPageSettings().setFitToPagesMode( getFlag( nFlags1, BIFF_SHEETPR_FITTOPAGES ) );
196 }
197 
198 void WorksheetSettings::importChartSheetPr( SequenceInputStream& rStrm )
199 {
200     rStrm.skip( 2 );    // flags, contains only the 'published' flag
201     rStrm >> maSheetSettings.maTabColor >> maSheetSettings.maCodeName;
202 }
203 
204 void WorksheetSettings::importSheetProtection( SequenceInputStream& rStrm )
205 {
206     rStrm >> maSheetProt.mnPasswordHash;
207     // no flags field for all these boolean flags?!?
208     maSheetProt.mbSheet            = rStrm.readInt32() != 0;
209     maSheetProt.mbObjects          = rStrm.readInt32() != 0;
210     maSheetProt.mbScenarios        = rStrm.readInt32() != 0;
211     maSheetProt.mbFormatCells      = rStrm.readInt32() != 0;
212     maSheetProt.mbFormatColumns    = rStrm.readInt32() != 0;
213     maSheetProt.mbFormatRows       = rStrm.readInt32() != 0;
214     maSheetProt.mbInsertColumns    = rStrm.readInt32() != 0;
215     maSheetProt.mbInsertRows       = rStrm.readInt32() != 0;
216     maSheetProt.mbInsertHyperlinks = rStrm.readInt32() != 0;
217     maSheetProt.mbDeleteColumns    = rStrm.readInt32() != 0;
218     maSheetProt.mbDeleteRows       = rStrm.readInt32() != 0;
219     maSheetProt.mbSelectLocked     = rStrm.readInt32() != 0;
220     maSheetProt.mbSort             = rStrm.readInt32() != 0;
221     maSheetProt.mbAutoFilter       = rStrm.readInt32() != 0;
222     maSheetProt.mbPivotTables      = rStrm.readInt32() != 0;
223     maSheetProt.mbSelectUnlocked   = rStrm.readInt32() != 0;
224 }
225 
226 void WorksheetSettings::importChartProtection( SequenceInputStream& rStrm )
227 {
228     rStrm >> maSheetProt.mnPasswordHash;
229     // no flags field for all these boolean flags?!?
230     maSheetProt.mbSheet            = rStrm.readInt32() != 0;
231     maSheetProt.mbObjects          = rStrm.readInt32() != 0;
232 }
233 
234 void WorksheetSettings::importPhoneticPr( SequenceInputStream& rStrm )
235 {
236     maPhoneticSett.importPhoneticPr( rStrm );
237 }
238 
239 void WorksheetSettings::importSheetExt( BiffInputStream& rStrm )
240 {
241     rStrm.skip( 16 );
242     sal_uInt32 nFlags;
243     rStrm >> nFlags;
244     sal_uInt8 nColorIdx = extractValue< sal_uInt8 >( nFlags, 0, 7 );
245     if( nColorIdx != BIFF_SHEETEXT_NOTABCOLOR )
246         maSheetSettings.maTabColor.setPaletteClr( nColorIdx );
247 }
248 
249 void WorksheetSettings::importSheetPr( BiffInputStream& rStrm )
250 {
251     sal_uInt16 nFlags;
252     rStrm >> nFlags;
253     // worksheet vs. dialogsheet
254     if( getFlag( nFlags, BIFF_SHEETPR_DIALOGSHEET ) )
255     {
256         OSL_ENSURE( getSheetType() == SHEETTYPE_WORKSHEET, "WorksheetSettings::importSheetPr - unexpected sheet type" );
257         setSheetType( SHEETTYPE_DIALOGSHEET );
258     }
259     // outline settings
260     maSheetSettings.mbApplyStyles  = getFlag( nFlags, BIFF_SHEETPR_APPLYSTYLES );
261     maSheetSettings.mbSummaryRight = getFlag( nFlags, BIFF_SHEETPR_SYMBOLSRIGHT );
262     maSheetSettings.mbSummaryBelow = getFlag( nFlags, BIFF_SHEETPR_SYMBOLSBELOW );
263     // fit printout to width/height
264     getPageSettings().setFitToPagesMode( getFlag( nFlags, BIFF_SHEETPR_FITTOPAGES ) );
265     // save external linked values, in BIFF5-BIFF8 moved to BOOKBOOK record
266     if( getBiff() <= BIFF4 )
267         getWorkbookSettings().setSaveExtLinkValues( !getFlag( nFlags, BIFF_SHEETPR_SKIPEXT ) );
268 }
269 
270 void WorksheetSettings::importProtect( BiffInputStream& rStrm )
271 {
272     maSheetProt.mbSheet = rStrm.readuInt16() != 0;
273 }
274 
275 void WorksheetSettings::importObjectProtect( BiffInputStream& rStrm )
276 {
277     maSheetProt.mbObjects = rStrm.readuInt16() != 0;
278 }
279 
280 void WorksheetSettings::importScenProtect( BiffInputStream& rStrm )
281 {
282     maSheetProt.mbScenarios = rStrm.readuInt16() != 0;
283 }
284 
285 void WorksheetSettings::importPassword( BiffInputStream& rStrm )
286 {
287     rStrm >> maSheetProt.mnPasswordHash;
288 }
289 
290 void WorksheetSettings::importSheetProtection( BiffInputStream& rStrm )
291 {
292     sal_uInt32 nFlags = rStrm.readuInt32();
293     // set flag means protection is disabled
294     maSheetProt.mbObjects          = !getFlag( nFlags, BIFF_SHEETPROT_OBJECTS );
295     maSheetProt.mbScenarios        = !getFlag( nFlags, BIFF_SHEETPROT_SCENARIOS );
296     maSheetProt.mbFormatCells      = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_CELLS );
297     maSheetProt.mbFormatColumns    = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_COLUMNS );
298     maSheetProt.mbFormatRows       = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_ROWS );
299     maSheetProt.mbInsertColumns    = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_COLUMNS );
300     maSheetProt.mbInsertRows       = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_ROWS );
301     maSheetProt.mbInsertHyperlinks = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_HLINKS );
302     maSheetProt.mbDeleteColumns    = !getFlag( nFlags, BIFF_SHEETPROT_DELETE_COLUMNS );
303     maSheetProt.mbDeleteRows       = !getFlag( nFlags, BIFF_SHEETPROT_DELETE_ROWS );
304     maSheetProt.mbSelectLocked     = !getFlag( nFlags, BIFF_SHEETPROT_SELECT_LOCKED );
305     maSheetProt.mbSort             = !getFlag( nFlags, BIFF_SHEETPROT_SORT );
306     maSheetProt.mbAutoFilter       = !getFlag( nFlags, BIFF_SHEETPROT_AUTOFILTER );
307     maSheetProt.mbPivotTables      = !getFlag( nFlags, BIFF_SHEETPROT_PIVOTTABLES );
308     maSheetProt.mbSelectUnlocked   = !getFlag( nFlags, BIFF_SHEETPROT_SELECT_UNLOCKED );
309 }
310 
311 void WorksheetSettings::importCodeName( BiffInputStream& rStrm )
312 {
313     maSheetSettings.maCodeName = rStrm.readUniString();
314 }
315 
316 void WorksheetSettings::importPhoneticPr( BiffInputStream& rStrm )
317 {
318     maPhoneticSett.importPhoneticPr( rStrm );
319 }
320 
321 void WorksheetSettings::finalizeImport()
322 {
323     // sheet protection
324     if( maSheetProt.mbSheet ) try
325     {
326         Reference< XProtectable > xProtectable( getSheet(), UNO_QUERY_THROW );
327         xProtectable->protect( OUString() );
328     }
329     catch( Exception& )
330     {
331     }
332 
333     // VBA code name
334     PropertySet aPropSet( getSheet() );
335     aPropSet.setProperty( PROP_CodeName, maSheetSettings.maCodeName );
336 
337     // sheet tab color
338     if( !maSheetSettings.maTabColor.isAuto() )
339     {
340         sal_Int32 nColor = maSheetSettings.maTabColor.getColor( getBaseFilter().getGraphicHelper() );
341         aPropSet.setProperty( PROP_TabColor, nColor );
342     }
343 }
344 
345 // ============================================================================
346 
347 } // namespace xls
348 } // namespace oox
349