update ooo310-m15
[ooovba.git] / sc / source / filter / excel / excimp8.cxx
blob07394d82842164b98a2223c9798fa173cbd661a9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: excimp8.cxx,v $
10 * $Revision: 1.127.4.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "excimp8.hxx"
37 #include <scitems.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <svtools/fltrcfg.hxx>
41 #include <svtools/wmf.hxx>
43 #include <svx/eeitem.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <svx/brshitem.hxx>
48 #include <svx/editdata.hxx>
49 #include <svx/editeng.hxx>
50 #include <svx/editobj.hxx>
51 #include <svx/editstat.hxx>
52 #include <svx/colritem.hxx>
53 #include <svx/udlnitem.hxx>
54 #include <svx/wghtitem.hxx>
55 #include <svx/postitem.hxx>
56 #include <svx/crsditem.hxx>
57 #include <svx/flditem.hxx>
58 #include <svx/xflclit.hxx>
59 #include <svx/svxmsbas.hxx>
61 #include <vcl/graph.hxx>
62 #include <vcl/bmpacc.hxx>
63 #include <sot/exchange.hxx>
65 #include <sfx2/docinf.hxx>
67 #include <tools/string.hxx>
68 #include <tools/urlobj.hxx>
69 #include <rtl/math.hxx>
70 #include <unotools/localedatawrapper.hxx>
71 #include <unotools/charclass.hxx>
72 #include <drwlayer.hxx>
74 #include <boost/scoped_array.hpp>
76 #include "cell.hxx"
77 #include "document.hxx"
78 #include "patattr.hxx"
79 #include "docpool.hxx"
80 #include "attrib.hxx"
81 #include "conditio.hxx"
82 #include "dbcolect.hxx"
83 #include "editutil.hxx"
84 #include "markdata.hxx"
85 #include "rangenam.hxx"
86 #include "docoptio.hxx"
87 #include "globstr.hrc"
88 #include "fprogressbar.hxx"
89 #include "xltracer.hxx"
90 #include "xihelper.hxx"
91 #include "xipage.hxx"
92 #include "xicontent.hxx"
93 #include "xilink.hxx"
94 #include "xiescher.hxx"
95 #include "xipivot.hxx"
97 #include "excform.hxx"
98 #include "scextopt.hxx"
99 #include "stlpool.hxx"
100 #include "stlsheet.hxx"
101 #include "detfunc.hxx"
102 #include "macromgr.hxx"
104 #include <com/sun/star/document/XDocumentProperties.hpp>
105 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
106 #include <com/sun/star/script/ModuleInfo.hpp>
107 #include <basic/basmgr.hxx>
108 #include <cppuhelper/component_context.hxx>
110 #include <com/sun/star/container/XNameContainer.hpp>
111 #include <sfx2/app.hxx>
113 using namespace com::sun::star;
116 #define INVALID_POS 0xFFFFFFFF
118 // defined in docfunc.cxx ( really this needs a new name )
119 script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule );
121 ImportExcel8::ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ) :
122 ImportExcel( rImpData, rStrm ), mnTab(0)
124 delete pFormConv;
126 pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc8( GetRoot() );
128 bHasBasic = FALSE;
132 ImportExcel8::~ImportExcel8()
137 void ImportExcel8::Calccount( void )
139 ScDocOptions aOpt = pD->GetDocOptions();
140 aOpt.SetIterCount( aIn.ReaduInt16() );
141 pD->SetDocOptions( aOpt );
145 void ImportExcel8::Precision( void )
147 ScDocOptions aOpt = pD->GetDocOptions();
148 aOpt.SetCalcAsShown( aIn.ReaduInt16() == 0 );
149 pD->SetDocOptions( aOpt );
153 void ImportExcel8::Delta( void )
155 ScDocOptions aOpt = pD->GetDocOptions();
156 aOpt.SetIterEps( aIn.ReadDouble() );
157 pD->SetDocOptions( aOpt );
161 void ImportExcel8::Iteration( void )
163 ScDocOptions aOpt = pD->GetDocOptions();
164 aOpt.SetIter( aIn.ReaduInt16() == 1 );
165 pD->SetDocOptions( aOpt );
169 void ImportExcel8::Boundsheet( void )
171 UINT8 nLen;
172 UINT16 nGrbit;
174 aIn.Ignore( 4 );
175 aIn >> nGrbit >> nLen;
177 String aName( aIn.ReadUniString( nLen ) );
178 GetTabInfo().AppendXclTabName( aName, nBdshtTab );
180 *pExcRoot->pTabNameBuff << aName;
182 SCTAB nScTab = static_cast< SCTAB >( nBdshtTab );
183 if( nScTab > 0 )
185 DBG_ASSERT( !pD->HasTable( nScTab ), "ImportExcel8::Boundsheet - sheet exists already" );
186 pD->MakeTable( nScTab );
189 if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
190 pD->SetVisible( nScTab, FALSE );
192 if( !pD->RenameTab( nScTab, aName ) )
194 pD->CreateValidTabName( aName );
195 pD->RenameTab( nScTab, aName );
198 nBdshtTab++;
202 void ImportExcel8::Scenman( void )
204 UINT16 nLastDispl;
206 aIn.Ignore( 4 );
207 aIn >> nLastDispl;
209 aScenList.SetLast( nLastDispl );
213 void ImportExcel8::Scenario( void )
215 aScenList.Append( new ExcScenario( aIn, *pExcRoot ) );
219 void ImportExcel8::Labelsst( void )
221 XclAddress aXclPos;
222 UINT16 nXF;
223 UINT32 nSst;
225 aIn >> aXclPos >> nXF >> nSst;
227 ScAddress aScPos( ScAddress::UNINITIALIZED );
228 if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
230 GetXFRangeBuffer().SetXF( aScPos, nXF );
231 if( ScBaseCell* pCell = GetSst().CreateCell( nSst, nXF ) )
232 GetDoc().PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pCell );
237 void ImportExcel8::Codename( BOOL bWorkbookGlobals )
239 if( bHasBasic )
241 String aName( aIn.ReadUniString() );
242 if( aName.Len() )
244 if( bWorkbookGlobals )
246 GetExtDocOptions().GetDocSettings().maGlobCodeName = aName;
247 GetDoc().SetCodeName( aName );
249 else
251 GetExtDocOptions().AppendCodeName( aName );
252 GetDoc().SetCodeName( GetCurrScTab(), aName );
258 void ImportExcel8::SheetProtection( void )
260 GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
263 void ImportExcel8::ReadBasic( void )
265 //bHasBasic = TRUE;
266 bHasBasic = TRUE;
268 SfxObjectShell* pShell = GetDocShell();
269 SotStorageRef xRootStrg = GetRootStorage();
270 SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get();
271 if( pShell && xRootStrg.Is() && pFilterOpt )
273 bool bLoadCode = pFilterOpt->IsLoadExcelBasicCode();
274 bool bLoadExecutable = pFilterOpt->IsLoadExcelBasicExecutable();
275 bool bLoadStrg = pFilterOpt->IsLoadExcelBasicStorage();
276 if( bLoadCode || bLoadStrg )
278 uno::Any aGlobs;
279 uno::Sequence< uno::Any > aArgs(1);
280 aArgs[ 0 ] <<= pShell->GetModel();
281 aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "ooo.vba.excel.Globals"), aArgs );
282 pShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
283 SvxImportMSVBasic aBasicImport( *pShell, *xRootStrg, bLoadCode, bLoadStrg );
284 bool bAsComment = !bLoadExecutable || !aGlobs.hasValue();
285 aBasicImport.Import( EXC_STORAGE_VBA_PROJECT, EXC_STORAGE_VBA, AutoGeneratedCodeNames, bAsComment );
286 if ( !bAsComment )
288 GetObjectManager().SetOleNameOverrideInfo( aBasicImport.ControlNameForObjectId() );
289 ScDocument& rDoc = GetDoc();
290 rDoc.GetMacroManager()->InitUserFuncData();
291 // Fake ThisComponent being setup by Activate ( which is a view
292 // related thing ),
293 // a) if another document is opened then in theory ThisComponent
294 // will be reset as before,
295 // b) when this document is 'really' Activated then ThisComponent
296 // again will be set as before
297 // The only wrinkle seems if this document is loaded 'InVisible'
298 // but.. I don't see that this is possible from the vba API
299 // I could be wrong though
300 // There may be implications setting the current component
301 // too early :-/ so I will just manually set the Basic Variables
302 //SfxObjectShell::SetCurrentComponent( pShell->GetModel() );
303 BasicManager* pAppMgr = SFX_APP()->GetBasicManager();
304 if ( pAppMgr )
306 uno::Any aModel = uno::makeAny( pShell->GetModel() );
307 pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aModel );
315 void ImportExcel8::EndSheet( void )
317 GetCondFormatManager().Apply();
318 ImportExcel::EndSheet();
322 void ImportExcel8::PostDocLoad( void )
324 // delay reading basic until sheet object ( codenames etc. ) are read
326 if ( bHasBasic )
327 ReadBasic();
328 // #i11776# filtered ranges before outlines and hidden rows
329 if( pExcRoot->pAutoFilterBuffer )
330 pExcRoot->pAutoFilterBuffer->Apply();
332 GetWebQueryBuffer().Apply(); //! test if extant
333 GetSheetProtectBuffer().Apply();
334 GetDocProtectBuffer().Apply();
336 ImportExcel::PostDocLoad();
338 // Scenarien bemachen! ACHTUNG: Hier wird Tabellen-Anzahl im Dokument erhoeht!!
339 if( !pD->IsClipboard() && aScenList.Count() )
341 pD->UpdateChartListenerCollection(); // references in charts must be updated
343 aScenList.Apply( GetRoot() );
346 // read doc info (no docshell while pasting from clipboard)
347 if( SfxObjectShell* pShell = GetDocShell() )
349 // BIFF5+ without storage is possible
350 SotStorageRef xRootStrg = GetRootStorage();
351 if( xRootStrg.Is() )
353 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
354 pShell->GetModel(), uno::UNO_QUERY_THROW);
355 uno::Reference<document::XDocumentProperties> xDocProps
356 = xDPS->getDocumentProperties();
357 sfx2::LoadOlePropertySet(xDocProps, GetRootStorage());
361 // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available
362 // when formula cells are calculated, for the GETPIVOTDATA function.
366 //___________________________________________________________________
367 // autofilter
369 void ImportExcel8::FilterMode( void )
371 // The FilterMode record exists: if either the AutoFilter
372 // record exists or an Advanced Filter is saved and stored
373 // in the sheet. Thus if the FilterMode records only exists
374 // then the latter is true..
375 if( !pExcRoot->pAutoFilterBuffer ) return;
377 pExcRoot->pAutoFilterBuffer->IncrementActiveAF();
379 XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
380 if( pData )
381 pData->SetAutoOrAdvanced();
384 void ImportExcel8::AutoFilterInfo( void )
386 if( !pExcRoot->pAutoFilterBuffer ) return;
388 XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
389 if( pData )
391 pData->SetAdvancedRange( NULL );
392 pData->Activate();
396 void ImportExcel8::AutoFilter( void )
398 if( !pExcRoot->pAutoFilterBuffer ) return;
400 XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
401 if( pData )
402 pData->ReadAutoFilter( aIn );
407 XclImpAutoFilterData::XclImpAutoFilterData( RootData* pRoot, const ScRange& rRange, const String& rName ) :
408 ExcRoot( pRoot ),
409 pCurrDBData(NULL),
410 nFirstEmpty( 0 ),
411 bActive( FALSE ),
412 bHasConflict( FALSE ),
413 bCriteria( FALSE ),
414 bAutoOrAdvanced(FALSE),
415 aFilterName(rName)
417 aParam.nCol1 = rRange.aStart.Col();
418 aParam.nRow1 = rRange.aStart.Row();
419 aParam.nTab = rRange.aStart.Tab();
420 aParam.nCol2 = rRange.aEnd.Col();
421 aParam.nRow2 = rRange.aEnd.Row();
423 aParam.bInplace = TRUE;
427 void XclImpAutoFilterData::CreateFromDouble( String& rStr, double fVal )
429 rStr += String( ::rtl::math::doubleToUString( fVal,
430 rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
431 ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), TRUE));
434 void XclImpAutoFilterData::SetCellAttribs()
436 ScDocument& rDoc = pExcRoot->pIR->GetDoc();
437 for ( SCCOL nCol = StartCol(); nCol <= EndCol(); nCol++ )
439 INT16 nFlag = ((ScMergeFlagAttr*) rDoc.GetAttr( nCol, StartRow(), Tab(), ATTR_MERGE_FLAG ))->GetValue();
440 rDoc.ApplyAttr( nCol, StartRow(), Tab(), ScMergeFlagAttr( nFlag | SC_MF_AUTO) );
444 void XclImpAutoFilterData::InsertQueryParam()
446 if( pCurrDBData && !bHasConflict )
448 ScRange aAdvRange;
449 BOOL bHasAdv = pCurrDBData->GetAdvancedQuerySource( aAdvRange );
450 if( bHasAdv )
451 pExcRoot->pIR->GetDoc().CreateQueryParam( aAdvRange.aStart.Col(),
452 aAdvRange.aStart.Row(), aAdvRange.aEnd.Col(), aAdvRange.aEnd.Row(),
453 aAdvRange.aStart.Tab(), aParam );
455 pCurrDBData->SetQueryParam( aParam );
456 if( bHasAdv )
457 pCurrDBData->SetAdvancedQuerySource( &aAdvRange );
458 else
460 pCurrDBData->SetAutoFilter( TRUE );
461 SetCellAttribs();
466 static void ExcelQueryToOooQuery( ScQueryEntry& rEntry, ScQueryParam& rParam )
468 if( rEntry.pStr == NULL )
469 return;
470 if( rEntry.eOp != SC_EQUAL && rEntry.eOp != SC_NOT_EQUAL )
471 return;
472 xub_StrLen nLen = rEntry.pStr->Len();
473 if( nLen == 0 )
474 return;
475 BOOL bRegExp = FALSE;
476 for( int i = 0; i < nLen; ++i ) {
477 sal_Unicode c = rEntry.pStr->GetChar( i );
478 if( c == '*' ) {
479 if( rEntry.eOp == SC_NOT_EQUAL ) {
480 bRegExp = TRUE;
481 rEntry.eOp = SC_DOES_NOT_CONTAIN;
483 else if( rEntry.eOp == SC_DOES_NOT_CONTAIN )
484 ; // ignore
485 else if( i == 0 )
486 rEntry.eOp = SC_ENDS_WITH;
487 else if( i == nLen-1 )
488 rEntry.eOp = rEntry.eOp == SC_ENDS_WITH ? SC_CONTAINS : SC_BEGINS_WITH;
489 else
490 bRegExp = TRUE;
492 else if( c == '?' )
493 bRegExp = TRUE;
495 if( rEntry.pStr->GetChar( 0 ) == '*' )
496 rEntry.pStr->Erase( 0, 1 );
497 nLen = rEntry.pStr->Len();
498 if( nLen > 0 && rEntry.pStr->GetChar( nLen-1 ) == '*' ) {
499 rEntry.pStr->Erase( nLen-1, 1 );
500 --nLen;
502 if( bRegExp ) {
503 rParam.bRegExp = TRUE;
504 for( int i = 0; i < nLen; ++i ) {
505 sal_Unicode c = rEntry.pStr->GetChar( i );
506 switch( c ) {
507 case '*':
508 rEntry.pStr->ReplaceAscii( i, 1, ".*" );
509 ++i;
510 ++nLen;
511 break;
512 case '.':
513 rEntry.pStr->InsertAscii( "\\", i );
514 ++i;
515 ++nLen;
516 break;
517 case '?':
518 rEntry.pStr->ReplaceAscii( i, 1, "." );
519 break;
520 default: break;
526 void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
528 UINT16 nCol, nFlags;
529 rStrm >> nCol >> nFlags;
531 ScQueryConnect eConn = ::get_flagvalue( nFlags, EXC_AFFLAG_ANDORMASK, SC_OR, SC_AND );
532 BOOL bTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10 );
533 BOOL bTopOfTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10TOP );
534 BOOL bPercent = ::get_flag( nFlags, EXC_AFFLAG_TOP10PERC );
535 UINT16 nCntOfTop10 = nFlags >> 7;
536 SCSIZE nCount = aParam.GetEntryCount();
538 if( bTop10 )
540 if( nFirstEmpty < nCount )
542 ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
543 aEntry.bDoQuery = TRUE;
544 aEntry.bQueryByString = TRUE;
545 aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
546 aEntry.eOp = bTopOfTop10 ?
547 (bPercent ? SC_TOPPERC : SC_TOPVAL) : (bPercent ? SC_BOTPERC : SC_BOTVAL);
548 aEntry.eConnect = SC_AND;
549 aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nCntOfTop10 ) );
551 rStrm.Ignore( 20 );
552 nFirstEmpty++;
555 else
557 UINT8 nE, nType, nOper, nBoolErr, nVal;
558 INT32 nRK;
559 double fVal;
560 BOOL bIgnore;
562 UINT8 nStrLen[ 2 ] = { 0, 0 };
563 ScQueryEntry *pQueryEntries[ 2 ] = { NULL, NULL };
565 for( nE = 0; nE < 2; nE++ )
567 if( nFirstEmpty < nCount )
569 ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
570 pQueryEntries[ nE ] = &aEntry;
571 bIgnore = FALSE;
573 rStrm >> nType >> nOper;
574 switch( nOper )
576 case EXC_AFOPER_LESS:
577 aEntry.eOp = SC_LESS;
578 break;
579 case EXC_AFOPER_EQUAL:
580 aEntry.eOp = SC_EQUAL;
581 break;
582 case EXC_AFOPER_LESSEQUAL:
583 aEntry.eOp = SC_LESS_EQUAL;
584 break;
585 case EXC_AFOPER_GREATER:
586 aEntry.eOp = SC_GREATER;
587 break;
588 case EXC_AFOPER_NOTEQUAL:
589 aEntry.eOp = SC_NOT_EQUAL;
590 break;
591 case EXC_AFOPER_GREATEREQUAL:
592 aEntry.eOp = SC_GREATER_EQUAL;
593 break;
594 default:
595 aEntry.eOp = SC_EQUAL;
598 switch( nType )
600 case EXC_AFTYPE_RK:
601 rStrm >> nRK;
602 rStrm.Ignore( 4 );
603 CreateFromDouble( *aEntry.pStr, XclTools::GetDoubleFromRK( nRK ) );
604 break;
605 case EXC_AFTYPE_DOUBLE:
606 rStrm >> fVal;
607 CreateFromDouble( *aEntry.pStr, fVal );
608 break;
609 case EXC_AFTYPE_STRING:
610 rStrm.Ignore( 4 );
611 rStrm >> nStrLen[ nE ];
612 rStrm.Ignore( 3 );
613 aEntry.pStr->Erase();
614 break;
615 case EXC_AFTYPE_BOOLERR:
616 rStrm >> nBoolErr >> nVal;
617 rStrm.Ignore( 6 );
618 aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nVal ) );
619 bIgnore = (BOOL) nBoolErr;
620 break;
621 case EXC_AFTYPE_EMPTY:
622 aEntry.bQueryByString = FALSE;
623 aEntry.nVal = SC_EMPTYFIELDS;
624 aEntry.eOp = SC_EQUAL;
625 break;
626 case EXC_AFTYPE_NOTEMPTY:
627 aEntry.bQueryByString = FALSE;
628 aEntry.nVal = SC_NONEMPTYFIELDS;
629 aEntry.eOp = SC_EQUAL;
630 break;
631 default:
632 rStrm.Ignore( 8 );
633 bIgnore = TRUE;
636 /* #i39464# conflict, if two conditions of one column are 'OR'ed,
637 and they follow conditions of other columns.
638 Example: Let A1 be a condition of column A, and B1 and B2
639 conditions of column B, connected with OR. Excel performs
640 'A1 AND (B1 OR B2)' in this case, but Calc would do
641 '(A1 AND B1) OR B2' instead. */
642 if( (nFirstEmpty > 1) && nE && (eConn == SC_OR) && !bIgnore )
643 bHasConflict = TRUE;
644 if( !bHasConflict && !bIgnore )
646 aEntry.bDoQuery = TRUE;
647 aEntry.bQueryByString = TRUE;
648 aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
649 aEntry.eConnect = nE ? eConn : SC_AND;
650 nFirstEmpty++;
653 else
654 rStrm.Ignore( 10 );
657 for( nE = 0; nE < 2; nE++ )
658 if( nStrLen[ nE ] && pQueryEntries[ nE ] ) {
659 pQueryEntries[ nE ]->pStr->Assign ( rStrm.ReadUniString( nStrLen[ nE ] ) );
660 ExcelQueryToOooQuery( *pQueryEntries[ nE ], aParam );
665 void XclImpAutoFilterData::SetAdvancedRange( const ScRange* pRange )
667 if (pRange)
669 aCriteriaRange = *pRange;
670 bCriteria = TRUE;
672 else
673 bCriteria = FALSE;
676 void XclImpAutoFilterData::SetExtractPos( const ScAddress& rAddr )
678 aParam.nDestCol = rAddr.Col();
679 aParam.nDestRow = rAddr.Row();
680 aParam.nDestTab = rAddr.Tab();
681 aParam.bInplace = FALSE;
682 aParam.bDestPers = TRUE;
685 void XclImpAutoFilterData::Apply( const BOOL bUseUnNamed )
687 CreateScDBData(bUseUnNamed);
689 if( bActive )
691 InsertQueryParam();
693 // #i38093# rows hidden by filter need extra flag, but CR_FILTERED is not set here yet
694 // SCROW nRow1 = StartRow();
695 // SCROW nRow2 = EndRow();
696 // size_t nRows = nRow2 - nRow1 + 1;
697 // boost::scoped_array<BYTE> pFlags( new BYTE[nRows]);
698 // pExcRoot->pDoc->GetRowFlagsArray( Tab()).FillDataArray( nRow1, nRow2,
699 // pFlags.get());
700 // for (size_t j=0; j<nRows; ++j)
701 // {
702 // if ((pFlags[j] & CR_HIDDEN) && !(pFlags[j] & CR_FILTERED))
703 // pExcRoot->pDoc->SetRowFlags( nRow1 + j, Tab(),
704 // pFlags[j] | CR_FILTERED );
705 // }
709 void XclImpAutoFilterData::CreateScDBData( const BOOL bUseUnNamed )
712 // Create the ScDBData() object if the AutoFilter is activated
713 // or if we need to create the Advanced Filter.
714 if( bActive || bCriteria)
716 ScDBCollection& rColl = pExcRoot->pIR->GetDatabaseRanges();
717 pCurrDBData = rColl.GetDBAtArea( Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
718 if( !pCurrDBData )
720 AmendAFName(bUseUnNamed);
722 pCurrDBData = new ScDBData( aFilterName, Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
724 if( pCurrDBData )
726 if(bCriteria)
728 EnableRemoveFilter();
730 pCurrDBData->SetQueryParam( aParam );
731 pCurrDBData->SetAdvancedQuerySource(&aCriteriaRange);
733 else
734 pCurrDBData->SetAdvancedQuerySource(NULL);
735 rColl.Insert( pCurrDBData );
742 void XclImpAutoFilterData::EnableRemoveFilter()
744 // only if this is a saved Advanced filter
745 if( !bActive && bAutoOrAdvanced )
747 ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
748 aEntry.bDoQuery = TRUE;
749 ++nFirstEmpty;
752 // TBD: force the automatic activation of the
753 // "Remove Filter" by setting a virtual mouse click
754 // inside the advanced range
757 void XclImpAutoFilterData::AmendAFName(const BOOL bUseUnNamed)
759 // If-and-only-if we have one AF filter then
760 // use the Calc "unnamed" range name. Calc
761 // only supports one in total while Excel
762 // supports one per sheet.
763 if( bUseUnNamed && bAutoOrAdvanced )
764 aFilterName = ScGlobal::GetRscString(STR_DB_NONAME);
767 XclImpAutoFilterBuffer::XclImpAutoFilterBuffer() :
768 nAFActiveCount( 0 )
772 XclImpAutoFilterBuffer::~XclImpAutoFilterBuffer()
774 for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
775 delete pData;
778 void XclImpAutoFilterBuffer::Insert( RootData* pRoot, const ScRange& rRange,
779 const String& rName )
781 if( !GetByTab( rRange.aStart.Tab() ) )
782 Append( new XclImpAutoFilterData( pRoot, rRange, rName ) );
785 void XclImpAutoFilterBuffer::AddAdvancedRange( const ScRange& rRange )
787 XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
788 if( pData )
789 pData->SetAdvancedRange( &rRange );
792 void XclImpAutoFilterBuffer::AddExtractPos( const ScRange& rRange )
794 XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
795 if( pData )
796 pData->SetExtractPos( rRange.aStart );
799 void XclImpAutoFilterBuffer::Apply()
801 for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
802 pData->Apply(UseUnNamed());
805 XclImpAutoFilterData* XclImpAutoFilterBuffer::GetByTab( SCTAB nTab )
807 for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
808 if( pData->Tab() == nTab )
809 return pData;
810 return NULL;