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