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 "excrecds.hxx"
21 :
22 : #include <map>
23 : #include <filter/msfilter/countryid.hxx>
24 :
25 : #include "scitems.hxx"
26 : #include <editeng/eeitem.hxx>
27 :
28 : #include <sfx2/objsh.hxx>
29 :
30 : #include <editeng/editdata.hxx>
31 : #include <editeng/editeng.hxx>
32 : #include <editeng/editobj.hxx>
33 : #include <editeng/editstat.hxx>
34 :
35 : #include <editeng/flditem.hxx>
36 : #include <editeng/flstitem.hxx>
37 :
38 : #include <svx/algitem.hxx>
39 : #include <editeng/boxitem.hxx>
40 : #include <editeng/brushitem.hxx>
41 : #include <svx/pageitem.hxx>
42 : #include <editeng/paperinf.hxx>
43 : #include <editeng/sizeitem.hxx>
44 : #include <editeng/ulspitem.hxx>
45 : #include <editeng/fhgtitem.hxx>
46 : #include <editeng/escapementitem.hxx>
47 : #include <svl/intitem.hxx>
48 : #include <svl/zforlist.hxx>
49 : #include <svl/zformat.hxx>
50 : #include <svtools/ctrltool.hxx>
51 :
52 :
53 : #include <string.h>
54 :
55 : #include "global.hxx"
56 : #include "globstr.hrc"
57 : #include "docpool.hxx"
58 : #include "patattr.hxx"
59 : #include "formulacell.hxx"
60 : #include "document.hxx"
61 : #include "scextopt.hxx"
62 : #include "attrib.hxx"
63 : #include "progress.hxx"
64 : #include "dociter.hxx"
65 : #include "rangenam.hxx"
66 : #include "dbdata.hxx"
67 : #include "stlsheet.hxx"
68 : #include "stlpool.hxx"
69 : #include "editutil.hxx"
70 : #include "formula/errorcodes.hxx"
71 : #include "queryentry.hxx"
72 : #include "queryparam.hxx"
73 :
74 : #include "excdoc.hxx"
75 : #include "xeescher.hxx"
76 : #include "xeformula.hxx"
77 : #include "xelink.hxx"
78 : #include "xename.hxx"
79 : #include "xecontent.hxx"
80 :
81 : #include "xcl97rec.hxx"
82 : #include "tabprotection.hxx"
83 :
84 : using namespace ::oox;
85 :
86 : using ::com::sun::star::uno::Sequence;
87 :
88 : //--------------------------------------------------------- class ExcDummy_00 -
89 : const sal_uInt8 ExcDummy_00::pMyData[] = {
90 : 0x5c, 0x00, 0x20, 0x00, 0x04, 'C', 'a', 'l', 'c', // WRITEACCESS
91 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
92 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
93 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
94 : };
95 : const sal_Size ExcDummy_00::nMyLen = sizeof( ExcDummy_00::pMyData );
96 :
97 : //-------------------------------------------------------- class ExcDummy_04x -
98 : const sal_uInt8 ExcDummy_040::pMyData[] = {
99 : 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, // BACKUP
100 : 0x8d, 0x00, 0x02, 0x00, 0x00, 0x00, // HIDEOBJ
101 : };
102 : const sal_Size ExcDummy_040::nMyLen = sizeof( ExcDummy_040::pMyData );
103 :
104 : const sal_uInt8 ExcDummy_041::pMyData[] = {
105 : 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, // PRECISION
106 : 0xda, 0x00, 0x02, 0x00, 0x00, 0x00 // BOOKBOOL
107 : };
108 : const sal_Size ExcDummy_041::nMyLen = sizeof( ExcDummy_041::pMyData );
109 :
110 : //-------------------------------------------------------- class ExcDummy_02a -
111 : const sal_uInt8 ExcDummy_02a::pMyData[] = {
112 : 0x0d, 0x00, 0x02, 0x00, 0x01, 0x00, // CALCMODE
113 : 0x0c, 0x00, 0x02, 0x00, 0x64, 0x00, // CALCCOUNT
114 : 0x0f, 0x00, 0x02, 0x00, 0x01, 0x00, // REFMODE
115 : 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, // ITERATION
116 : 0x10, 0x00, 0x08, 0x00, 0xfc, 0xa9, 0xf1, 0xd2, 0x4d, // DELTA
117 : 0x62, 0x50, 0x3f,
118 : 0x5f, 0x00, 0x02, 0x00, 0x01, 0x00 // SAVERECALC
119 : };
120 : const sal_Size ExcDummy_02a::nMyLen = sizeof( ExcDummy_02a::pMyData );
121 :
122 : //----------------------------------------------------------- class ExcRecord -
123 :
124 0 : void ExcRecord::Save( XclExpStream& rStrm )
125 : {
126 0 : SetRecHeader( GetNum(), GetLen() );
127 0 : XclExpRecord::Save( rStrm );
128 0 : }
129 :
130 0 : void ExcRecord::SaveCont( XclExpStream& /*rStrm*/ )
131 : {
132 0 : }
133 :
134 0 : void ExcRecord::WriteBody( XclExpStream& rStrm )
135 : {
136 0 : SaveCont( rStrm );
137 0 : }
138 :
139 0 : void ExcRecord::SaveXml( XclExpXmlStream& /*rStrm*/ )
140 : {
141 0 : }
142 :
143 :
144 : //--------------------------------------------------------- class ExcEmptyRec -
145 :
146 0 : void ExcEmptyRec::Save( XclExpStream& /*rStrm*/ )
147 : {
148 0 : }
149 :
150 :
151 0 : sal_uInt16 ExcEmptyRec::GetNum() const
152 : {
153 0 : return 0;
154 : }
155 :
156 :
157 0 : sal_Size ExcEmptyRec::GetLen() const
158 : {
159 0 : return 0;
160 : }
161 :
162 : //--------------------------------------------------------- class ExcDummyRec -
163 :
164 0 : void ExcDummyRec::Save( XclExpStream& rStrm )
165 : {
166 0 : rStrm.Write( GetData(), GetLen() ); // raw write mode
167 0 : }
168 :
169 :
170 0 : sal_uInt16 ExcDummyRec::GetNum( void ) const
171 : {
172 0 : return 0x0000;
173 : }
174 :
175 : //------------------------------------------------------- class ExcBoolRecord -
176 :
177 0 : void ExcBoolRecord::SaveCont( XclExpStream& rStrm )
178 : {
179 0 : rStrm << (sal_uInt16)(bVal ? 0x0001 : 0x0000);
180 0 : }
181 :
182 :
183 0 : sal_Size ExcBoolRecord::GetLen( void ) const
184 : {
185 0 : return 2;
186 : }
187 :
188 :
189 : //--------------------------------------------------------- class ExcBof_Base -
190 :
191 0 : ExcBof_Base::ExcBof_Base() :
192 : nRupBuild( 0x096C ), // copied from Excel
193 0 : nRupYear( 0x07C9 ) // copied from Excel
194 : {
195 0 : }
196 :
197 : //-------------------------------------------------------------- class ExcBof -
198 :
199 0 : ExcBof::ExcBof( void )
200 : {
201 0 : nDocType = 0x0010;
202 0 : nVers = 0x0500;
203 0 : }
204 :
205 :
206 0 : void ExcBof::SaveCont( XclExpStream& rStrm )
207 : {
208 0 : rStrm << nVers << nDocType << nRupBuild << nRupYear;
209 0 : }
210 :
211 :
212 0 : sal_uInt16 ExcBof::GetNum( void ) const
213 : {
214 0 : return 0x0809;
215 : }
216 :
217 :
218 0 : sal_Size ExcBof::GetLen( void ) const
219 : {
220 0 : return 8;
221 : }
222 :
223 : //------------------------------------------------------------- class ExcBofW -
224 :
225 0 : ExcBofW::ExcBofW( void )
226 : {
227 0 : nDocType = 0x0005;
228 0 : nVers = 0x0500;
229 0 : }
230 :
231 :
232 0 : void ExcBofW::SaveCont( XclExpStream& rStrm )
233 : {
234 0 : rStrm << nVers << nDocType << nRupBuild << nRupYear;
235 0 : }
236 :
237 0 : sal_uInt16 ExcBofW::GetNum( void ) const
238 : {
239 0 : return 0x0809;
240 : }
241 :
242 0 : sal_Size ExcBofW::GetLen( void ) const
243 : {
244 0 : return 8;
245 : }
246 :
247 : //-------------------------------------------------------------- class ExcEof -
248 :
249 0 : sal_uInt16 ExcEof::GetNum( void ) const
250 : {
251 0 : return 0x000A;
252 : }
253 :
254 :
255 0 : sal_Size ExcEof::GetLen( void ) const
256 : {
257 0 : return 0;
258 : }
259 :
260 : //--------------------------------------------------------- class ExcDummy_00 -
261 :
262 0 : sal_Size ExcDummy_00::GetLen( void ) const
263 : {
264 0 : return nMyLen;
265 : }
266 :
267 :
268 0 : const sal_uInt8* ExcDummy_00::GetData( void ) const
269 : {
270 0 : return pMyData;
271 : }
272 :
273 : //-------------------------------------------------------- class ExcDummy_04x -
274 :
275 0 : sal_Size ExcDummy_040::GetLen( void ) const
276 : {
277 0 : return nMyLen;
278 : }
279 :
280 :
281 0 : const sal_uInt8* ExcDummy_040::GetData( void ) const
282 : {
283 0 : return pMyData;
284 : }
285 :
286 :
287 0 : sal_Size ExcDummy_041::GetLen( void ) const
288 : {
289 0 : return nMyLen;
290 : }
291 :
292 :
293 0 : const sal_uInt8* ExcDummy_041::GetData( void ) const
294 : {
295 0 : return pMyData;
296 : }
297 :
298 : //------------------------------------------------------------- class Exc1904 -
299 :
300 0 : Exc1904::Exc1904( ScDocument& rDoc )
301 : {
302 0 : Date* pDate = rDoc.GetFormatTable()->GetNullDate();
303 0 : bVal = pDate ? (*pDate == Date( 1, 1, 1904 )) : false;
304 0 : bDateCompatibility = pDate ? !( *pDate == Date( 30, 12, 1899 )) : false;
305 0 : }
306 :
307 :
308 0 : sal_uInt16 Exc1904::GetNum( void ) const
309 : {
310 0 : return 0x0022;
311 : }
312 :
313 :
314 0 : void Exc1904::SaveXml( XclExpXmlStream& rStrm )
315 : {
316 0 : bool bISOIEC = ( rStrm.getVersion() == oox::core::ISOIEC_29500_2008 );
317 :
318 0 : if( bISOIEC )
319 : {
320 : rStrm.WriteAttributes(
321 : XML_dateCompatibility, XclXmlUtils::ToPsz( bDateCompatibility ),
322 0 : FSEND );
323 : }
324 :
325 0 : if( !bISOIEC || bDateCompatibility )
326 : {
327 : rStrm.WriteAttributes(
328 : XML_date1904, XclXmlUtils::ToPsz( bVal ),
329 0 : FSEND );
330 : }
331 0 : }
332 :
333 : //------------------------------------------------------ class ExcBundlesheet -
334 :
335 0 : ExcBundlesheetBase::ExcBundlesheetBase( RootData& rRootData, SCTAB nTabNum ) :
336 : m_nStrPos( STREAM_SEEK_TO_END ),
337 : m_nOwnPos( STREAM_SEEK_TO_END ),
338 0 : nGrbit( rRootData.pER->GetTabInfo().IsVisibleTab( nTabNum ) ? 0x0000 : 0x0001 ),
339 0 : nTab( nTabNum )
340 : {
341 0 : }
342 :
343 :
344 0 : ExcBundlesheetBase::ExcBundlesheetBase() :
345 : m_nStrPos( STREAM_SEEK_TO_END ),
346 : m_nOwnPos( STREAM_SEEK_TO_END ),
347 : nGrbit( 0x0000 ),
348 0 : nTab( SCTAB_GLOBAL )
349 : {
350 0 : }
351 :
352 :
353 0 : void ExcBundlesheetBase::UpdateStreamPos( XclExpStream& rStrm )
354 : {
355 0 : rStrm.SetSvStreamPos( m_nOwnPos );
356 0 : rStrm.DisableEncryption();
357 0 : rStrm << static_cast<sal_uInt32>(m_nStrPos);
358 0 : rStrm.EnableEncryption();
359 0 : }
360 :
361 :
362 0 : sal_uInt16 ExcBundlesheetBase::GetNum( void ) const
363 : {
364 0 : return 0x0085;
365 : }
366 :
367 :
368 0 : ExcBundlesheet::ExcBundlesheet( RootData& rRootData, SCTAB _nTab ) :
369 0 : ExcBundlesheetBase( rRootData, _nTab )
370 : {
371 0 : OUString sTabName = rRootData.pER->GetTabInfo().GetScTabName( _nTab );
372 : OSL_ENSURE( sTabName.getLength() < 256, "ExcBundlesheet::ExcBundlesheet - table name too long" );
373 0 : aName = OUStringToOString(sTabName, rRootData.pER->GetTextEncoding());
374 0 : }
375 :
376 :
377 0 : void ExcBundlesheet::SaveCont( XclExpStream& rStrm )
378 : {
379 0 : m_nOwnPos = rStrm.GetSvStreamPos();
380 0 : rStrm << (sal_uInt32) 0x00000000 // dummy (stream position of the sheet)
381 0 : << nGrbit;
382 0 : rStrm.WriteByteString(aName); // 8 bit length, max 255 chars
383 0 : }
384 :
385 :
386 0 : sal_Size ExcBundlesheet::GetLen() const
387 : {
388 0 : return 7 + std::min( aName.getLength(), (sal_Int32) 255 );
389 : }
390 :
391 :
392 : //--------------------------------------------------------- class ExcDummy_02 -
393 :
394 0 : sal_Size ExcDummy_02a::GetLen( void ) const
395 : {
396 0 : return nMyLen;
397 : }
398 :
399 0 : const sal_uInt8* ExcDummy_02a::GetData( void ) const
400 : {
401 0 : return pMyData;
402 : }
403 : //--------------------------------------------------------- class ExcDummy_02 -
404 :
405 0 : XclExpCountry::XclExpCountry( const XclExpRoot& rRoot ) :
406 0 : XclExpRecord( EXC_ID_COUNTRY, 4 )
407 : {
408 : /* #i31530# set document country as UI country too -
409 : needed for correct behaviour of number formats. */
410 : mnUICountry = mnDocCountry = static_cast< sal_uInt16 >(
411 0 : ::msfilter::ConvertLanguageToCountry( rRoot.GetDocLanguage() ) );
412 0 : }
413 :
414 0 : void XclExpCountry::WriteBody( XclExpStream& rStrm )
415 : {
416 0 : rStrm << mnUICountry << mnDocCountry;
417 0 : }
418 :
419 : // XclExpWsbool ===============================================================
420 :
421 0 : XclExpWsbool::XclExpWsbool( bool bFitToPages )
422 0 : : XclExpUInt16Record( EXC_ID_WSBOOL, EXC_WSBOOL_DEFAULTFLAGS )
423 : {
424 0 : if( bFitToPages )
425 0 : SetValue( GetValue() | EXC_WSBOOL_FITTOPAGE );
426 0 : }
427 :
428 0 : XclExpXmlSheetPr::XclExpXmlSheetPr( bool bFitToPages, SCTAB nScTab, const Color& rTabColor, XclExpFilterManager* pManager ) :
429 0 : mnScTab(nScTab), mpManager(pManager), mbFitToPage(bFitToPages), maTabColor(rTabColor) {}
430 :
431 0 : void XclExpXmlSheetPr::SaveXml( XclExpXmlStream& rStrm )
432 : {
433 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
434 : rWorksheet->startElement( XML_sheetPr,
435 : // OOXTODO: XML_syncHorizontal,
436 : // OOXTODO: XML_syncVertical,
437 : // OOXTODO: XML_syncRef,
438 : // OOXTODO: XML_transitionEvaluation,
439 : // OOXTODO: XML_transitionEntry,
440 : // OOXTODO: XML_published,
441 : // OOXTODO: XML_codeName,
442 0 : XML_filterMode, mpManager ? XclXmlUtils::ToPsz( mpManager->HasFilterMode( mnScTab ) ) : NULL,
443 : // OOXTODO: XML_enableFormatConditionsCalculation,
444 0 : FSEND );
445 :
446 : // Note : the order of child elements is significant. Don't change the order.
447 :
448 : // OOXTODO: XML_outlinePr
449 :
450 : rWorksheet->singleElement(
451 0 : XML_tabColor, XML_rgb, XclXmlUtils::ToOString(maTabColor).getStr(), FSEND);
452 :
453 : rWorksheet->singleElement(XML_pageSetUpPr,
454 : // OOXTODO: XML_autoPageBreaks,
455 0 : XML_fitToPage, XclXmlUtils::ToPsz(mbFitToPage), FSEND);
456 :
457 0 : rWorksheet->endElement( XML_sheetPr );
458 0 : }
459 :
460 :
461 : // XclExpWindowProtection ===============================================================
462 :
463 0 : XclExpWindowProtection::XclExpWindowProtection(bool bValue) :
464 0 : XclExpBoolRecord(EXC_ID_WINDOWPROTECT, bValue)
465 : {
466 0 : }
467 :
468 0 : void XclExpWindowProtection::SaveXml( XclExpXmlStream& rStrm )
469 : {
470 : rStrm.WriteAttributes(
471 0 : XML_lockWindows, XclXmlUtils::ToPsz( GetBool() ),
472 0 : FSEND );
473 0 : }
474 :
475 : // XclExpDocProtection ===============================================================
476 :
477 0 : XclExpProtection::XclExpProtection(bool bValue) :
478 0 : XclExpBoolRecord(EXC_ID_PROTECT, bValue)
479 : {
480 0 : }
481 :
482 0 : XclExpSheetProtection::XclExpSheetProtection(bool bValue, SCTAB nTab ) :
483 : XclExpProtection( bValue),
484 0 : mnTab(nTab)
485 : {
486 0 : }
487 :
488 0 : void XclExpSheetProtection::SaveXml( XclExpXmlStream& rStrm )
489 : {
490 0 : ScDocument& rDoc = rStrm.GetRoot().GetDoc();
491 0 : const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnTab);
492 0 : if ( pTabProtect )
493 : {
494 0 : Sequence<sal_Int8> aHash = pTabProtect->getPasswordHash(PASSHASH_XL);
495 0 : sal_uInt16 nHash(0x0000);
496 0 : OString sHash;
497 0 : if (aHash.getLength() >= 2)
498 : {
499 0 : nHash = ((aHash[0] << 8) & 0xFFFF);
500 0 : nHash |= (aHash[1] & 0xFF);
501 0 : sHash = OString::number( nHash, 16 );
502 : }
503 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
504 : rWorksheet->singleElement( XML_sheetProtection,
505 : XML_sheet, XclXmlUtils::ToPsz( true ),
506 0 : XML_password, sHash.isEmpty()? NULL : sHash.getStr(),
507 0 : XML_objects, pTabProtect->isOptionEnabled( ScTableProtection::OBJECTS ) ? NULL : XclXmlUtils::ToPsz( true ),
508 0 : XML_scenarios, pTabProtect->isOptionEnabled( ScTableProtection::SCENARIOS ) ? NULL : XclXmlUtils::ToPsz( true ),
509 0 : XML_formatCells, pTabProtect->isOptionEnabled( ScTableProtection::FORMAT_CELLS ) ? XclXmlUtils::ToPsz( false ) : NULL,
510 0 : XML_formatColumns, pTabProtect->isOptionEnabled( ScTableProtection::FORMAT_COLUMNS ) ? XclXmlUtils::ToPsz( false ) : NULL,
511 0 : XML_formatRows, pTabProtect->isOptionEnabled( ScTableProtection::FORMAT_ROWS ) ? XclXmlUtils::ToPsz( false ) : NULL,
512 0 : XML_insertColumns, pTabProtect->isOptionEnabled( ScTableProtection::INSERT_COLUMNS ) ? XclXmlUtils::ToPsz( false ) : NULL,
513 0 : XML_insertRows, pTabProtect->isOptionEnabled( ScTableProtection::INSERT_ROWS ) ? XclXmlUtils::ToPsz( false ) : NULL,
514 0 : XML_insertHyperlinks, pTabProtect->isOptionEnabled( ScTableProtection::INSERT_HYPERLINKS ) ? XclXmlUtils::ToPsz( false ) : NULL,
515 0 : XML_deleteColumns, pTabProtect->isOptionEnabled( ScTableProtection::DELETE_COLUMNS ) ? XclXmlUtils::ToPsz( false ) : NULL,
516 0 : XML_deleteRows, pTabProtect->isOptionEnabled( ScTableProtection::DELETE_ROWS ) ? XclXmlUtils::ToPsz( false ) : NULL,
517 0 : XML_selectLockedCells, pTabProtect->isOptionEnabled( ScTableProtection::SELECT_LOCKED_CELLS ) ? NULL : XclXmlUtils::ToPsz( true ),
518 0 : XML_sort, pTabProtect->isOptionEnabled( ScTableProtection::SORT ) ? XclXmlUtils::ToPsz( false ) : NULL,
519 0 : XML_autoFilter, pTabProtect->isOptionEnabled( ScTableProtection::AUTOFILTER ) ? XclXmlUtils::ToPsz( false ) : NULL,
520 0 : XML_pivotTables, pTabProtect->isOptionEnabled( ScTableProtection::PIVOT_TABLES ) ? XclXmlUtils::ToPsz( false ) : NULL,
521 0 : XML_selectUnlockedCells, pTabProtect->isOptionEnabled( ScTableProtection::SELECT_UNLOCKED_CELLS ) ? NULL : XclXmlUtils::ToPsz( true ),
522 0 : FSEND );
523 :
524 0 : const ::std::vector<ScEnhancedProtection>& rProts( pTabProtect->getEnhancedProtection());
525 0 : if (!rProts.empty())
526 : {
527 0 : rWorksheet->startElement( XML_protectedRanges, FSEND);
528 0 : for (::std::vector<ScEnhancedProtection>::const_iterator it( rProts.begin()), end( rProts.end());
529 : it != end; ++it)
530 : {
531 : SAL_WARN_IF( (*it).maSecurityDescriptorXML.isEmpty() && !(*it).maSecurityDescriptor.empty(),
532 : "sc.filter", "XclExpSheetProtection::SaveXml: loosing BIFF security descriptor");
533 : rWorksheet->singleElement( XML_protectedRange,
534 0 : XML_name, (*it).maTitle.isEmpty() ? NULL : XclXmlUtils::ToOString( (*it).maTitle).getStr(),
535 0 : XML_securityDescriptor, (*it).maSecurityDescriptorXML.isEmpty() ? NULL : XclXmlUtils::ToOString( (*it).maSecurityDescriptorXML).getStr(),
536 : /* XXX 'password' is not part of OOXML, but Excel2013
537 : * writes it if loaded from BIFF, in which case
538 : * 'algorithmName', 'hashValue', 'saltValue' and
539 : * 'spinCount' are absent; so do we if it was present. */
540 0 : XML_password, (*it).mnPasswordVerifier ? OString::number( (*it).mnPasswordVerifier, 16).getStr() : NULL,
541 0 : XML_algorithmName, (*it).maAlgorithmName.isEmpty() ? NULL : XclXmlUtils::ToOString( (*it).maAlgorithmName).getStr(),
542 0 : XML_hashValue, (*it).maHashValue.isEmpty() ? NULL : XclXmlUtils::ToOString( (*it).maHashValue).getStr(),
543 0 : XML_saltValue, (*it).maSaltValue.isEmpty() ? NULL : XclXmlUtils::ToOString( (*it).maSaltValue).getStr(),
544 0 : XML_spinCount, (*it).mnSpinCount ? OString::number( (*it).mnSpinCount).getStr() : NULL,
545 0 : XML_sqref, (*it).maRangeList.Is() ? XclXmlUtils::ToOString( *(*it).maRangeList).getStr() : NULL,
546 0 : FSEND);
547 : }
548 0 : rWorksheet->endElement( XML_protectedRanges);
549 0 : }
550 : }
551 0 : }
552 :
553 :
554 0 : XclExpPassHash::XclExpPassHash(const Sequence<sal_Int8>& aHash) :
555 : XclExpRecord(EXC_ID_PASSWORD, 2),
556 0 : mnHash(0x0000)
557 : {
558 0 : if (aHash.getLength() >= 2)
559 : {
560 0 : mnHash = ((aHash[0] << 8) & 0xFFFF);
561 0 : mnHash |= (aHash[1] & 0xFF);
562 : }
563 0 : }
564 :
565 0 : XclExpPassHash::~XclExpPassHash()
566 : {
567 0 : }
568 :
569 0 : void XclExpPassHash::WriteBody(XclExpStream& rStrm)
570 : {
571 0 : rStrm << mnHash;
572 0 : }
573 :
574 0 : XclExpFiltermode::XclExpFiltermode() :
575 0 : XclExpEmptyRecord( EXC_ID_FILTERMODE )
576 : {
577 0 : }
578 :
579 0 : XclExpAutofilterinfo::XclExpAutofilterinfo( const ScAddress& rStartPos, SCCOL nScCol ) :
580 : XclExpUInt16Record( EXC_ID_AUTOFILTERINFO, static_cast< sal_uInt16 >( nScCol ) ),
581 0 : maStartPos( rStartPos )
582 : {
583 0 : }
584 :
585 0 : ExcFilterCondition::ExcFilterCondition() :
586 : nType( EXC_AFTYPE_NOTUSED ),
587 : nOper( EXC_AFOPER_EQUAL ),
588 : fVal( 0.0 ),
589 0 : pText( NULL )
590 : {
591 0 : }
592 :
593 0 : ExcFilterCondition::~ExcFilterCondition()
594 : {
595 0 : if( pText )
596 0 : delete pText;
597 0 : }
598 :
599 0 : sal_Size ExcFilterCondition::GetTextBytes() const
600 : {
601 0 : return pText ? (1 + pText->GetBufferSize()) : 0;
602 : }
603 :
604 0 : void ExcFilterCondition::SetCondition( sal_uInt8 nTp, sal_uInt8 nOp, double fV, OUString* pT )
605 : {
606 0 : nType = nTp;
607 0 : nOper = nOp;
608 0 : fVal = fV;
609 :
610 0 : delete pText;
611 0 : (pT) ? pText = new XclExpString( *pT, EXC_STR_8BITLENGTH ) : pText = NULL;
612 0 : }
613 :
614 0 : void ExcFilterCondition::Save( XclExpStream& rStrm )
615 : {
616 0 : rStrm << nType << nOper;
617 0 : switch( nType )
618 : {
619 : case EXC_AFTYPE_DOUBLE:
620 0 : rStrm << fVal;
621 0 : break;
622 : case EXC_AFTYPE_STRING:
623 : OSL_ENSURE( pText, "ExcFilterCondition::Save() -- pText is NULL!" );
624 0 : rStrm << (sal_uInt32)0 << (sal_uInt8) pText->Len() << (sal_uInt16)0 << (sal_uInt8)0;
625 0 : break;
626 : case EXC_AFTYPE_BOOLERR:
627 0 : rStrm << (sal_uInt8)0 << (sal_uInt8)((fVal != 0) ? 1 : 0) << (sal_uInt32)0 << (sal_uInt16)0;
628 0 : break;
629 : default:
630 0 : rStrm << (sal_uInt32)0 << (sal_uInt32)0;
631 : }
632 0 : }
633 :
634 0 : static const char* lcl_GetOperator( sal_uInt8 nOper )
635 : {
636 0 : switch( nOper )
637 : {
638 0 : case EXC_AFOPER_EQUAL: return "equal";
639 0 : case EXC_AFOPER_GREATER: return "greaterThan";
640 0 : case EXC_AFOPER_GREATEREQUAL: return "greaterThanOrEqual";
641 0 : case EXC_AFOPER_LESS: return "lessThan";
642 0 : case EXC_AFOPER_LESSEQUAL: return "lessThanOrEqual";
643 0 : case EXC_AFOPER_NOTEQUAL: return "notEqual";
644 : case EXC_AFOPER_NONE:
645 0 : default: return "**none**";
646 : }
647 : }
648 :
649 0 : static OString lcl_GetValue( sal_uInt8 nType, double fVal, XclExpString* pStr )
650 : {
651 0 : switch( nType )
652 : {
653 0 : case EXC_AFTYPE_STRING: return XclXmlUtils::ToOString( *pStr );
654 0 : case EXC_AFTYPE_DOUBLE: return OString::number( fVal );
655 0 : case EXC_AFTYPE_BOOLERR: return OString::number( ( fVal != 0 ? 1 : 0 ) );
656 0 : default: return OString();
657 : }
658 : }
659 :
660 0 : void ExcFilterCondition::SaveXml( XclExpXmlStream& rStrm )
661 : {
662 0 : if( IsEmpty() )
663 0 : return;
664 :
665 0 : rStrm.GetCurrentStream()->singleElement( XML_customFilter,
666 : XML_operator, lcl_GetOperator( nOper ),
667 : XML_val, lcl_GetValue( nType, fVal, pText ).getStr(),
668 0 : FSEND );
669 : }
670 :
671 0 : void ExcFilterCondition::SaveText( XclExpStream& rStrm )
672 : {
673 0 : if( nType == EXC_AFTYPE_STRING )
674 : {
675 : OSL_ENSURE( pText, "ExcFilterCondition::SaveText() -- pText is NULL!" );
676 0 : pText->WriteFlagField( rStrm );
677 0 : pText->WriteBuffer( rStrm );
678 : }
679 0 : }
680 :
681 0 : XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC ) :
682 : XclExpRecord( EXC_ID_AUTOFILTER, 24 ),
683 : XclExpRoot( rRoot ),
684 : meType(FilterCondition),
685 : nCol( nC ),
686 0 : nFlags( 0 )
687 : {
688 0 : }
689 :
690 0 : bool XclExpAutofilter::AddCondition( ScQueryConnect eConn, sal_uInt8 nType, sal_uInt8 nOp,
691 : double fVal, OUString* pText, bool bSimple )
692 : {
693 0 : if( !aCond[ 1 ].IsEmpty() )
694 0 : return false;
695 :
696 0 : sal_uInt16 nInd = aCond[ 0 ].IsEmpty() ? 0 : 1;
697 :
698 0 : if( nInd == 1 )
699 0 : nFlags |= (eConn == SC_OR) ? EXC_AFFLAG_OR : EXC_AFFLAG_AND;
700 0 : if( bSimple )
701 0 : nFlags |= (nInd == 0) ? EXC_AFFLAG_SIMPLE1 : EXC_AFFLAG_SIMPLE2;
702 :
703 0 : aCond[ nInd ].SetCondition( nType, nOp, fVal, pText );
704 :
705 0 : AddRecSize( aCond[ nInd ].GetTextBytes() );
706 :
707 0 : return true;
708 : }
709 :
710 0 : bool XclExpAutofilter::HasCondition() const
711 : {
712 0 : return !aCond[0].IsEmpty();
713 : }
714 :
715 0 : bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
716 : {
717 0 : const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
718 0 : if (rItems.empty())
719 0 : return true;
720 :
721 0 : if (GetOutput() != EXC_OUTPUT_BINARY && rItems.size() > 1)
722 0 : return AddMultiValueEntry(rEntry);
723 :
724 0 : bool bConflict = false;
725 0 : OUString sText;
726 0 : const ScQueryEntry::Item& rItem = rItems[0];
727 0 : if (!rItem.maString.isEmpty())
728 : {
729 0 : sText = rItem.maString.getString();
730 0 : switch( rEntry.eOp )
731 : {
732 : case SC_CONTAINS:
733 : case SC_DOES_NOT_CONTAIN:
734 : {
735 0 : sText = "*" + sText + "*";
736 : }
737 0 : break;
738 : case SC_BEGINS_WITH:
739 : case SC_DOES_NOT_BEGIN_WITH:
740 0 : sText += "*";
741 0 : break;
742 : case SC_ENDS_WITH:
743 : case SC_DOES_NOT_END_WITH:
744 0 : sText = "*" + sText;
745 0 : break;
746 : default:
747 : {
748 : //nothing
749 : }
750 : }
751 : }
752 :
753 0 : bool bLen = sText.getLength() > 0;
754 :
755 : // empty/nonempty fields
756 0 : if (rEntry.IsQueryByEmpty())
757 0 : bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, NULL, true );
758 0 : else if(rEntry.IsQueryByNonEmpty())
759 0 : bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_NOTEMPTY, EXC_AFOPER_NONE, 0.0, NULL, true );
760 : // other conditions
761 : else
762 : {
763 0 : double fVal = 0.0;
764 0 : sal_uInt32 nIndex = 0;
765 0 : bool bIsNum = bLen ? GetFormatter().IsNumberFormat( sText, nIndex, fVal ) : true;
766 : OUString* pText;
767 0 : (bIsNum) ? pText = NULL : pText = &sText;
768 :
769 : // top10 flags
770 0 : sal_uInt16 nNewFlags = 0x0000;
771 0 : switch( rEntry.eOp )
772 : {
773 : case SC_TOPVAL:
774 0 : nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP);
775 0 : break;
776 : case SC_BOTVAL:
777 0 : nNewFlags = EXC_AFFLAG_TOP10;
778 0 : break;
779 : case SC_TOPPERC:
780 0 : nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP | EXC_AFFLAG_TOP10PERC);
781 0 : break;
782 : case SC_BOTPERC:
783 0 : nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10PERC);
784 0 : break;
785 : default:;
786 : }
787 0 : bool bNewTop10 = ::get_flag( nNewFlags, EXC_AFFLAG_TOP10 );
788 :
789 0 : bConflict = HasTop10() && bNewTop10;
790 0 : if( !bConflict )
791 : {
792 0 : if( bNewTop10 )
793 : {
794 0 : if( fVal < 0 ) fVal = 0;
795 0 : if( fVal >= 501 ) fVal = 500;
796 0 : nFlags |= (nNewFlags | (sal_uInt16)(fVal) << 7);
797 : }
798 : // normal condition
799 : else
800 : {
801 0 : sal_uInt8 nType = bIsNum ? EXC_AFTYPE_DOUBLE : EXC_AFTYPE_STRING;
802 0 : sal_uInt8 nOper = EXC_AFOPER_NONE;
803 :
804 0 : switch( rEntry.eOp )
805 : {
806 0 : case SC_EQUAL: nOper = EXC_AFOPER_EQUAL; break;
807 0 : case SC_LESS: nOper = EXC_AFOPER_LESS; break;
808 0 : case SC_GREATER: nOper = EXC_AFOPER_GREATER; break;
809 0 : case SC_LESS_EQUAL: nOper = EXC_AFOPER_LESSEQUAL; break;
810 0 : case SC_GREATER_EQUAL: nOper = EXC_AFOPER_GREATEREQUAL; break;
811 0 : case SC_NOT_EQUAL: nOper = EXC_AFOPER_NOTEQUAL; break;
812 : case SC_CONTAINS:
813 : case SC_BEGINS_WITH:
814 : case SC_ENDS_WITH:
815 0 : nOper = EXC_AFOPER_EQUAL; break;
816 : case SC_DOES_NOT_CONTAIN:
817 : case SC_DOES_NOT_BEGIN_WITH:
818 : case SC_DOES_NOT_END_WITH:
819 0 : nOper = EXC_AFOPER_NOTEQUAL; break;
820 : default:;
821 : }
822 0 : bConflict = !AddCondition( rEntry.eConnect, nType, nOper, fVal, pText );
823 : }
824 : }
825 : }
826 0 : return bConflict;
827 : }
828 :
829 0 : bool XclExpAutofilter::AddMultiValueEntry( const ScQueryEntry& rEntry )
830 : {
831 0 : meType = MultiValue;
832 0 : const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
833 0 : ScQueryEntry::QueryItemsType::const_iterator itr = rItems.begin(), itrEnd = rItems.end();
834 0 : for (; itr != itrEnd; ++itr)
835 0 : maMultiValues.push_back(itr->maString.getString());
836 :
837 0 : return false;
838 : }
839 :
840 0 : void XclExpAutofilter::WriteBody( XclExpStream& rStrm )
841 : {
842 0 : rStrm << nCol << nFlags;
843 0 : aCond[ 0 ].Save( rStrm );
844 0 : aCond[ 1 ].Save( rStrm );
845 0 : aCond[ 0 ].SaveText( rStrm );
846 0 : aCond[ 1 ].SaveText( rStrm );
847 0 : }
848 :
849 0 : void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
850 : {
851 0 : if (meType == FilterCondition && !HasCondition())
852 0 : return;
853 :
854 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
855 :
856 : rWorksheet->startElement( XML_filterColumn,
857 : XML_colId, OString::number( nCol ).getStr(),
858 : // OOXTODO: XML_hiddenButton, AutoFilter12 fHideArrow?
859 : // OOXTODO: XML_showButton,
860 0 : FSEND );
861 :
862 0 : switch (meType)
863 : {
864 : case FilterCondition:
865 : {
866 0 : if( HasTop10() )
867 : {
868 : rWorksheet->singleElement( XML_top10,
869 0 : XML_top, XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10TOP ) ),
870 0 : XML_percent, XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10PERC ) ),
871 : XML_val, OString::number( (nFlags >> 7 ) ).getStr(),
872 : // OOXTODO: XML_filterVal,
873 0 : FSEND );
874 : }
875 :
876 : rWorksheet->startElement( XML_customFilters,
877 0 : XML_and, XclXmlUtils::ToPsz( (nFlags & EXC_AFFLAG_ANDORMASK) == EXC_AFFLAG_AND ),
878 0 : FSEND );
879 0 : aCond[ 0 ].SaveXml( rStrm );
880 0 : aCond[ 1 ].SaveXml( rStrm );
881 0 : rWorksheet->endElement( XML_customFilters );
882 : // OOXTODO: XLM_colorFilter, XML_dynamicFilter,
883 : // XML_extLst, XML_filters, XML_iconFilter, XML_top10
884 : }
885 0 : break;
886 : case MultiValue:
887 : {
888 0 : rWorksheet->startElement(XML_filters, FSEND);
889 0 : std::vector<OUString>::const_iterator itr = maMultiValues.begin(), itrEnd = maMultiValues.end();
890 0 : for (; itr != itrEnd; ++itr)
891 : {
892 0 : const char* pz = OUStringToOString(*itr, RTL_TEXTENCODING_UTF8).getStr();
893 0 : rWorksheet->singleElement(XML_filter, XML_val, pz, FSEND);
894 : }
895 0 : rWorksheet->endElement(XML_filters);
896 : }
897 0 : break;
898 : }
899 0 : rWorksheet->endElement( XML_filterColumn );
900 : }
901 :
902 0 : ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab ) :
903 : XclExpRoot( rRoot ),
904 : pFilterMode( NULL ),
905 : pFilterInfo( NULL )
906 0 : , mbAutoFilter (false)
907 : {
908 0 : XclExpNameManager& rNameMgr = GetNameManager();
909 :
910 0 : sal_Bool bFound = false;
911 0 : sal_Bool bAdvanced = false;
912 0 : ScDBData* pData = rRoot.GetDoc().GetAnonymousDBData(nTab);
913 0 : ScRange aAdvRange;
914 0 : if (pData)
915 : {
916 0 : bAdvanced = pData->GetAdvancedQuerySource( aAdvRange );
917 0 : bFound = (pData->HasQueryParam() || pData->HasAutoFilter() || bAdvanced);
918 : }
919 0 : if( bFound )
920 : {
921 0 : ScQueryParam aParam;
922 0 : pData->GetQueryParam( aParam );
923 :
924 : ScRange aRange( aParam.nCol1, aParam.nRow1, aParam.nTab,
925 0 : aParam.nCol2, aParam.nRow2, aParam.nTab );
926 0 : SCCOL nColCnt = aParam.nCol2 - aParam.nCol1 + 1;
927 :
928 0 : maRef = aRange;
929 :
930 : // #i2394# built-in defined names must be sorted by containing sheet name
931 0 : rNameMgr.InsertBuiltInName( EXC_BUILTIN_FILTERDATABASE, aRange );
932 :
933 : // advanced filter
934 0 : if( bAdvanced )
935 : {
936 : // filter criteria, excel allows only same table
937 0 : if( aAdvRange.aStart.Tab() == nTab )
938 0 : rNameMgr.InsertBuiltInName( EXC_BUILTIN_CRITERIA, aAdvRange );
939 :
940 : // filter destination range, excel allows only same table
941 0 : if( !aParam.bInplace )
942 : {
943 0 : ScRange aDestRange( aParam.nDestCol, aParam.nDestRow, aParam.nDestTab );
944 0 : aDestRange.aEnd.IncCol( nColCnt - 1 );
945 0 : if( aDestRange.aStart.Tab() == nTab )
946 0 : rNameMgr.InsertBuiltInName( EXC_BUILTIN_EXTRACT, aDestRange );
947 : }
948 :
949 0 : pFilterMode = new XclExpFiltermode;
950 : }
951 : // AutoFilter
952 : else
953 : {
954 0 : sal_Bool bConflict = false;
955 0 : sal_Bool bContLoop = sal_True;
956 0 : bool bHasOr = false;
957 0 : SCCOLROW nFirstField = aParam.GetEntry( 0 ).nField;
958 :
959 : // create AUTOFILTER records for filtered columns
960 0 : for( SCSIZE nEntry = 0; !bConflict && bContLoop && (nEntry < aParam.GetEntryCount()); nEntry++ )
961 : {
962 0 : const ScQueryEntry& rEntry = aParam.GetEntry( nEntry );
963 :
964 0 : bContLoop = rEntry.bDoQuery;
965 0 : if( bContLoop )
966 : {
967 0 : XclExpAutofilter* pFilter = GetByCol( static_cast<SCCOL>(rEntry.nField) - aRange.aStart.Col() );
968 :
969 0 : if( nEntry > 0 )
970 0 : bHasOr |= (rEntry.eConnect == SC_OR);
971 :
972 0 : bConflict = (nEntry > 1) && bHasOr;
973 0 : if( !bConflict )
974 0 : bConflict = (nEntry == 1) && (rEntry.eConnect == SC_OR) &&
975 0 : (nFirstField != rEntry.nField);
976 0 : if( !bConflict )
977 0 : bConflict = pFilter->AddEntry( rEntry );
978 : }
979 : }
980 :
981 : // additional tests for conflicts
982 0 : for( size_t nPos = 0, nSize = maFilterList.GetSize(); !bConflict && (nPos < nSize); ++nPos )
983 : {
984 0 : XclExpAutofilterRef xFilter = maFilterList.GetRecord( nPos );
985 0 : bConflict = xFilter->HasCondition() && xFilter->HasTop10();
986 0 : }
987 :
988 0 : if( bConflict )
989 0 : maFilterList.RemoveAllRecords();
990 :
991 0 : if( !maFilterList.IsEmpty() )
992 0 : pFilterMode = new XclExpFiltermode;
993 0 : pFilterInfo = new XclExpAutofilterinfo( aRange.aStart, nColCnt );
994 :
995 0 : if (maFilterList.IsEmpty () && !bConflict)
996 0 : mbAutoFilter = true;
997 0 : }
998 : }
999 0 : }
1000 :
1001 0 : ExcAutoFilterRecs::~ExcAutoFilterRecs()
1002 : {
1003 0 : delete pFilterMode;
1004 0 : delete pFilterInfo;
1005 0 : }
1006 :
1007 0 : XclExpAutofilter* ExcAutoFilterRecs::GetByCol( SCCOL nCol )
1008 : {
1009 0 : XclExpAutofilterRef xFilter;
1010 0 : for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
1011 : {
1012 0 : xFilter = maFilterList.GetRecord( nPos );
1013 0 : if( xFilter->GetCol() == static_cast<sal_uInt16>(nCol) )
1014 0 : return xFilter.get();
1015 : }
1016 0 : xFilter.reset( new XclExpAutofilter( GetRoot(), static_cast<sal_uInt16>(nCol) ) );
1017 0 : maFilterList.AppendRecord( xFilter );
1018 0 : return xFilter.get();
1019 : }
1020 :
1021 0 : bool ExcAutoFilterRecs::IsFiltered( SCCOL nCol )
1022 : {
1023 0 : for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
1024 0 : if( maFilterList.GetRecord( nPos )->GetCol() == static_cast<sal_uInt16>(nCol) )
1025 0 : return true;
1026 0 : return false;
1027 : }
1028 :
1029 0 : void ExcAutoFilterRecs::AddObjRecs()
1030 : {
1031 0 : if( pFilterInfo )
1032 : {
1033 0 : ScAddress aAddr( pFilterInfo->GetStartPos() );
1034 0 : for( SCCOL nObj = 0, nCount = pFilterInfo->GetColCount(); nObj < nCount; nObj++ )
1035 : {
1036 0 : XclObj* pObjRec = new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) );
1037 0 : GetObjectManager().AddObj( pObjRec );
1038 0 : aAddr.IncCol( 1 );
1039 : }
1040 : }
1041 0 : }
1042 :
1043 0 : void ExcAutoFilterRecs::Save( XclExpStream& rStrm )
1044 : {
1045 0 : if( pFilterMode )
1046 0 : pFilterMode->Save( rStrm );
1047 0 : if( pFilterInfo )
1048 0 : pFilterInfo->Save( rStrm );
1049 0 : maFilterList.Save( rStrm );
1050 0 : }
1051 :
1052 0 : void ExcAutoFilterRecs::SaveXml( XclExpXmlStream& rStrm )
1053 : {
1054 0 : if( maFilterList.IsEmpty() && !mbAutoFilter )
1055 0 : return;
1056 :
1057 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
1058 : rWorksheet->startElement( XML_autoFilter,
1059 : XML_ref, XclXmlUtils::ToOString( maRef ).getStr(),
1060 0 : FSEND );
1061 : // OOXTODO: XML_extLst, XML_sortState
1062 0 : if( !maFilterList.IsEmpty() )
1063 0 : maFilterList.SaveXml( rStrm );
1064 0 : rWorksheet->endElement( XML_autoFilter );
1065 : }
1066 :
1067 0 : bool ExcAutoFilterRecs::HasFilterMode() const
1068 : {
1069 0 : return pFilterMode != NULL;
1070 : }
1071 :
1072 0 : XclExpFilterManager::XclExpFilterManager( const XclExpRoot& rRoot ) :
1073 0 : XclExpRoot( rRoot )
1074 : {
1075 0 : }
1076 :
1077 0 : void XclExpFilterManager::InitTabFilter( SCTAB nScTab )
1078 : {
1079 0 : maFilterMap[ nScTab ].reset( new ExcAutoFilterRecs( GetRoot(), nScTab ) );
1080 0 : }
1081 :
1082 0 : XclExpRecordRef XclExpFilterManager::CreateRecord( SCTAB nScTab )
1083 : {
1084 0 : XclExpTabFilterRef xRec;
1085 0 : XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
1086 0 : if( aIt != maFilterMap.end() )
1087 : {
1088 0 : xRec = aIt->second;
1089 0 : xRec->AddObjRecs();
1090 : }
1091 0 : return xRec;
1092 : }
1093 :
1094 0 : bool XclExpFilterManager::HasFilterMode( SCTAB nScTab )
1095 : {
1096 0 : XclExpTabFilterRef xRec;
1097 0 : XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
1098 0 : if( aIt != maFilterMap.end() )
1099 : {
1100 0 : return aIt->second->HasFilterMode();
1101 : }
1102 0 : return false;
1103 0 : }
1104 :
1105 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|