Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "xicontent.hxx"
30 : : #include <sfx2/objsh.hxx>
31 : : #include <sfx2/docfile.hxx>
32 : : #include <tools/urlobj.hxx>
33 : : #include <editeng/editeng.hxx>
34 : : #include <editeng/editobj.hxx>
35 : : #include <sfx2/linkmgr.hxx>
36 : : #include <svl/itemset.hxx>
37 : : #include "scitems.hxx"
38 : : #include <editeng/eeitem.hxx>
39 : : #include <svl/intitem.hxx>
40 : : #include <svl/stritem.hxx>
41 : : #include <editeng/flditem.hxx>
42 : : #include <editeng/fhgtitem.hxx>
43 : : #include <editeng/wghtitem.hxx>
44 : : #include <editeng/udlnitem.hxx>
45 : : #include <editeng/postitem.hxx>
46 : : #include <editeng/colritem.hxx>
47 : : #include <editeng/crsditem.hxx>
48 : : #include "stringutil.hxx"
49 : : #include "document.hxx"
50 : : #include "editutil.hxx"
51 : : #include "cell.hxx"
52 : : #include "validat.hxx"
53 : : #include "patattr.hxx"
54 : : #include "docpool.hxx"
55 : : #include "rangenam.hxx"
56 : : #include "arealink.hxx"
57 : : #include "stlsheet.hxx"
58 : : #include "scextopt.hxx"
59 : : #include "xlformula.hxx"
60 : : #include "xltracer.hxx"
61 : : #include "xistream.hxx"
62 : : #include "xihelper.hxx"
63 : : #include "xistyle.hxx"
64 : : #include "xiescher.hxx"
65 : : #include "xiname.hxx"
66 : :
67 : : #include "excform.hxx"
68 : : #include "tabprotection.hxx"
69 : :
70 : : #include <memory>
71 : :
72 : : using ::com::sun::star::uno::Sequence;
73 : : using ::std::auto_ptr;
74 : :
75 : : // Shared string table ========================================================
76 : :
77 : 55 : XclImpSst::XclImpSst( const XclImpRoot& rRoot ) :
78 [ + - ]: 55 : XclImpRoot( rRoot )
79 : : {
80 : 55 : }
81 : :
82 : 43 : void XclImpSst::ReadSst( XclImpStream& rStrm )
83 : : {
84 [ + - ]: 43 : rStrm.Ignore( 4 );
85 : 43 : sal_uInt32 nStrCount(0);
86 [ + - ]: 43 : rStrm >> nStrCount;
87 : 43 : maStrings.clear();
88 [ + - ]: 43 : maStrings.reserve( static_cast< size_t >( nStrCount ) );
89 [ + + ][ + - ]: 850 : while( (nStrCount > 0) && rStrm.IsValid() )
[ + + ]
90 : : {
91 [ + - ]: 807 : XclImpString aString;
92 [ + - ]: 807 : aString.Read( rStrm );
93 [ + - ]: 807 : maStrings.push_back( aString );
94 : 807 : --nStrCount;
95 [ + - ]: 807 : }
96 : 43 : }
97 : :
98 : 2100 : const XclImpString* XclImpSst::GetString( sal_uInt32 nSstIndex ) const
99 : : {
100 [ + - ]: 2100 : return (nSstIndex < maStrings.size()) ? &maStrings[ nSstIndex ] : 0;
101 : : }
102 : :
103 : 2100 : ScBaseCell* XclImpSst::CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex ) const
104 : : {
105 : 2100 : ScBaseCell* pCell = 0;
106 [ + - ]: 2100 : if( const XclImpString* pString = GetString( nSstIndex ) )
107 : 2100 : pCell = XclImpStringHelper::CreateCell( *this, *pString, nXFIndex );
108 : 2100 : return pCell;
109 : : }
110 : :
111 : : // Hyperlinks =================================================================
112 : :
113 : : namespace {
114 : :
115 : : /** Reads character array and stores it into rString.
116 : : @param nChars Number of following characters (not byte count!).
117 : : @param b16Bit true = 16-bit characters, false = 8-bit characters. */
118 : 24 : void lclAppendString32( String& rString, XclImpStream& rStrm, sal_uInt32 nChars, bool b16Bit )
119 : : {
120 : 24 : sal_uInt16 nReadChars = ulimit_cast< sal_uInt16 >( nChars );
121 [ + - ]: 24 : rString.Append( rStrm.ReadRawUniString( nReadChars, b16Bit ) );
122 : : // ignore remaining chars
123 : 24 : sal_Size nIgnore = nChars - nReadChars;
124 [ + - ]: 24 : if( b16Bit )
125 : 24 : nIgnore *= 2;
126 : 24 : rStrm.Ignore( nIgnore );
127 : 24 : }
128 : :
129 : : /** Reads 32-bit string length and the character array and stores it into rString.
130 : : @param b16Bit true = 16-bit characters, false = 8-bit characters. */
131 : 0 : void lclAppendString32( String& rString, XclImpStream& rStrm, bool b16Bit )
132 : : {
133 : 0 : lclAppendString32( rString, rStrm, rStrm.ReaduInt32(), b16Bit );
134 : 0 : }
135 : :
136 : : /** Reads 32-bit string length and ignores following character array.
137 : : @param b16Bit true = 16-bit characters, false = 8-bit characters. */
138 : 21 : void lclIgnoreString32( XclImpStream& rStrm, bool b16Bit )
139 : : {
140 : 21 : sal_uInt32 nChars(0);
141 [ + - ]: 21 : rStrm >> nChars;
142 [ + - ]: 21 : if( b16Bit )
143 : 21 : nChars *= 2;
144 [ + - ]: 21 : rStrm.Ignore( nChars );
145 : 21 : }
146 : :
147 : : /** Converts a path to an absolute path.
148 : : @param rPath The source path. The resulting path is returned here.
149 : : @param nLevel Number of parent directories to add in front of the path. */
150 : 0 : void lclGetAbsPath( String& rPath, sal_uInt16 nLevel, SfxObjectShell* pDocShell )
151 : : {
152 [ # # ]: 0 : String aTmpStr;
153 [ # # ]: 0 : while( nLevel )
154 : : {
155 [ # # ]: 0 : aTmpStr.AppendAscii( "../" );
156 : 0 : --nLevel;
157 : : }
158 [ # # ]: 0 : aTmpStr += rPath;
159 : :
160 [ # # ]: 0 : if( pDocShell )
161 : : {
162 : 0 : bool bWasAbs = false;
163 [ # # ][ # # ]: 0 : rPath = pDocShell->GetMedium()->GetURLObject().smartRel2Abs( aTmpStr, bWasAbs ).GetMainURL( INetURLObject::NO_DECODE );
[ # # ][ # # ]
[ # # ][ # # ]
164 : : // full path as stored in SvxURLField must be encoded
165 : : }
166 : : else
167 [ # # ][ # # ]: 0 : rPath = aTmpStr;
168 : 0 : }
169 : :
170 : : /** Inserts the URL into a text cell. Does not modify value or formula cells. */
171 : 24 : void lclInsertUrl( const XclImpRoot& rRoot, const String& rUrl, SCCOL nScCol, SCROW nScRow, SCTAB nScTab )
172 : : {
173 : 24 : ScDocument& rDoc = rRoot.GetDoc();
174 : 24 : ScAddress aScPos( nScCol, nScRow, nScTab );
175 [ + - ]: 24 : CellType eCellType = rDoc.GetCellType( aScPos );
176 [ + - ]: 24 : switch( eCellType )
177 : : {
178 : : // #i54261# hyperlinks in string cells
179 : : case CELLTYPE_STRING:
180 : : case CELLTYPE_EDIT:
181 : : {
182 [ + - ]: 24 : String aDisplText;
183 [ + - ]: 24 : rDoc.GetString( nScCol, nScRow, nScTab, aDisplText );
184 [ - + ]: 24 : if( !aDisplText.Len() )
185 [ # # ]: 0 : aDisplText = rUrl;
186 : :
187 [ + - ]: 24 : ScEditEngineDefaulter& rEE = rRoot.GetEditEngine();
188 [ + - ][ + - ]: 24 : SvxURLField aUrlField( rUrl, aDisplText, SVXURLFORMAT_APPDEFAULT );
[ + - ]
189 : :
190 [ # # ][ - + ]: 24 : const ScEditCell* pEditCell = (eCellType == CELLTYPE_EDIT) ? static_cast< const ScEditCell* >( rDoc.GetCell( aScPos ) ) : 0;
191 [ - + ]: 24 : const EditTextObject* pEditObj = pEditCell ? pEditCell->GetData() : 0;
192 [ - + ]: 24 : if( pEditObj )
193 : : {
194 [ # # ]: 0 : rEE.SetText( *pEditObj );
195 [ # # ][ # # ]: 0 : rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection( 0, 0, 0xFFFF, 0 ) );
[ # # ]
196 : : }
197 : : else
198 : : {
199 [ + - ][ + - ]: 24 : rEE.SetText( EMPTY_STRING );
200 [ + - ][ + - ]: 24 : rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection() );
[ + - ]
201 [ + - ][ + - ]: 24 : if( const ScPatternAttr* pPattern = rDoc.GetPattern( aScPos.Col(), aScPos.Row(), nScTab ) )
202 : : {
203 [ + - ][ + - ]: 24 : SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
204 [ + - ]: 24 : pPattern->FillEditItemSet( &aItemSet );
205 [ + - ][ + - ]: 24 : rEE.QuickSetAttribs( aItemSet, ESelection( 0, 0, 0xFFFF, 0 ) );
206 : : }
207 : : }
208 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
209 [ + - ]: 24 : ::std::auto_ptr< EditTextObject > xTextObj( rEE.CreateTextObject() );
210 : : SAL_WNODEPRECATED_DECLARATIONS_POP
211 : :
212 [ + - ][ + - ]: 24 : ScEditCell* pCell = new ScEditCell( xTextObj.get(), &rDoc, rEE.GetEditTextObjectPool() );
[ + - ]
213 [ + - ][ + - ]: 24 : rDoc.PutCell( aScPos, pCell );
[ + - ][ + - ]
214 : : }
215 : 24 : break;
216 : :
217 : : default:;
218 : : }
219 : 24 : }
220 : :
221 : : } // namespace
222 : :
223 : : // ----------------------------------------------------------------------------
224 : :
225 : 24 : void XclImpHyperlink::ReadHlink( XclImpStream& rStrm )
226 : : {
227 : 24 : XclRange aXclRange( ScAddress::UNINITIALIZED );
228 [ + - ]: 24 : rStrm >> aXclRange;
229 : : // #i80006# Excel silently ignores invalid hi-byte of column index (TODO: everywhere?)
230 : 24 : aXclRange.maFirst.mnCol &= 0xFF;
231 : 24 : aXclRange.maLast.mnCol &= 0xFF;
232 [ + - ]: 24 : String aString = ReadEmbeddedData( rStrm );
233 [ + - ]: 24 : if ( aString.Len() > 0 )
234 [ + - ][ + - ]: 24 : rStrm.GetRoot().GetXFRangeBuffer().SetHyperlink( aXclRange, aString );
[ + - ]
235 : 24 : }
236 : :
237 : 24 : String XclImpHyperlink::ReadEmbeddedData( XclImpStream& rStrm )
238 : : {
239 : 24 : const XclImpRoot& rRoot = rStrm.GetRoot();
240 [ + - ]: 24 : SfxObjectShell* pDocShell = rRoot.GetDocShell();
241 : :
242 : : OSL_ENSURE_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
243 : :
244 [ + - ]: 24 : XclGuid aGuid;
245 [ + - ]: 24 : rStrm >> aGuid;
246 [ + - ]: 24 : rStrm.Ignore( 4 );
247 : 24 : sal_uInt32 nFlags(0);
248 [ + - ]: 24 : rStrm >> nFlags;
249 : :
250 : : OSL_ENSURE( aGuid == XclTools::maGuidStdLink, "XclImpHyperlink::ReadEmbeddedData - unknown header GUID" );
251 : :
252 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
253 : 24 : ::std::auto_ptr< String > xLongName; // link / file name
254 : 24 : ::std::auto_ptr< String > xShortName; // 8.3-representation of file name
255 : 24 : ::std::auto_ptr< String > xTextMark; // text mark
256 : : SAL_WNODEPRECATED_DECLARATIONS_POP
257 : :
258 : : // description (ignore)
259 [ + + ]: 24 : if( ::get_flag( nFlags, EXC_HLINK_DESCR ) )
260 [ + - ]: 21 : lclIgnoreString32( rStrm, true );
261 : : // target frame (ignore) !! DESCR/FRAME - is this the right order? (never seen them together)
262 [ - + ]: 24 : if( ::get_flag( nFlags, EXC_HLINK_FRAME ) )
263 [ # # ]: 0 : lclIgnoreString32( rStrm, true );
264 : :
265 : : // URL fields are zero-terminated - do not let the stream replace them
266 : : // in the lclAppendString32() with the '?' character.
267 : 24 : rStrm.SetNulSubstChar( '\0' );
268 : :
269 : : // UNC path
270 [ - + ]: 24 : if( ::get_flag( nFlags, EXC_HLINK_UNC ) )
271 : : {
272 [ # # ][ # # ]: 0 : xLongName.reset( new String );
273 [ # # ]: 0 : lclAppendString32( *xLongName, rStrm, true );
274 [ # # ]: 0 : lclGetAbsPath( *xLongName, 0, pDocShell );
275 : : }
276 : : // file link or URL
277 [ + - ]: 24 : else if( ::get_flag( nFlags, EXC_HLINK_BODY ) )
278 : : {
279 [ + - ]: 24 : rStrm >> aGuid;
280 : :
281 [ + - ][ - + ]: 24 : if( aGuid == XclTools::maGuidFileMoniker )
282 : : {
283 : 0 : sal_uInt16 nLevel = 0; // counter for level to climb down in path
284 [ # # ]: 0 : rStrm >> nLevel;
285 [ # # ][ # # ]: 0 : xShortName.reset( new String );
286 [ # # ]: 0 : lclAppendString32( *xShortName, rStrm, false );
287 [ # # ]: 0 : rStrm.Ignore( 24 );
288 : :
289 : 0 : sal_uInt32 nStrLen = 0;
290 [ # # ]: 0 : rStrm >> nStrLen;
291 [ # # ]: 0 : if( nStrLen )
292 : : {
293 : 0 : nStrLen = 0;
294 [ # # ]: 0 : rStrm >> nStrLen;
295 : 0 : nStrLen /= 2; // it's byte count here...
296 [ # # ]: 0 : rStrm.Ignore( 2 );
297 [ # # ][ # # ]: 0 : xLongName.reset( new String );
298 [ # # ]: 0 : lclAppendString32( *xLongName, rStrm, nStrLen, true );
299 [ # # ]: 0 : lclGetAbsPath( *xLongName, nLevel, pDocShell );
300 : : }
301 : : else
302 [ # # ]: 0 : lclGetAbsPath( *xShortName, nLevel, pDocShell );
303 : : }
304 [ + - ][ + - ]: 24 : else if( aGuid == XclTools::maGuidUrlMoniker )
305 : : {
306 : 24 : sal_uInt32 nStrLen(0);
307 [ + - ]: 24 : rStrm >> nStrLen;
308 : 24 : nStrLen /= 2; // it's byte count here...
309 [ + - ][ + - ]: 24 : xLongName.reset( new String );
310 [ + - ]: 24 : lclAppendString32( *xLongName, rStrm, nStrLen, true );
311 [ - + ]: 24 : if( !::get_flag( nFlags, EXC_HLINK_ABS ) )
312 [ # # ]: 24 : lclGetAbsPath( *xLongName, 0, pDocShell );
313 : : }
314 : : else
315 : : {
316 : : OSL_FAIL( "XclImpHyperlink::ReadEmbeddedData - unknown content GUID" );
317 : : }
318 : : }
319 : :
320 : : // text mark
321 [ - + ]: 24 : if( ::get_flag( nFlags, EXC_HLINK_MARK ) )
322 : : {
323 [ # # ][ # # ]: 0 : xTextMark.reset( new String );
324 [ # # ]: 0 : lclAppendString32( *xTextMark, rStrm, true );
325 : : }
326 : :
327 : 24 : rStrm.SetNulSubstChar(); // back to default
328 : :
329 : : OSL_ENSURE( rStrm.GetRecLeft() == 0, "XclImpHyperlink::ReadEmbeddedData - record size mismatch" );
330 : :
331 [ # # ][ - + ]: 24 : if( !xLongName.get() && xShortName.get() )
[ - + ]
332 : 0 : xLongName = xShortName;
333 [ - + ][ # # ]: 24 : else if( !xLongName.get() && xTextMark.get() )
[ - + ]
334 [ # # ][ # # ]: 0 : xLongName.reset( new String );
335 : :
336 [ + - ]: 24 : if( xLongName.get() )
337 : : {
338 [ - + ]: 24 : if( xTextMark.get() )
339 : : {
340 [ # # ]: 0 : if( xLongName->Len() == 0 )
341 [ # # ]: 0 : xTextMark->SearchAndReplaceAll( '!', '.' );
342 [ # # ]: 0 : xLongName->Append( '#' );
343 [ # # ]: 0 : xLongName->Append( *xTextMark );
344 : : }
345 [ + - ]: 24 : return *xLongName;
346 : : }
347 [ # # ][ # # ]: 24 : return String::EmptyString();
[ + - ][ + - ]
[ + - ]
348 : : }
349 : :
350 : 24 : void XclImpHyperlink::ConvertToValidTabName(String& rUrl)
351 : : {
352 : 24 : xub_StrLen n = rUrl.Len();
353 [ + - ]: 24 : if (n < 4)
354 : : // Needs at least 4 characters.
355 : : return;
356 : :
357 : 24 : sal_Unicode c = rUrl.GetChar(0);
358 [ - + ]: 24 : if (c != sal_Unicode('#'))
359 : : // the 1st character must be '#'.
360 : : return;
361 : :
362 [ # # ][ # # ]: 0 : String aNewUrl(rtl::OUString('#')), aTabName;
363 : :
364 : 0 : bool bInQuote = false;
365 : 0 : bool bQuoteTabName = false;
366 [ # # ]: 0 : for (xub_StrLen i = 1; i < n; ++i)
367 : : {
368 : 0 : c = rUrl.GetChar(i);
369 [ # # ]: 0 : if (c == sal_Unicode('\''))
370 : : {
371 [ # # ][ # # ]: 0 : if (bInQuote && i+1 < n && rUrl.GetChar(i+1) == sal_Unicode('\''))
[ # # ][ # # ]
372 : : {
373 : : // Two consecutive single quotes ('') signify a single literal
374 : : // quite. When this occurs, the whole table name needs to be
375 : : // quoted.
376 : 0 : bQuoteTabName = true;
377 [ # # ]: 0 : aTabName.Append(c);
378 [ # # ]: 0 : aTabName.Append(c);
379 : 0 : ++i;
380 : 0 : continue;
381 : : }
382 : :
383 : 0 : bInQuote = !bInQuote;
384 [ # # ][ # # ]: 0 : if (!bInQuote && aTabName.Len() > 0)
[ # # ]
385 : : {
386 [ # # ]: 0 : if (bQuoteTabName)
387 [ # # ]: 0 : aNewUrl.Append(sal_Unicode('\''));
388 [ # # ]: 0 : aNewUrl.Append(aTabName);
389 [ # # ]: 0 : if (bQuoteTabName)
390 [ # # ]: 0 : aNewUrl.Append(sal_Unicode('\''));
391 : : }
392 : : }
393 [ # # ]: 0 : else if (bInQuote)
394 [ # # ]: 0 : aTabName.Append(c);
395 : : else
396 [ # # ]: 0 : aNewUrl.Append(c);
397 : : }
398 : :
399 [ # # ]: 0 : if (bInQuote)
400 : : // It should be outside the quotes!
401 : : return;
402 : :
403 : : // All is good. Pass the new URL.
404 [ # # ][ # # ]: 24 : rUrl = aNewUrl;
[ # # ][ # # ]
[ # # ]
405 : : }
406 : :
407 : 24 : void XclImpHyperlink::InsertUrl( const XclImpRoot& rRoot, const XclRange& rXclRange, const String& rUrl )
408 : : {
409 [ + - ]: 24 : String aUrl(rUrl);
410 [ + - ]: 24 : ConvertToValidTabName(aUrl);
411 : :
412 : 24 : SCTAB nScTab = rRoot.GetCurrScTab();
413 : 24 : ScRange aScRange( ScAddress::UNINITIALIZED );
414 [ + - ][ + - ]: 24 : if( rRoot.GetAddressConverter().ConvertRange( aScRange, rXclRange, nScTab, nScTab, true ) )
[ + - ]
415 : : {
416 : : SCCOL nScCol1, nScCol2;
417 : : SCROW nScRow1, nScRow2;
418 : 24 : aScRange.GetVars( nScCol1, nScRow1, nScTab, nScCol2, nScRow2, nScTab );
419 [ + + ]: 48 : for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol )
420 [ + + ]: 48 : for( SCROW nScRow = nScRow1; nScRow <= nScRow2; ++nScRow )
421 [ + - ]: 24 : lclInsertUrl( rRoot, aUrl, nScCol, nScRow, nScTab );
422 [ + - ]: 24 : }
423 : 24 : }
424 : :
425 : : // Label ranges ===============================================================
426 : :
427 : 0 : void XclImpLabelranges::ReadLabelranges( XclImpStream& rStrm )
428 : : {
429 : 0 : const XclImpRoot& rRoot = rStrm.GetRoot();
430 : : OSL_ENSURE_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
431 : :
432 : 0 : ScDocument& rDoc = rRoot.GetDoc();
433 : 0 : SCTAB nScTab = rRoot.GetCurrScTab();
434 [ # # ]: 0 : XclImpAddressConverter& rAddrConv = rRoot.GetAddressConverter();
435 : 0 : ScRangePairListRef xLabelRangesRef;
436 : 0 : const ScRange* pScRange = 0;
437 : :
438 [ # # ][ # # ]: 0 : XclRangeList aRowXclRanges, aColXclRanges;
439 [ # # ][ # # ]: 0 : rStrm >> aRowXclRanges >> aColXclRanges;
440 : :
441 : : // row label ranges
442 [ # # ]: 0 : ScRangeList aRowScRanges;
443 [ # # ]: 0 : rAddrConv.ConvertRangeList( aRowScRanges, aRowXclRanges, nScTab, false );
444 [ # # ]: 0 : xLabelRangesRef = rDoc.GetRowNameRangesRef();
445 [ # # ][ # # ]: 0 : for ( size_t i = 0, nRanges = aRowScRanges.size(); i < nRanges; ++i )
446 : : {
447 [ # # ]: 0 : pScRange = aRowScRanges[ i ];
448 : 0 : ScRange aDataRange( *pScRange );
449 [ # # ]: 0 : if( aDataRange.aEnd.Col() < MAXCOL )
450 : : {
451 : 0 : aDataRange.aStart.SetCol( aDataRange.aEnd.Col() + 1 );
452 : 0 : aDataRange.aEnd.SetCol( MAXCOL );
453 : : }
454 [ # # ]: 0 : else if( aDataRange.aStart.Col() > 0 )
455 : : {
456 : 0 : aDataRange.aEnd.SetCol( aDataRange.aStart.Col() - 1 );
457 : 0 : aDataRange.aStart.SetCol( 0 );
458 : : }
459 [ # # ]: 0 : xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
460 : : }
461 : :
462 : : // column label ranges
463 [ # # ]: 0 : ScRangeList aColScRanges;
464 [ # # ]: 0 : rAddrConv.ConvertRangeList( aColScRanges, aColXclRanges, nScTab, false );
465 [ # # ]: 0 : xLabelRangesRef = rDoc.GetColNameRangesRef();
466 : :
467 [ # # ][ # # ]: 0 : for ( size_t i = 0, nRanges = aColScRanges.size(); i < nRanges; ++i )
468 : : {
469 [ # # ]: 0 : pScRange = aColScRanges[ i ];
470 : 0 : ScRange aDataRange( *pScRange );
471 [ # # ]: 0 : if( aDataRange.aEnd.Row() < MAXROW )
472 : : {
473 : 0 : aDataRange.aStart.SetRow( aDataRange.aEnd.Row() + 1 );
474 : 0 : aDataRange.aEnd.SetRow( MAXROW );
475 : : }
476 [ # # ]: 0 : else if( aDataRange.aStart.Row() > 0 )
477 : : {
478 : 0 : aDataRange.aEnd.SetRow( aDataRange.aStart.Row() - 1 );
479 : 0 : aDataRange.aStart.SetRow( 0 );
480 : : }
481 [ # # ]: 0 : xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
482 [ # # ][ # # ]: 0 : }
[ # # ]
483 : 0 : }
484 : :
485 : : // Conditional formatting =====================================================
486 : :
487 : 0 : XclImpCondFormat::XclImpCondFormat( const XclImpRoot& rRoot, sal_uInt32 nFormatIndex ) :
488 : : XclImpRoot( rRoot ),
489 : : mnFormatIndex( nFormatIndex ),
490 : : mnCondCount( 0 ),
491 [ # # ]: 0 : mnCondIndex( 0 )
492 : : {
493 : 0 : }
494 : :
495 [ # # ][ # # ]: 0 : XclImpCondFormat::~XclImpCondFormat()
496 : : {
497 [ # # ]: 0 : }
498 : :
499 : 0 : void XclImpCondFormat::ReadCondfmt( XclImpStream& rStrm )
500 : : {
501 : : OSL_ENSURE( !mnCondCount, "XclImpCondFormat::ReadCondfmt - already initialized" );
502 [ # # ]: 0 : XclRangeList aXclRanges;
503 [ # # ]: 0 : rStrm >> mnCondCount;
504 [ # # ]: 0 : rStrm.Ignore( 10 );
505 [ # # ]: 0 : rStrm >> aXclRanges;
506 [ # # ][ # # ]: 0 : GetAddressConverter().ConvertRangeList( maRanges, aXclRanges, GetCurrScTab(), true );
507 : 0 : }
508 : :
509 : 0 : void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
510 : : {
511 [ # # ]: 0 : if( mnCondIndex >= mnCondCount )
512 : : {
513 : : OSL_FAIL( "XclImpCondFormat::ReadCF - CF without leading CONDFMT" );
514 : : return;
515 : : }
516 : :
517 : : // entire conditional format outside of valid range?
518 [ # # ][ # # ]: 0 : if( maRanges.empty() )
519 : : return;
520 : :
521 : 0 : sal_uInt8 nType(0), nOperator(0);
522 : 0 : sal_uInt16 nFmlaSize1(0), nFmlaSize2(0);
523 : 0 : sal_uInt32 nFlags(0);
524 : :
525 [ # # ][ # # ]: 0 : rStrm >> nType >> nOperator >> nFmlaSize1 >> nFmlaSize2 >> nFlags;
[ # # ][ # # ]
[ # # ]
526 [ # # ]: 0 : rStrm.Ignore( 2 );
527 : :
528 : : // *** mode and comparison operator ***
529 : :
530 : 0 : ScConditionMode eMode = SC_COND_NONE;
531 [ # # # ]: 0 : switch( nType )
532 : : {
533 : : case EXC_CF_TYPE_CELL:
534 : : {
535 [ # # # # : 0 : switch( nOperator )
# # # #
# ]
536 : : {
537 : 0 : case EXC_CF_CMP_BETWEEN: eMode = SC_COND_BETWEEN; break;
538 : 0 : case EXC_CF_CMP_NOT_BETWEEN: eMode = SC_COND_NOTBETWEEN; break;
539 : 0 : case EXC_CF_CMP_EQUAL: eMode = SC_COND_EQUAL; break;
540 : 0 : case EXC_CF_CMP_NOT_EQUAL: eMode = SC_COND_NOTEQUAL; break;
541 : 0 : case EXC_CF_CMP_GREATER: eMode = SC_COND_GREATER; break;
542 : 0 : case EXC_CF_CMP_LESS: eMode = SC_COND_LESS; break;
543 : 0 : case EXC_CF_CMP_GREATER_EQUAL: eMode = SC_COND_EQGREATER; break;
544 : 0 : case EXC_CF_CMP_LESS_EQUAL: eMode = SC_COND_EQLESS; break;
545 : : default:
546 : : OSL_TRACE( "XclImpCondFormat::ReadCF - unknown CF comparison 0x%02hX", nOperator );
547 : : }
548 : : }
549 : 0 : break;
550 : :
551 : : case EXC_CF_TYPE_FMLA:
552 : 0 : eMode = SC_COND_DIRECT;
553 : 0 : break;
554 : :
555 : : default:
556 : : OSL_TRACE( "XclImpCondFormat::ReadCF - unknown CF mode 0x%02hX", nType );
557 : : return;
558 : : }
559 : :
560 : : // *** create style sheet ***
561 : :
562 [ # # ][ # # ]: 0 : String aStyleName( XclTools::GetCondFormatStyleName( GetCurrScTab(), mnFormatIndex, mnCondIndex ) );
563 [ # # ][ # # ]: 0 : SfxItemSet& rStyleItemSet = ScfTools::MakeCellStyleSheet( GetStyleSheetPool(), aStyleName, true ).GetItemSet();
[ # # ]
564 : :
565 [ # # ]: 0 : const XclImpPalette& rPalette = GetPalette();
566 : :
567 : : // *** font block ***
568 : :
569 [ # # ]: 0 : if( ::get_flag( nFlags, EXC_CF_BLOCK_FONT ) )
570 : : {
571 [ # # ]: 0 : XclImpFont aFont( GetRoot() );
572 [ # # ]: 0 : aFont.ReadCFFontBlock( rStrm );
573 [ # # ][ # # ]: 0 : aFont.FillToItemSet( rStyleItemSet, EXC_FONTITEM_CELL );
574 : : }
575 : :
576 : : // *** border block ***
577 : :
578 [ # # ]: 0 : if( ::get_flag( nFlags, EXC_CF_BLOCK_BORDER ) )
579 : : {
580 : 0 : sal_uInt16 nLineStyle(0);
581 : 0 : sal_uInt32 nLineColor(0);
582 [ # # ][ # # ]: 0 : rStrm >> nLineStyle >> nLineColor;
583 [ # # ]: 0 : rStrm.Ignore( 2 );
584 : :
585 [ # # ]: 0 : XclImpCellBorder aBorder;
586 [ # # ]: 0 : aBorder.FillFromCF8( nLineStyle, nLineColor, nFlags );
587 [ # # ]: 0 : aBorder.FillToItemSet( rStyleItemSet, rPalette );
588 : : }
589 : :
590 : : // *** pattern block ***
591 : :
592 [ # # ]: 0 : if( ::get_flag( nFlags, EXC_CF_BLOCK_AREA ) )
593 : : {
594 : 0 : sal_uInt16 nPattern(0), nColor(0);
595 [ # # ][ # # ]: 0 : rStrm >> nPattern >> nColor;
596 : :
597 [ # # ]: 0 : XclImpCellArea aArea;
598 [ # # ]: 0 : aArea.FillFromCF8( nPattern, nColor, nFlags );
599 [ # # ]: 0 : aArea.FillToItemSet( rStyleItemSet, rPalette );
600 : : }
601 : :
602 : : // *** formulas ***
603 : :
604 [ # # ]: 0 : const ScAddress& rPos = maRanges.front()->aStart; // assured above that maRanges is not empty
605 [ # # ]: 0 : ExcelToSc& rFmlaConv = GetOldFmlaConverter();
606 : :
607 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
608 : 0 : ::std::auto_ptr< ScTokenArray > xTokArr1;
609 : : SAL_WNODEPRECATED_DECLARATIONS_POP
610 [ # # ]: 0 : if( nFmlaSize1 > 0 )
611 : : {
612 : 0 : const ScTokenArray* pTokArr = 0;
613 [ # # ]: 0 : rFmlaConv.Reset( rPos );
614 [ # # ]: 0 : rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_RangeName );
615 : : // formula converter owns pTokArr -> create a copy of the token array
616 [ # # ]: 0 : if( pTokArr )
617 [ # # ]: 0 : xTokArr1.reset( pTokArr->Clone() );
618 : : }
619 : :
620 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
621 : 0 : ::std::auto_ptr< ScTokenArray > pTokArr2;
622 : : SAL_WNODEPRECATED_DECLARATIONS_POP
623 [ # # ]: 0 : if( nFmlaSize2 > 0 )
624 : : {
625 : 0 : const ScTokenArray* pTokArr = 0;
626 [ # # ]: 0 : rFmlaConv.Reset( rPos );
627 [ # # ]: 0 : rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_RangeName );
628 : : // formula converter owns pTokArr -> create a copy of the token array
629 [ # # ]: 0 : if( pTokArr )
630 [ # # ]: 0 : pTokArr2.reset( pTokArr->Clone() );
631 : : }
632 : :
633 : : // *** create the Calc conditional formatting ***
634 : :
635 [ # # ]: 0 : if( !mxScCondFmt.get() )
636 : : {
637 : 0 : sal_uLong nKey = 0;
638 [ # # ][ # # ]: 0 : mxScCondFmt.reset( new ScConditionalFormat( nKey, GetDocPtr() ) );
639 : : }
640 : :
641 [ # # ][ # # ]: 0 : ScCondFormatEntry* pEntry = new ScCondFormatEntry( eMode, xTokArr1.get(), pTokArr2.get(), GetDocPtr(), rPos, aStyleName );
642 [ # # ]: 0 : mxScCondFmt->AddEntry( pEntry );
643 [ # # ][ # # ]: 0 : ++mnCondIndex;
[ # # ]
644 : : }
645 : :
646 : 0 : void XclImpCondFormat::Apply()
647 : : {
648 [ # # ]: 0 : if( mxScCondFmt.get() )
649 : : {
650 : 0 : ScDocument& rDoc = GetDoc();
651 : :
652 [ # # ][ # # ]: 0 : sal_uLong nKey = rDoc.AddCondFormat( mxScCondFmt->Clone(), maRanges.front()->aStart.Tab() );
[ # # ]
653 [ # # ][ # # ]: 0 : ScPatternAttr aPattern( rDoc.GetPool() );
654 [ # # ][ # # ]: 0 : aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_CONDITIONAL, nKey ) );
[ # # ]
655 : :
656 : : // maRanges contains only valid cell ranges
657 [ # # ][ # # ]: 0 : for ( size_t i = 0, nRanges = maRanges.size(); i < nRanges; ++i )
658 : : {
659 [ # # ]: 0 : const ScRange* pScRange = maRanges[ i ];
660 : : rDoc.ApplyPatternAreaTab(
661 : 0 : pScRange->aStart.Col(), pScRange->aStart.Row(),
662 : 0 : pScRange->aEnd.Col(), pScRange->aEnd.Row(),
663 [ # # ]: 0 : pScRange->aStart.Tab(), aPattern );
664 [ # # ]: 0 : }
665 : : }
666 : 0 : }
667 : :
668 : : // ----------------------------------------------------------------------------
669 : :
670 : 55 : XclImpCondFormatManager::XclImpCondFormatManager( const XclImpRoot& rRoot ) :
671 [ + - ]: 55 : XclImpRoot( rRoot )
672 : : {
673 : 55 : }
674 : :
675 : 0 : void XclImpCondFormatManager::ReadCondfmt( XclImpStream& rStrm )
676 : : {
677 [ # # ]: 0 : XclImpCondFormat* pFmt = new XclImpCondFormat( GetRoot(), maCondFmtList.size() );
678 : 0 : pFmt->ReadCondfmt( rStrm );
679 : 0 : maCondFmtList.push_back( pFmt );
680 : 0 : }
681 : :
682 : 0 : void XclImpCondFormatManager::ReadCF( XclImpStream& rStrm )
683 : : {
684 : : OSL_ENSURE( !maCondFmtList.empty(), "XclImpCondFormatManager::ReadCF - CF without leading CONDFMT" );
685 [ # # ]: 0 : if( !maCondFmtList.empty() )
686 : 0 : maCondFmtList.back().ReadCF( rStrm );
687 : 0 : }
688 : :
689 : 165 : void XclImpCondFormatManager::Apply()
690 : : {
691 [ + - ][ # # ]: 165 : for( XclImpCondFmtList::iterator itFmt = maCondFmtList.begin(); itFmt != maCondFmtList.end(); ++itFmt )
[ + - ][ + - ]
[ - + ]
692 [ # # ][ # # ]: 0 : itFmt->Apply();
693 : 165 : maCondFmtList.clear();
694 : 165 : }
695 : :
696 : : // Data Validation ============================================================
697 : :
698 : 3 : XclImpValidationManager::DVItem::DVItem( const ScRangeList& rRanges, const ScValidationData& rValidData ) :
699 [ + - ]: 3 : maRanges(rRanges), maValidData(rValidData) {}
700 : :
701 : 55 : XclImpValidationManager::XclImpValidationManager( const XclImpRoot& rRoot ) :
702 [ + - ]: 55 : XclImpRoot( rRoot )
703 : : {
704 : 55 : }
705 : :
706 : 6 : void XclImpValidationManager::ReadDval( XclImpStream& rStrm )
707 : : {
708 : 6 : const XclImpRoot& rRoot = rStrm.GetRoot();
709 : : OSL_ENSURE_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
710 : :
711 : 6 : sal_uInt32 nObjId(0);
712 [ + - ]: 6 : rStrm.Ignore( 10 );
713 [ + - ]: 6 : rStrm >> nObjId;
714 [ + + ]: 6 : if( nObjId != EXC_DVAL_NOOBJ )
715 : : {
716 : : OSL_ENSURE( nObjId <= 0xFFFF, "XclImpValidation::ReadDval - invalid object ID" );
717 [ + - ][ + - ]: 3 : rRoot.GetCurrSheetDrawing().SetSkipObj( static_cast< sal_uInt16 >( nObjId ) );
718 : : }
719 : 6 : }
720 : :
721 : 3 : void XclImpValidationManager::ReadDV( XclImpStream& rStrm )
722 : : {
723 : 3 : const XclImpRoot& rRoot = rStrm.GetRoot();
724 : : OSL_ENSURE_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
725 : :
726 : 3 : ScDocument& rDoc = rRoot.GetDoc();
727 : 3 : SCTAB nScTab = rRoot.GetCurrScTab();
728 [ + - ]: 3 : ExcelToSc& rFmlaConv = rRoot.GetOldFmlaConverter();
729 : :
730 : : // flags
731 : 3 : sal_uInt32 nFlags(0);
732 [ + - ]: 3 : rStrm >> nFlags;
733 : :
734 : : // message strings
735 : : /* Empty strings are single NUL characters in Excel (string length is 1).
736 : : -> Do not let the stream replace them with '?' characters. */
737 : 3 : rStrm.SetNulSubstChar( '\0' );
738 [ + - ]: 3 : String aPromptTitle( rStrm.ReadUniString() );
739 [ + - ]: 3 : String aErrorTitle( rStrm.ReadUniString() );
740 [ + - ]: 3 : String aPromptMessage( rStrm.ReadUniString() );
741 [ + - ]: 3 : String aErrorMessage( rStrm.ReadUniString() );
742 : 3 : rStrm.SetNulSubstChar(); // back to default
743 : :
744 : : // formula(s)
745 [ - + ][ + - ]: 3 : if ( rStrm.GetRecLeft() <= 8 )
746 : : // Not enough bytes left in the record. Bail out.
747 : : return;
748 : :
749 : :
750 : : // first formula
751 : : // string list is single tStr token with NUL separators -> replace them with LF
752 : 3 : rStrm.SetNulSubstChar( '\n' );
753 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
754 : 3 : ::std::auto_ptr< ScTokenArray > xTokArr1;
755 : : SAL_WNODEPRECATED_DECLARATIONS_POP
756 : :
757 : 3 : sal_uInt16 nLen = 0;
758 [ + - ]: 3 : rStrm >> nLen;
759 [ + - ]: 3 : rStrm.Ignore( 2 );
760 [ + - ]: 3 : if( nLen > 0 )
761 : : {
762 : 3 : const ScTokenArray* pTokArr = 0;
763 [ + - ]: 3 : rFmlaConv.Reset();
764 [ + - ]: 3 : rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
765 : : // formula converter owns pTokArr -> create a copy of the token array
766 [ + - ]: 3 : if( pTokArr )
767 [ + - ]: 3 : xTokArr1.reset( pTokArr->Clone() );
768 : : }
769 : 3 : rStrm.SetNulSubstChar(); // back to default
770 : :
771 : : // second formula
772 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
773 : 3 : ::std::auto_ptr< ScTokenArray > xTokArr2;
774 : : SAL_WNODEPRECATED_DECLARATIONS_POP
775 : :
776 : 3 : nLen = 0;
777 [ + - ]: 3 : rStrm >> nLen;
778 [ + - ]: 3 : rStrm.Ignore( 2 );
779 [ - + ]: 3 : if( nLen > 0 )
780 : : {
781 : 0 : const ScTokenArray* pTokArr = 0;
782 [ # # ]: 0 : rFmlaConv.Reset();
783 [ # # ]: 0 : rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
784 : : // formula converter owns pTokArr -> create a copy of the token array
785 [ # # ]: 0 : if( pTokArr )
786 [ # # ]: 0 : xTokArr2.reset( pTokArr->Clone() );
787 : : }
788 : :
789 : : // read all cell ranges
790 [ + - ]: 3 : XclRangeList aXclRanges;
791 [ + - ]: 3 : rStrm >> aXclRanges;
792 : :
793 : : // convert to Calc range list
794 [ + - ]: 3 : ScRangeList aScRanges;
795 [ + - ][ + - ]: 3 : rRoot.GetAddressConverter().ConvertRangeList( aScRanges, aXclRanges, nScTab, true );
796 : :
797 : : // only continue if there are valid ranges
798 [ + - ][ - + ]: 3 : if ( aScRanges.empty() )
799 : : return;
800 : :
801 : 3 : bool bIsValid = true; // valid settings in flags field
802 : :
803 : 3 : ScValidationMode eValMode = SC_VALID_ANY;
804 [ - - - + : 3 : switch( nFlags & EXC_DV_MODE_MASK )
- - - -
- ]
805 : : {
806 : 0 : case EXC_DV_MODE_ANY: eValMode = SC_VALID_ANY; break;
807 : 0 : case EXC_DV_MODE_WHOLE: eValMode = SC_VALID_WHOLE; break;
808 : 0 : case EXC_DV_MODE_DECIMAL: eValMode = SC_VALID_DECIMAL; break;
809 : 3 : case EXC_DV_MODE_LIST: eValMode = SC_VALID_LIST; break;
810 : 0 : case EXC_DV_MODE_DATE: eValMode = SC_VALID_DATE; break;
811 : 0 : case EXC_DV_MODE_TIME: eValMode = SC_VALID_TIME; break;
812 : 0 : case EXC_DV_MODE_TEXTLEN: eValMode = SC_VALID_TEXTLEN; break;
813 : 0 : case EXC_DV_MODE_CUSTOM: eValMode = SC_VALID_CUSTOM; break;
814 : 0 : default: bIsValid = false;
815 : : }
816 [ + - ][ + - ]: 3 : rRoot.GetTracer().TraceDVType(eValMode == SC_VALID_CUSTOM);
817 : :
818 : 3 : ScConditionMode eCondMode = SC_COND_BETWEEN;
819 [ + - - - : 3 : switch( nFlags & EXC_DV_COND_MASK )
- - - -
- ]
820 : : {
821 : 3 : case EXC_DV_COND_BETWEEN: eCondMode = SC_COND_BETWEEN; break;
822 : 0 : case EXC_DV_COND_NOTBETWEEN:eCondMode = SC_COND_NOTBETWEEN; break;
823 : 0 : case EXC_DV_COND_EQUAL: eCondMode = SC_COND_EQUAL; break;
824 : 0 : case EXC_DV_COND_NOTEQUAL: eCondMode = SC_COND_NOTEQUAL; break;
825 : 0 : case EXC_DV_COND_GREATER: eCondMode = SC_COND_GREATER; break;
826 : 0 : case EXC_DV_COND_LESS: eCondMode = SC_COND_LESS; break;
827 : 0 : case EXC_DV_COND_EQGREATER: eCondMode = SC_COND_EQGREATER; break;
828 : 0 : case EXC_DV_COND_EQLESS: eCondMode = SC_COND_EQLESS; break;
829 : 0 : default: bIsValid = false;
830 : : }
831 : :
832 [ - + ]: 3 : if ( !bIsValid )
833 : : // No valid validation found. Bail out.
834 : : return;
835 : :
836 : :
837 : : // first range for base address for relative references
838 [ + - ]: 3 : const ScRange& rScRange = *aScRanges.front(); // aScRanges is not empty
839 : :
840 : : // process string list of a list validity (convert to list of string tokens)
841 [ + - ][ + - ]: 3 : if( xTokArr1.get() && (eValMode == SC_VALID_LIST) && ::get_flag( nFlags, EXC_DV_STRINGLIST ) )
[ - + ][ - + ]
842 [ # # ]: 0 : XclTokenArrayHelper::ConvertStringToList( *xTokArr1, '\n', true );
843 : :
844 : : maDVItems.push_back(
845 [ + - ][ + - ]: 3 : new DVItem(aScRanges, ScValidationData(eValMode, eCondMode, xTokArr1.get(), xTokArr2.get(), &rDoc, rScRange.aStart)));
[ + - ][ + - ]
[ + - ]
846 [ + - ]: 3 : DVItem& rItem = maDVItems.back();
847 : :
848 [ + - ]: 3 : rItem.maValidData.SetIgnoreBlank( ::get_flag( nFlags, EXC_DV_IGNOREBLANK ) );
849 : 3 : rItem.maValidData.SetListType( ::get_flagvalue( nFlags, EXC_DV_SUPPRESSDROPDOWN, ValidListType::INVISIBLE, ValidListType::UNSORTED ) );
850 : :
851 : : // *** prompt box ***
852 [ - + ][ - + ]: 3 : if( aPromptTitle.Len() || aPromptMessage.Len() )
[ + - ]
853 : : {
854 : : // set any text stored in the record
855 [ # # ]: 0 : rItem.maValidData.SetInput( aPromptTitle, aPromptMessage );
856 [ # # ]: 0 : if( !::get_flag( nFlags, EXC_DV_SHOWPROMPT ) )
857 [ # # ]: 0 : rItem.maValidData.ResetInput();
858 : : }
859 : :
860 : : // *** error box ***
861 : 3 : ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
862 [ - - + ]: 3 : switch( nFlags & EXC_DV_ERROR_MASK )
863 : : {
864 : 0 : case EXC_DV_ERROR_WARNING: eErrStyle = SC_VALERR_WARNING; break;
865 : 0 : case EXC_DV_ERROR_INFO: eErrStyle = SC_VALERR_INFO; break;
866 : : }
867 : : // set texts and error style
868 [ + - ]: 3 : rItem.maValidData.SetError( aErrorTitle, aErrorMessage, eErrStyle );
869 [ - + ]: 3 : if( !::get_flag( nFlags, EXC_DV_SHOWERROR ) )
870 [ # # ][ + - ]: 3 : rItem.maValidData.ResetError();
[ - + ][ - + ]
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ][ + - ]
871 : : }
872 : :
873 : 165 : void XclImpValidationManager::Apply()
874 : : {
875 : 165 : ScDocument& rDoc = GetRoot().GetDoc();
876 [ + - ][ + - ]: 165 : DVItemList::iterator itr = maDVItems.begin(), itrEnd = maDVItems.end();
877 [ + - ][ + - ]: 168 : for (; itr != itrEnd; ++itr)
[ + + ]
878 : : {
879 [ + - ]: 3 : DVItem& rItem = *itr;
880 : : // set the handle ID
881 [ + - ]: 3 : sal_uLong nHandle = rDoc.AddValidationEntry( rItem.maValidData );
882 [ + - ][ + - ]: 3 : ScPatternAttr aPattern( rDoc.GetPool() );
883 [ + - ][ + - ]: 3 : aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nHandle ) );
[ + - ]
884 : :
885 : : // apply all ranges
886 [ + - ][ + + ]: 6 : for ( size_t i = 0, nRanges = rItem.maRanges.size(); i < nRanges; ++i )
887 : : {
888 [ + - ]: 3 : const ScRange* pScRange = rItem.maRanges[ i ];
889 : 3 : rDoc.ApplyPatternAreaTab( pScRange->aStart.Col(), pScRange->aStart.Row(),
890 [ + - ]: 6 : pScRange->aEnd.Col(), pScRange->aEnd.Row(), pScRange->aStart.Tab(), aPattern );
891 : : }
892 [ + - ]: 3 : }
893 [ + - ]: 165 : maDVItems.clear();
894 : 165 : }
895 : :
896 : : // Web queries ================================================================
897 : :
898 : 0 : XclImpWebQuery::XclImpWebQuery( const ScRange& rDestRange ) :
899 : : maDestRange( rDestRange ),
900 : : meMode( xlWQUnknown ),
901 [ # # ][ # # ]: 0 : mnRefresh( 0 )
902 : : {
903 : 0 : }
904 : :
905 : 0 : void XclImpWebQuery::ReadParamqry( XclImpStream& rStrm )
906 : : {
907 : 0 : sal_uInt16 nFlags = rStrm.ReaduInt16();
908 : 0 : sal_uInt16 nType = ::extract_value< sal_uInt16 >( nFlags, 0, 3 );
909 [ # # ][ # # ]: 0 : if( (nType == EXC_PQRYTYPE_WEBQUERY) && ::get_flag( nFlags, EXC_PQRY_WEBQUERY ) )
[ # # ]
910 : : {
911 [ # # ]: 0 : if( ::get_flag( nFlags, EXC_PQRY_TABLES ) )
912 : : {
913 : 0 : meMode = xlWQAllTables;
914 : 0 : maTables = ScfTools::GetHTMLTablesName();
915 : : }
916 : : else
917 : : {
918 : 0 : meMode = xlWQDocument;
919 : 0 : maTables = ScfTools::GetHTMLDocName();
920 : : }
921 : : }
922 : 0 : }
923 : :
924 : 0 : void XclImpWebQuery::ReadWqstring( XclImpStream& rStrm )
925 : : {
926 [ # # ]: 0 : maURL = rStrm.ReadUniString();
927 : 0 : }
928 : :
929 : 0 : void XclImpWebQuery::ReadWqsettings( XclImpStream& rStrm )
930 : : {
931 [ # # ]: 0 : rStrm.Ignore( 10 );
932 : 0 : sal_uInt16 nFlags(0);
933 [ # # ]: 0 : rStrm >> nFlags;
934 [ # # ]: 0 : rStrm.Ignore( 10 );
935 [ # # ]: 0 : rStrm >> mnRefresh;
936 : :
937 [ # # ][ # # ]: 0 : if( ::get_flag( nFlags, EXC_WQSETT_SPECTABLES ) && (meMode == xlWQAllTables) )
[ # # ]
938 : 0 : meMode = xlWQSpecTables;
939 : 0 : }
940 : :
941 : 0 : void XclImpWebQuery::ReadWqtables( XclImpStream& rStrm )
942 : : {
943 [ # # ]: 0 : if( meMode == xlWQSpecTables )
944 : : {
945 [ # # ]: 0 : rStrm.Ignore( 4 );
946 [ # # ]: 0 : String aTables( rStrm.ReadUniString() );
947 : :
948 : 0 : const sal_Unicode cSep = ';';
949 [ # # ]: 0 : String aQuotedPairs( RTL_CONSTASCII_USTRINGPARAM( "\"\"" ) );
950 [ # # ]: 0 : xub_StrLen nTokenCnt = ScStringUtil::GetQuotedTokenCount( aTables, aQuotedPairs, ',' );
951 [ # # ]: 0 : maTables.Erase();
952 : 0 : xub_StrLen nStringIx = 0;
953 [ # # ]: 0 : for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
954 : : {
955 [ # # ]: 0 : String aToken( ScStringUtil::GetQuotedToken( aTables, 0, aQuotedPairs, ',', nStringIx ) );
956 [ # # ][ # # ]: 0 : sal_Int32 nTabNum = CharClass::isAsciiNumeric( aToken ) ? aToken.ToInt32() : 0;
[ # # ]
957 [ # # ]: 0 : if( nTabNum > 0 )
958 [ # # ][ # # ]: 0 : ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLIndex( static_cast< sal_uInt32 >( nTabNum ) ), cSep );
[ # # ]
959 : : else
960 : : {
961 [ # # ]: 0 : ScGlobal::EraseQuotes( aToken, '"', false );
962 [ # # ]: 0 : if( aToken.Len() )
963 [ # # ][ # # ]: 0 : ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLName( aToken ), cSep );
[ # # ]
964 : : }
965 [ # # ][ # # ]: 0 : }
[ # # ]
966 : : }
967 : 0 : }
968 : :
969 : 0 : void XclImpWebQuery::Apply( ScDocument& rDoc, const String& rFilterName )
970 : : {
971 [ # # ][ # # ]: 0 : if( maURL.Len() && (meMode != xlWQUnknown) && rDoc.GetDocumentShell() )
[ # # ][ # # ]
972 : : {
973 : : ScAreaLink* pLink = new ScAreaLink( rDoc.GetDocumentShell(),
974 [ # # ]: 0 : maURL, rFilterName, EMPTY_STRING, maTables, maDestRange, mnRefresh * 60UL );
975 : : rDoc.GetLinkManager()->InsertFileLink( *pLink, OBJECT_CLIENT_FILE,
976 : 0 : maURL, &rFilterName, &maTables );
977 : : }
978 : 0 : }
979 : :
980 : : // ----------------------------------------------------------------------------
981 : :
982 : 55 : XclImpWebQueryBuffer::XclImpWebQueryBuffer( const XclImpRoot& rRoot ) :
983 [ + - ]: 55 : XclImpRoot( rRoot )
984 : : {
985 : 55 : }
986 : :
987 : 0 : void XclImpWebQueryBuffer::ReadQsi( XclImpStream& rStrm )
988 : : {
989 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
990 : : {
991 [ # # ]: 0 : rStrm.Ignore( 10 );
992 [ # # ]: 0 : String aXclName( rStrm.ReadUniString() );
993 : :
994 : : // #i64794# Excel replaces spaces with underscores
995 [ # # ]: 0 : aXclName.SearchAndReplaceAll( ' ', '_' );
996 : :
997 : : // find the defined name used in Calc
998 [ # # ][ # # ]: 0 : if( const XclImpName* pName = GetNameManager().FindName( aXclName, GetCurrScTab() ) )
[ # # ]
999 : : {
1000 [ # # ]: 0 : if( const ScRangeData* pRangeData = pName->GetScRangeData() )
1001 : : {
1002 : 0 : ScRange aRange;
1003 [ # # ][ # # ]: 0 : if( pRangeData->IsReference( aRange ) )
1004 [ # # ][ # # ]: 0 : maWQList.push_back( new XclImpWebQuery( aRange ) );
[ # # ]
1005 : : }
1006 [ # # ]: 0 : }
1007 : : }
1008 : : else
1009 : : {
1010 : : DBG_ERROR_BIFF();
1011 : : }
1012 : 0 : }
1013 : :
1014 : 0 : void XclImpWebQueryBuffer::ReadParamqry( XclImpStream& rStrm )
1015 : : {
1016 [ # # ]: 0 : if (!maWQList.empty())
1017 : 0 : maWQList.back().ReadParamqry( rStrm );
1018 : 0 : }
1019 : :
1020 : 0 : void XclImpWebQueryBuffer::ReadWqstring( XclImpStream& rStrm )
1021 : : {
1022 [ # # ]: 0 : if (!maWQList.empty())
1023 : 0 : maWQList.back().ReadWqstring( rStrm );
1024 : 0 : }
1025 : :
1026 : 0 : void XclImpWebQueryBuffer::ReadWqsettings( XclImpStream& rStrm )
1027 : : {
1028 [ # # ]: 0 : if (!maWQList.empty())
1029 : 0 : maWQList.back().ReadWqsettings( rStrm );
1030 : 0 : }
1031 : :
1032 : 0 : void XclImpWebQueryBuffer::ReadWqtables( XclImpStream& rStrm )
1033 : : {
1034 [ # # ]: 0 : if (!maWQList.empty())
1035 : 0 : maWQList.back().ReadWqtables( rStrm );
1036 : 0 : }
1037 : :
1038 : 55 : void XclImpWebQueryBuffer::Apply()
1039 : : {
1040 : 55 : ScDocument& rDoc = GetDoc();
1041 [ + - ]: 55 : String aFilterName( RTL_CONSTASCII_USTRINGPARAM( EXC_WEBQRY_FILTER ) );
1042 [ + - ][ # # ]: 55 : for( XclImpWebQueryList::iterator itQuery = maWQList.begin(); itQuery != maWQList.end(); ++itQuery )
[ + - ][ + - ]
[ - + ]
1043 [ # # ][ # # ]: 55 : itQuery->Apply( rDoc, aFilterName );
[ + - ]
1044 : 55 : }
1045 : :
1046 : : // Decryption =================================================================
1047 : :
1048 : : namespace {
1049 : :
1050 : 0 : XclImpDecrypterRef lclReadFilepass5( XclImpStream& rStrm )
1051 : : {
1052 : 0 : XclImpDecrypterRef xDecr;
1053 : : OSL_ENSURE( rStrm.GetRecLeft() == 4, "lclReadFilepass5 - wrong record size" );
1054 [ # # ][ # # ]: 0 : if( rStrm.GetRecLeft() == 4 )
1055 : : {
1056 : 0 : sal_uInt16 nKey(0), nHash(0);
1057 [ # # ][ # # ]: 0 : rStrm >> nKey >> nHash;
1058 [ # # ][ # # ]: 0 : xDecr.reset( new XclImpBiff5Decrypter( nKey, nHash ) );
[ # # ]
1059 : : }
1060 : 0 : return xDecr;
1061 : : }
1062 : :
1063 : 0 : XclImpDecrypterRef lclReadFilepass8_Standard( XclImpStream& rStrm )
1064 : : {
1065 : 0 : XclImpDecrypterRef xDecr;
1066 : : OSL_ENSURE( rStrm.GetRecLeft() == 48, "lclReadFilepass8 - wrong record size" );
1067 [ # # ][ # # ]: 0 : if( rStrm.GetRecLeft() == 48 )
1068 : : {
1069 : : sal_uInt8 pnSalt[ 16 ];
1070 : : sal_uInt8 pnVerifier[ 16 ];
1071 : : sal_uInt8 pnVerifierHash[ 16 ];
1072 [ # # ]: 0 : rStrm.Read( pnSalt, 16 );
1073 [ # # ]: 0 : rStrm.Read( pnVerifier, 16 );
1074 [ # # ]: 0 : rStrm.Read( pnVerifierHash, 16 );
1075 [ # # ][ # # ]: 0 : xDecr.reset( new XclImpBiff8Decrypter( pnSalt, pnVerifier, pnVerifierHash ) );
[ # # ]
1076 : : }
1077 : 0 : return xDecr;
1078 : : }
1079 : :
1080 : 0 : XclImpDecrypterRef lclReadFilepass8_Strong( XclImpStream& /*rStrm*/ )
1081 : : {
1082 : : // not supported
1083 : 0 : return XclImpDecrypterRef();
1084 : : }
1085 : :
1086 : 0 : XclImpDecrypterRef lclReadFilepass8( XclImpStream& rStrm )
1087 : : {
1088 [ # # ]: 0 : XclImpDecrypterRef xDecr;
1089 : :
1090 : 0 : sal_uInt16 nMode(0);
1091 [ # # ]: 0 : rStrm >> nMode;
1092 [ # # # ]: 0 : switch( nMode )
1093 : : {
1094 : : case EXC_FILEPASS_BIFF5:
1095 [ # # ][ # # ]: 0 : xDecr = lclReadFilepass5( rStrm );
[ # # ]
1096 : 0 : break;
1097 : :
1098 : : case EXC_FILEPASS_BIFF8:
1099 : : {
1100 [ # # ]: 0 : rStrm.Ignore( 2 );
1101 : 0 : sal_uInt16 nSubMode(0);
1102 [ # # ]: 0 : rStrm >> nSubMode;
1103 [ # # # ]: 0 : switch( nSubMode )
1104 : : {
1105 : : case EXC_FILEPASS_BIFF8_STD:
1106 [ # # ][ # # ]: 0 : xDecr = lclReadFilepass8_Standard( rStrm );
[ # # ]
1107 : 0 : break;
1108 : : case EXC_FILEPASS_BIFF8_STRONG:
1109 [ # # ][ # # ]: 0 : xDecr = lclReadFilepass8_Strong( rStrm );
[ # # ]
1110 : 0 : break;
1111 : : default:
1112 : : OSL_FAIL( "lclReadFilepass8 - unknown BIFF8 encryption sub mode" );
1113 : : }
1114 : : }
1115 : 0 : break;
1116 : :
1117 : : default:
1118 : : OSL_FAIL( "lclReadFilepass8 - unknown encryption mode" );
1119 : : }
1120 : :
1121 : 0 : return xDecr;
1122 : : }
1123 : :
1124 : : } // namespace
1125 : :
1126 : : // ----------------------------------------------------------------------------
1127 : :
1128 : 0 : ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm )
1129 : : {
1130 [ # # ]: 0 : XclImpDecrypterRef xDecr;
1131 [ # # ]: 0 : rStrm.DisableDecryption();
1132 : :
1133 : : // read the FILEPASS record and create a new decrypter object
1134 [ # # # ]: 0 : switch( rStrm.GetRoot().GetBiff() )
1135 : : {
1136 : : case EXC_BIFF2:
1137 : : case EXC_BIFF3:
1138 : : case EXC_BIFF4:
1139 [ # # ][ # # ]: 0 : case EXC_BIFF5: xDecr = lclReadFilepass5( rStrm ); break;
[ # # ]
1140 [ # # ][ # # ]: 0 : case EXC_BIFF8: xDecr = lclReadFilepass8( rStrm ); break;
[ # # ]
1141 : : default: DBG_ERROR_BIFF();
1142 : : };
1143 : :
1144 : : // set decrypter at import stream
1145 [ # # ][ # # ]: 0 : rStrm.SetDecrypter( xDecr );
[ # # ]
1146 : :
1147 : : // request and verify a password (decrypter implements IDocPasswordVerifier)
1148 [ # # ]: 0 : if( xDecr )
1149 [ # # ][ # # ]: 0 : rStrm.GetRoot().RequestEncryptionData( *xDecr );
1150 : :
1151 : : // return error code (success, wrong password, etc.)
1152 [ # # ][ # # ]: 0 : return xDecr ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
1153 : : }
1154 : :
1155 : : // Document protection ========================================================
1156 : :
1157 : 55 : XclImpDocProtectBuffer::XclImpDocProtectBuffer( const XclImpRoot& rRoot ) :
1158 : : XclImpRoot( rRoot ),
1159 : : mnPassHash(0x0000),
1160 : : mbDocProtect(false),
1161 : 55 : mbWinProtect(false)
1162 : : {
1163 : 55 : }
1164 : :
1165 : 28 : void XclImpDocProtectBuffer::ReadDocProtect( XclImpStream& rStrm )
1166 : : {
1167 : 28 : mbDocProtect = rStrm.ReaduInt16() ? true : false;
1168 : 28 : }
1169 : :
1170 : 28 : void XclImpDocProtectBuffer::ReadWinProtect( XclImpStream& rStrm )
1171 : : {
1172 : 28 : mbWinProtect = rStrm.ReaduInt16() ? true : false;
1173 : 28 : }
1174 : :
1175 : 28 : void XclImpDocProtectBuffer::ReadPasswordHash( XclImpStream& rStrm )
1176 : : {
1177 : 28 : rStrm.EnableDecryption();
1178 : 28 : mnPassHash = rStrm.ReaduInt16();
1179 : 28 : }
1180 : :
1181 : 55 : void XclImpDocProtectBuffer::Apply() const
1182 : : {
1183 [ + + ][ - + ]: 55 : if (!mbDocProtect && !mbWinProtect)
1184 : : // Excel requires either the structure or windows protection is set.
1185 : : // If neither is set then the document is not protected at all.
1186 : 55 : return;
1187 : :
1188 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1189 [ + - ][ + - ]: 3 : auto_ptr<ScDocProtection> pProtect(new ScDocProtection);
1190 : : SAL_WNODEPRECATED_DECLARATIONS_POP
1191 [ + - ]: 3 : pProtect->setProtected(true);
1192 : :
1193 [ - + ]: 3 : if (mnPassHash)
1194 : : {
1195 : : // 16-bit password pash.
1196 [ # # ]: 0 : Sequence<sal_Int8> aPass(2);
1197 [ # # ]: 0 : aPass[0] = (mnPassHash >> 8) & 0xFF;
1198 [ # # ]: 0 : aPass[1] = mnPassHash & 0xFF;
1199 [ # # ][ # # ]: 0 : pProtect->setPasswordHash(aPass, PASSHASH_XL);
1200 : : }
1201 : :
1202 : : // document protection options
1203 [ + - ]: 3 : pProtect->setOption(ScDocProtection::STRUCTURE, mbDocProtect);
1204 [ + - ]: 3 : pProtect->setOption(ScDocProtection::WINDOWS, mbWinProtect);
1205 : :
1206 [ + - ][ + - ]: 55 : GetDoc().SetDocProtection(pProtect.get());
1207 : : }
1208 : :
1209 : : // Sheet Protection ===========================================================
1210 : :
1211 : 117 : XclImpSheetProtectBuffer::Sheet::Sheet() :
1212 : : mbProtected(false),
1213 : : mnPasswordHash(0x0000),
1214 : 117 : mnOptions(0x4400)
1215 : : {
1216 : 117 : }
1217 : :
1218 : : // ----------------------------------------------------------------------------
1219 : :
1220 : 234 : XclImpSheetProtectBuffer::Sheet::Sheet(const Sheet& r) :
1221 : : mbProtected(r.mbProtected),
1222 : : mnPasswordHash(r.mnPasswordHash),
1223 : 234 : mnOptions(r.mnOptions)
1224 : : {
1225 : 234 : }
1226 : :
1227 : 55 : XclImpSheetProtectBuffer::XclImpSheetProtectBuffer( const XclImpRoot& rRoot ) :
1228 [ + - ]: 55 : XclImpRoot( rRoot )
1229 : : {
1230 : 55 : }
1231 : :
1232 : 36 : void XclImpSheetProtectBuffer::ReadProtect( XclImpStream& rStrm, SCTAB nTab )
1233 : : {
1234 [ + + ]: 36 : if ( rStrm.ReaduInt16() )
1235 : : {
1236 : 33 : Sheet* pSheet = GetSheetItem(nTab);
1237 [ + - ]: 33 : if (pSheet)
1238 : 33 : pSheet->mbProtected = true;
1239 : : }
1240 : 36 : }
1241 : :
1242 : 90 : void XclImpSheetProtectBuffer::ReadOptions( XclImpStream& rStrm, SCTAB nTab )
1243 : : {
1244 [ + - ]: 90 : rStrm.Ignore(12);
1245 : :
1246 : : // feature type can be either 2 or 4. If 2, this record stores flag for
1247 : : // enhanced protection, whereas if 4 it stores flag for smart tag.
1248 : 90 : sal_uInt16 nFeatureType(0);
1249 [ + - ]: 90 : rStrm >> nFeatureType;
1250 [ + - ]: 90 : if (nFeatureType != 2)
1251 : : // We currently only support import of enhanced protection data.
1252 : : return;
1253 : :
1254 [ + - ]: 90 : rStrm.Ignore(1); // always 1
1255 : :
1256 : : // The flag size specifies the size of bytes that follows that stores
1257 : : // feature data. If -1 it depends on the feature type imported earlier.
1258 : : // For enhanced protection data, the size is always 4. For the most xls
1259 : : // documents out there this value is almost always -1.
1260 : 90 : sal_Int32 nFlagSize(0);
1261 [ + - ]: 90 : rStrm >> nFlagSize;
1262 [ + - ]: 90 : if (nFlagSize != -1)
1263 : : return;
1264 : :
1265 : : // There are actually 4 bytes to read, but the upper 2 bytes currently
1266 : : // don't store any bits.
1267 : 90 : sal_uInt16 nOptions(0);
1268 [ + - ]: 90 : rStrm >> nOptions;
1269 : :
1270 [ + - ]: 90 : Sheet* pSheet = GetSheetItem(nTab);
1271 [ + - ]: 90 : if (pSheet)
1272 : 90 : pSheet->mnOptions = nOptions;
1273 : : }
1274 : :
1275 : 3 : void XclImpSheetProtectBuffer::ReadPasswordHash( XclImpStream& rStrm, SCTAB nTab )
1276 : : {
1277 : 3 : sal_uInt16 nHash(0);
1278 [ + - ]: 3 : rStrm >> nHash;
1279 [ + - ]: 3 : Sheet* pSheet = GetSheetItem(nTab);
1280 [ + - ]: 3 : if (pSheet)
1281 : 3 : pSheet->mnPasswordHash = nHash;
1282 : 3 : }
1283 : :
1284 : 55 : void XclImpSheetProtectBuffer::Apply() const
1285 : : {
1286 [ + + ]: 172 : for (ProtectedSheetMap::const_iterator itr = maProtectedSheets.begin(), itrEnd = maProtectedSheets.end();
1287 : : itr != itrEnd; ++itr)
1288 : : {
1289 [ + + ]: 117 : if (!itr->second.mbProtected)
1290 : : // This sheet is (for whatever reason) not protected.
1291 : 84 : continue;
1292 : :
1293 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1294 [ + - ][ + - ]: 33 : auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
1295 : : SAL_WNODEPRECATED_DECLARATIONS_POP
1296 [ + - ]: 33 : pProtect->setProtected(true);
1297 : :
1298 : : // 16-bit hash password
1299 : 33 : const sal_uInt16 nHash = itr->second.mnPasswordHash;
1300 [ - + ]: 33 : if (nHash)
1301 : : {
1302 [ # # ]: 0 : Sequence<sal_Int8> aPass(2);
1303 [ # # ]: 0 : aPass[0] = (nHash >> 8) & 0xFF;
1304 [ # # ]: 0 : aPass[1] = nHash & 0xFF;
1305 [ # # ][ # # ]: 0 : pProtect->setPasswordHash(aPass, PASSHASH_XL);
1306 : : }
1307 : :
1308 : : // sheet protection options
1309 : 33 : const sal_uInt16 nOptions = itr->second.mnOptions;
1310 [ + - ]: 33 : pProtect->setOption( ScTableProtection::OBJECTS, (nOptions & 0x0001) );
1311 [ + - ]: 33 : pProtect->setOption( ScTableProtection::SCENARIOS, (nOptions & 0x0002) );
1312 [ + - ]: 33 : pProtect->setOption( ScTableProtection::FORMAT_CELLS, (nOptions & 0x0004) );
1313 [ + - ]: 33 : pProtect->setOption( ScTableProtection::FORMAT_COLUMNS, (nOptions & 0x0008) );
1314 [ + - ]: 33 : pProtect->setOption( ScTableProtection::FORMAT_ROWS, (nOptions & 0x0010) );
1315 [ + - ]: 33 : pProtect->setOption( ScTableProtection::INSERT_COLUMNS, (nOptions & 0x0020) );
1316 [ + - ]: 33 : pProtect->setOption( ScTableProtection::INSERT_ROWS, (nOptions & 0x0040) );
1317 [ + - ]: 33 : pProtect->setOption( ScTableProtection::INSERT_HYPERLINKS, (nOptions & 0x0080) );
1318 [ + - ]: 33 : pProtect->setOption( ScTableProtection::DELETE_COLUMNS, (nOptions & 0x0100) );
1319 [ + - ]: 33 : pProtect->setOption( ScTableProtection::DELETE_ROWS, (nOptions & 0x0200) );
1320 [ + - ]: 33 : pProtect->setOption( ScTableProtection::SELECT_LOCKED_CELLS, (nOptions & 0x0400) );
1321 [ + - ]: 33 : pProtect->setOption( ScTableProtection::SORT, (nOptions & 0x0800) );
1322 [ + - ]: 33 : pProtect->setOption( ScTableProtection::AUTOFILTER, (nOptions & 0x1000) );
1323 [ + - ]: 33 : pProtect->setOption( ScTableProtection::PIVOT_TABLES, (nOptions & 0x2000) );
1324 [ + - ]: 33 : pProtect->setOption( ScTableProtection::SELECT_UNLOCKED_CELLS, (nOptions & 0x4000) );
1325 : :
1326 : : // all done. now commit.
1327 [ + - ]: 33 : GetDoc().SetTabProtection(itr->first, pProtect.get());
1328 [ + - ]: 33 : }
1329 : 55 : }
1330 : :
1331 : 126 : XclImpSheetProtectBuffer::Sheet* XclImpSheetProtectBuffer::GetSheetItem( SCTAB nTab )
1332 : : {
1333 [ + - ]: 126 : ProtectedSheetMap::iterator itr = maProtectedSheets.find(nTab);
1334 [ + + ]: 126 : if (itr == maProtectedSheets.end())
1335 : : {
1336 : : // new sheet
1337 [ + - ][ - + ]: 117 : if ( !maProtectedSheets.insert( ProtectedSheetMap::value_type(nTab, Sheet()) ).second )
1338 : 0 : return NULL;
1339 : :
1340 [ + - ]: 117 : itr = maProtectedSheets.find(nTab);
1341 : : }
1342 : :
1343 : 126 : return &itr->second;
1344 [ + - ][ + - ]: 24 : }
1345 : :
1346 : : // ============================================================================
1347 : :
1348 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|