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