merge the formfield patch from ooo-build
[ooovba.git] / sc / source / filter / excel / excimp8.cxx
blob79d504b320d2a3b53199b22558a116384275ba2f
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>
112 #include "xltoolbar.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.DisableDecryption();
175 maSheetOffsets.push_back( aIn.ReaduInt32() );
176 aIn.EnableDecryption();
177 aIn >> nGrbit >> nLen;
179 String aName( aIn.ReadUniString( nLen ) );
180 GetTabInfo().AppendXclTabName( aName, nBdshtTab );
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 );
309 #if 1
310 // see if we have the XCB stream
311 SvStorageStreamRef xXCB = xRootStrg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "XCB" ) ), STREAM_STD_READ | STREAM_NOCREATE );
312 if ( xXCB.Is()|| SVSTREAM_OK == xXCB->GetError() )
314 CTBWrapper wrapper;
315 if ( wrapper.Read( xXCB ) )
317 #if DEBUG
318 wrapper.Print( stderr );
319 #endif
320 wrapper.ImportCustomToolBar( *pShell );
323 #endif
330 void ImportExcel8::EndSheet( void )
332 GetCondFormatManager().Apply();
333 ImportExcel::EndSheet();
337 void ImportExcel8::PostDocLoad( void )
339 // delay reading basic until sheet object ( codenames etc. ) are read
341 if ( bHasBasic )
342 ReadBasic();
343 // #i11776# filtered ranges before outlines and hidden rows
344 if( pExcRoot->pAutoFilterBuffer )
345 pExcRoot->pAutoFilterBuffer->Apply();
347 GetWebQueryBuffer().Apply(); //! test if extant
348 GetSheetProtectBuffer().Apply();
349 GetDocProtectBuffer().Apply();
351 ImportExcel::PostDocLoad();
353 // Scenarien bemachen! ACHTUNG: Hier wird Tabellen-Anzahl im Dokument erhoeht!!
354 if( !pD->IsClipboard() && aScenList.Count() )
356 pD->UpdateChartListenerCollection(); // references in charts must be updated
358 aScenList.Apply( GetRoot() );
361 // read doc info (no docshell while pasting from clipboard)
362 if( SfxObjectShell* pShell = GetDocShell() )
364 // BIFF5+ without storage is possible
365 SotStorageRef xRootStrg = GetRootStorage();
366 if( xRootStrg.Is() )
368 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
369 pShell->GetModel(), uno::UNO_QUERY_THROW);
370 uno::Reference<document::XDocumentProperties> xDocProps
371 = xDPS->getDocumentProperties();
372 sfx2::LoadOlePropertySet(xDocProps, GetRootStorage());
376 // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available
377 // when formula cells are calculated, for the GETPIVOTDATA function.
381 //___________________________________________________________________
382 // autofilter
384 void ImportExcel8::FilterMode( void )
386 // The FilterMode record exists: if either the AutoFilter
387 // record exists or an Advanced Filter is saved and stored
388 // in the sheet. Thus if the FilterMode records only exists
389 // then the latter is true..
390 if( !pExcRoot->pAutoFilterBuffer ) return;
392 pExcRoot->pAutoFilterBuffer->IncrementActiveAF();
394 XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
395 if( pData )
396 pData->SetAutoOrAdvanced();
399 void ImportExcel8::AutoFilterInfo( void )
401 if( !pExcRoot->pAutoFilterBuffer ) return;
403 XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
404 if( pData )
406 pData->SetAdvancedRange( NULL );
407 pData->Activate();
411 void ImportExcel8::AutoFilter( void )
413 if( !pExcRoot->pAutoFilterBuffer ) return;
415 XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
416 if( pData )
417 pData->ReadAutoFilter( aIn );
422 XclImpAutoFilterData::XclImpAutoFilterData( RootData* pRoot, const ScRange& rRange, const String& rName ) :
423 ExcRoot( pRoot ),
424 pCurrDBData(NULL),
425 nFirstEmpty( 0 ),
426 bActive( FALSE ),
427 bHasConflict( FALSE ),
428 bCriteria( FALSE ),
429 bAutoOrAdvanced(FALSE),
430 aFilterName(rName)
432 aParam.nCol1 = rRange.aStart.Col();
433 aParam.nRow1 = rRange.aStart.Row();
434 aParam.nTab = rRange.aStart.Tab();
435 aParam.nCol2 = rRange.aEnd.Col();
436 aParam.nRow2 = rRange.aEnd.Row();
438 aParam.bInplace = TRUE;
442 void XclImpAutoFilterData::CreateFromDouble( String& rStr, double fVal )
444 rStr += String( ::rtl::math::doubleToUString( fVal,
445 rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
446 ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), TRUE));
449 void XclImpAutoFilterData::SetCellAttribs()
451 ScDocument& rDoc = pExcRoot->pIR->GetDoc();
452 for ( SCCOL nCol = StartCol(); nCol <= EndCol(); nCol++ )
454 INT16 nFlag = ((ScMergeFlagAttr*) rDoc.GetAttr( nCol, StartRow(), Tab(), ATTR_MERGE_FLAG ))->GetValue();
455 rDoc.ApplyAttr( nCol, StartRow(), Tab(), ScMergeFlagAttr( nFlag | SC_MF_AUTO) );
459 void XclImpAutoFilterData::InsertQueryParam()
461 if( pCurrDBData && !bHasConflict )
463 ScRange aAdvRange;
464 BOOL bHasAdv = pCurrDBData->GetAdvancedQuerySource( aAdvRange );
465 if( bHasAdv )
466 pExcRoot->pIR->GetDoc().CreateQueryParam( aAdvRange.aStart.Col(),
467 aAdvRange.aStart.Row(), aAdvRange.aEnd.Col(), aAdvRange.aEnd.Row(),
468 aAdvRange.aStart.Tab(), aParam );
470 pCurrDBData->SetQueryParam( aParam );
471 if( bHasAdv )
472 pCurrDBData->SetAdvancedQuerySource( &aAdvRange );
473 else
475 pCurrDBData->SetAutoFilter( TRUE );
476 SetCellAttribs();
481 static void ExcelQueryToOooQuery( ScQueryEntry& rEntry )
483 if( ( rEntry.eOp != SC_EQUAL && rEntry.eOp != SC_NOT_EQUAL ) || rEntry.pStr == NULL )
484 return;
485 else
487 xub_StrLen nLen = rEntry.pStr->Len();
488 sal_Unicode nStart = rEntry.pStr->GetChar( 0 );
489 sal_Unicode nEnd = rEntry.pStr->GetChar( nLen-1 );
490 if( nLen >2 && nStart == '*' && nEnd == '*' )
492 rEntry.pStr->Erase( nLen-1, 1 );
493 rEntry.pStr->Erase( 0, 1 );
494 rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_CONTAINS : SC_DOES_NOT_CONTAIN;
496 else if( nLen > 1 && nStart == '*' && nEnd != '*' )
498 rEntry.pStr->Erase( 0, 1 );
499 rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_ENDS_WITH : SC_DOES_NOT_END_WITH;
501 else if( nLen > 1 && nStart != '*' && nEnd == '*' )
503 rEntry.pStr->Erase( nLen-1, 1 );
504 rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_BEGINS_WITH : SC_DOES_NOT_BEGIN_WITH;
506 else if( nLen == 2 && nStart == '*' && nEnd == '*' )
508 rEntry.pStr->Erase( 0, 1 );
513 void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
515 UINT16 nCol, nFlags;
516 rStrm >> nCol >> nFlags;
518 ScQueryConnect eConn = ::get_flagvalue( nFlags, EXC_AFFLAG_ANDORMASK, SC_OR, SC_AND );
519 BOOL bTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10 );
520 BOOL bTopOfTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10TOP );
521 BOOL bPercent = ::get_flag( nFlags, EXC_AFFLAG_TOP10PERC );
522 UINT16 nCntOfTop10 = nFlags >> 7;
523 SCSIZE nCount = aParam.GetEntryCount();
525 if( bTop10 )
527 if( nFirstEmpty < nCount )
529 ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
530 aEntry.bDoQuery = TRUE;
531 aEntry.bQueryByString = TRUE;
532 aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
533 aEntry.eOp = bTopOfTop10 ?
534 (bPercent ? SC_TOPPERC : SC_TOPVAL) : (bPercent ? SC_BOTPERC : SC_BOTVAL);
535 aEntry.eConnect = SC_AND;
536 aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nCntOfTop10 ) );
538 rStrm.Ignore( 20 );
539 nFirstEmpty++;
542 else
544 UINT8 nE, nType, nOper, nBoolErr, nVal;
545 INT32 nRK;
546 double fVal;
547 BOOL bIgnore;
549 UINT8 nStrLen[ 2 ] = { 0, 0 };
550 ScQueryEntry *pQueryEntries[ 2 ] = { NULL, NULL };
552 for( nE = 0; nE < 2; nE++ )
554 if( nFirstEmpty < nCount )
556 ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
557 pQueryEntries[ nE ] = &aEntry;
558 bIgnore = FALSE;
560 rStrm >> nType >> nOper;
561 switch( nOper )
563 case EXC_AFOPER_LESS:
564 aEntry.eOp = SC_LESS;
565 break;
566 case EXC_AFOPER_EQUAL:
567 aEntry.eOp = SC_EQUAL;
568 break;
569 case EXC_AFOPER_LESSEQUAL:
570 aEntry.eOp = SC_LESS_EQUAL;
571 break;
572 case EXC_AFOPER_GREATER:
573 aEntry.eOp = SC_GREATER;
574 break;
575 case EXC_AFOPER_NOTEQUAL:
576 aEntry.eOp = SC_NOT_EQUAL;
577 break;
578 case EXC_AFOPER_GREATEREQUAL:
579 aEntry.eOp = SC_GREATER_EQUAL;
580 break;
581 default:
582 aEntry.eOp = SC_EQUAL;
585 switch( nType )
587 case EXC_AFTYPE_RK:
588 rStrm >> nRK;
589 rStrm.Ignore( 4 );
590 CreateFromDouble( *aEntry.pStr, XclTools::GetDoubleFromRK( nRK ) );
591 break;
592 case EXC_AFTYPE_DOUBLE:
593 rStrm >> fVal;
594 CreateFromDouble( *aEntry.pStr, fVal );
595 break;
596 case EXC_AFTYPE_STRING:
597 rStrm.Ignore( 4 );
598 rStrm >> nStrLen[ nE ];
599 rStrm.Ignore( 3 );
600 aEntry.pStr->Erase();
601 break;
602 case EXC_AFTYPE_BOOLERR:
603 rStrm >> nBoolErr >> nVal;
604 rStrm.Ignore( 6 );
605 aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nVal ) );
606 bIgnore = (BOOL) nBoolErr;
607 break;
608 case EXC_AFTYPE_EMPTY:
609 aEntry.bQueryByString = FALSE;
610 aEntry.nVal = SC_EMPTYFIELDS;
611 aEntry.eOp = SC_EQUAL;
612 break;
613 case EXC_AFTYPE_NOTEMPTY:
614 aEntry.bQueryByString = FALSE;
615 aEntry.nVal = SC_NONEMPTYFIELDS;
616 aEntry.eOp = SC_EQUAL;
617 break;
618 default:
619 rStrm.Ignore( 8 );
620 bIgnore = TRUE;
623 /* #i39464# conflict, if two conditions of one column are 'OR'ed,
624 and they follow conditions of other columns.
625 Example: Let A1 be a condition of column A, and B1 and B2
626 conditions of column B, connected with OR. Excel performs
627 'A1 AND (B1 OR B2)' in this case, but Calc would do
628 '(A1 AND B1) OR B2' instead. */
629 if( (nFirstEmpty > 1) && nE && (eConn == SC_OR) && !bIgnore )
630 bHasConflict = TRUE;
631 if( !bHasConflict && !bIgnore )
633 aEntry.bDoQuery = TRUE;
634 aEntry.bQueryByString = TRUE;
635 aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
636 aEntry.eConnect = nE ? eConn : SC_AND;
637 nFirstEmpty++;
640 else
641 rStrm.Ignore( 10 );
644 for( nE = 0; nE < 2; nE++ )
645 if( nStrLen[ nE ] && pQueryEntries[ nE ] )
647 pQueryEntries[ nE ]->pStr->Assign ( rStrm.ReadUniString( nStrLen[ nE ] ) );
648 ExcelQueryToOooQuery( *pQueryEntries[ nE ] );
654 void XclImpAutoFilterData::SetAdvancedRange( const ScRange* pRange )
656 if (pRange)
658 aCriteriaRange = *pRange;
659 bCriteria = TRUE;
661 else
662 bCriteria = FALSE;
665 void XclImpAutoFilterData::SetExtractPos( const ScAddress& rAddr )
667 aParam.nDestCol = rAddr.Col();
668 aParam.nDestRow = rAddr.Row();
669 aParam.nDestTab = rAddr.Tab();
670 aParam.bInplace = FALSE;
671 aParam.bDestPers = TRUE;
674 void XclImpAutoFilterData::Apply( const BOOL bUseUnNamed )
676 CreateScDBData(bUseUnNamed);
678 if( bActive )
680 InsertQueryParam();
682 // #i38093# rows hidden by filter need extra flag, but CR_FILTERED is not set here yet
683 // SCROW nRow1 = StartRow();
684 // SCROW nRow2 = EndRow();
685 // size_t nRows = nRow2 - nRow1 + 1;
686 // boost::scoped_array<BYTE> pFlags( new BYTE[nRows]);
687 // pExcRoot->pDoc->GetRowFlagsArray( Tab()).FillDataArray( nRow1, nRow2,
688 // pFlags.get());
689 // for (size_t j=0; j<nRows; ++j)
690 // {
691 // if ((pFlags[j] & CR_HIDDEN) && !(pFlags[j] & CR_FILTERED))
692 // pExcRoot->pDoc->SetRowFlags( nRow1 + j, Tab(),
693 // pFlags[j] | CR_FILTERED );
694 // }
698 void XclImpAutoFilterData::CreateScDBData( const BOOL bUseUnNamed )
701 // Create the ScDBData() object if the AutoFilter is activated
702 // or if we need to create the Advanced Filter.
703 if( bActive || bCriteria)
705 ScDBCollection& rColl = pExcRoot->pIR->GetDatabaseRanges();
706 pCurrDBData = rColl.GetDBAtArea( Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
707 if( !pCurrDBData )
709 AmendAFName(bUseUnNamed);
711 pCurrDBData = new ScDBData( aFilterName, Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
713 if( pCurrDBData )
715 if(bCriteria)
717 EnableRemoveFilter();
719 pCurrDBData->SetQueryParam( aParam );
720 pCurrDBData->SetAdvancedQuerySource(&aCriteriaRange);
722 else
723 pCurrDBData->SetAdvancedQuerySource(NULL);
724 rColl.Insert( pCurrDBData );
731 void XclImpAutoFilterData::EnableRemoveFilter()
733 // only if this is a saved Advanced filter
734 if( !bActive && bAutoOrAdvanced )
736 ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
737 aEntry.bDoQuery = TRUE;
738 ++nFirstEmpty;
741 // TBD: force the automatic activation of the
742 // "Remove Filter" by setting a virtual mouse click
743 // inside the advanced range
746 void XclImpAutoFilterData::AmendAFName(const BOOL bUseUnNamed)
748 // If-and-only-if we have one AF filter then
749 // use the Calc "unnamed" range name. Calc
750 // only supports one in total while Excel
751 // supports one per sheet.
752 if( bUseUnNamed && bAutoOrAdvanced )
753 aFilterName = ScGlobal::GetRscString(STR_DB_NONAME);
756 XclImpAutoFilterBuffer::XclImpAutoFilterBuffer() :
757 nAFActiveCount( 0 )
761 XclImpAutoFilterBuffer::~XclImpAutoFilterBuffer()
763 for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
764 delete pData;
767 void XclImpAutoFilterBuffer::Insert( RootData* pRoot, const ScRange& rRange,
768 const String& rName )
770 if( !GetByTab( rRange.aStart.Tab() ) )
771 Append( new XclImpAutoFilterData( pRoot, rRange, rName ) );
774 void XclImpAutoFilterBuffer::AddAdvancedRange( const ScRange& rRange )
776 XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
777 if( pData )
778 pData->SetAdvancedRange( &rRange );
781 void XclImpAutoFilterBuffer::AddExtractPos( const ScRange& rRange )
783 XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
784 if( pData )
785 pData->SetExtractPos( rRange.aStart );
788 void XclImpAutoFilterBuffer::Apply()
790 for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
791 pData->Apply(UseUnNamed());
794 XclImpAutoFilterData* XclImpAutoFilterBuffer::GetByTab( SCTAB nTab )
796 for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
797 if( pData->Tab() == nTab )
798 return pData;
799 return NULL;