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>
77 #include "document.hxx"
78 #include "patattr.hxx"
79 #include "docpool.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"
92 #include "xicontent.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)
126 pFormConv
= pExcRoot
->pFmlaConverter
= new ExcelToSc8( GetRoot() );
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 )
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
);
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
);
202 void ImportExcel8::Scenman( void )
209 aScenList
.SetLast( nLastDispl
);
213 void ImportExcel8::Scenario( void )
215 aScenList
.Append( new ExcScenario( aIn
, *pExcRoot
) );
219 void ImportExcel8::Labelsst( void )
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
)
241 String
aName( aIn
.ReadUniString() );
244 if( bWorkbookGlobals
)
246 GetExtDocOptions().GetDocSettings().maGlobCodeName
= aName
;
247 GetDoc().SetCodeName( aName
);
251 GetExtDocOptions().AppendCodeName( aName
);
252 GetDoc().SetCodeName( GetCurrScTab(), aName
);
258 void ImportExcel8::SheetProtection( void )
260 GetSheetProtectBuffer().ReadOptions( aIn
, GetCurrScTab() );
263 void ImportExcel8::ReadBasic( void )
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
)
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
);
288 GetObjectManager().SetOleNameOverrideInfo( aBasicImport
.ControlNameForObjectId() );
289 ScDocument
& rDoc
= GetDoc();
290 rDoc
.GetMacroManager()->InitUserFuncData();
291 // Fake ThisComponent being setup by Activate ( which is a view
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();
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
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();
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 //___________________________________________________________________
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() );
381 pData
->SetAutoOrAdvanced();
384 void ImportExcel8::AutoFilterInfo( void )
386 if( !pExcRoot
->pAutoFilterBuffer
) return;
388 XclImpAutoFilterData
* pData
= pExcRoot
->pAutoFilterBuffer
->GetByTab( GetCurrScTab() );
391 pData
->SetAdvancedRange( NULL
);
396 void ImportExcel8::AutoFilter( void )
398 if( !pExcRoot
->pAutoFilterBuffer
) return;
400 XclImpAutoFilterData
* pData
= pExcRoot
->pAutoFilterBuffer
->GetByTab( GetCurrScTab() );
402 pData
->ReadAutoFilter( aIn
);
407 XclImpAutoFilterData::XclImpAutoFilterData( RootData
* pRoot
, const ScRange
& rRange
, const String
& rName
) :
412 bHasConflict( FALSE
),
414 bAutoOrAdvanced(FALSE
),
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
)
449 BOOL bHasAdv
= pCurrDBData
->GetAdvancedQuerySource( aAdvRange
);
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
);
457 pCurrDBData
->SetAdvancedQuerySource( &aAdvRange
);
460 pCurrDBData
->SetAutoFilter( TRUE
);
466 static void ExcelQueryToOooQuery( ScQueryEntry
& rEntry
, ScQueryParam
& rParam
)
468 if( rEntry
.pStr
== NULL
)
470 if( rEntry
.eOp
!= SC_EQUAL
&& rEntry
.eOp
!= SC_NOT_EQUAL
)
472 xub_StrLen nLen
= rEntry
.pStr
->Len();
475 BOOL bRegExp
= FALSE
;
476 for( int i
= 0; i
< nLen
; ++i
) {
477 sal_Unicode c
= rEntry
.pStr
->GetChar( i
);
479 if( rEntry
.eOp
== SC_NOT_EQUAL
) {
481 rEntry
.eOp
= SC_DOES_NOT_CONTAIN
;
483 else if( rEntry
.eOp
== SC_DOES_NOT_CONTAIN
)
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
;
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 );
503 rParam
.bRegExp
= TRUE
;
504 for( int i
= 0; i
< nLen
; ++i
) {
505 sal_Unicode c
= rEntry
.pStr
->GetChar( i
);
508 rEntry
.pStr
->ReplaceAscii( i
, 1, ".*" );
513 rEntry
.pStr
->InsertAscii( "\\", i
);
518 rEntry
.pStr
->ReplaceAscii( i
, 1, "." );
526 void XclImpAutoFilterData::ReadAutoFilter( XclImpStream
& rStrm
)
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();
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
) );
557 UINT8 nE
, nType
, nOper
, nBoolErr
, nVal
;
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
;
573 rStrm
>> nType
>> nOper
;
576 case EXC_AFOPER_LESS
:
577 aEntry
.eOp
= SC_LESS
;
579 case EXC_AFOPER_EQUAL
:
580 aEntry
.eOp
= SC_EQUAL
;
582 case EXC_AFOPER_LESSEQUAL
:
583 aEntry
.eOp
= SC_LESS_EQUAL
;
585 case EXC_AFOPER_GREATER
:
586 aEntry
.eOp
= SC_GREATER
;
588 case EXC_AFOPER_NOTEQUAL
:
589 aEntry
.eOp
= SC_NOT_EQUAL
;
591 case EXC_AFOPER_GREATEREQUAL
:
592 aEntry
.eOp
= SC_GREATER_EQUAL
;
595 aEntry
.eOp
= SC_EQUAL
;
603 CreateFromDouble( *aEntry
.pStr
, XclTools::GetDoubleFromRK( nRK
) );
605 case EXC_AFTYPE_DOUBLE
:
607 CreateFromDouble( *aEntry
.pStr
, fVal
);
609 case EXC_AFTYPE_STRING
:
611 rStrm
>> nStrLen
[ nE
];
613 aEntry
.pStr
->Erase();
615 case EXC_AFTYPE_BOOLERR
:
616 rStrm
>> nBoolErr
>> nVal
;
618 aEntry
.pStr
->Assign( String::CreateFromInt32( (sal_Int32
) nVal
) );
619 bIgnore
= (BOOL
) nBoolErr
;
621 case EXC_AFTYPE_EMPTY
:
622 aEntry
.bQueryByString
= FALSE
;
623 aEntry
.nVal
= SC_EMPTYFIELDS
;
624 aEntry
.eOp
= SC_EQUAL
;
626 case EXC_AFTYPE_NOTEMPTY
:
627 aEntry
.bQueryByString
= FALSE
;
628 aEntry
.nVal
= SC_NONEMPTYFIELDS
;
629 aEntry
.eOp
= SC_EQUAL
;
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
)
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
;
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
)
669 aCriteriaRange
= *pRange
;
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
);
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,
700 // for (size_t j=0; j<nRows; ++j)
702 // if ((pFlags[j] & CR_HIDDEN) && !(pFlags[j] & CR_FILTERED))
703 // pExcRoot->pDoc->SetRowFlags( nRow1 + j, Tab(),
704 // pFlags[j] | CR_FILTERED );
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() );
720 AmendAFName(bUseUnNamed
);
722 pCurrDBData
= new ScDBData( aFilterName
, Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
728 EnableRemoveFilter();
730 pCurrDBData
->SetQueryParam( aParam
);
731 pCurrDBData
->SetAdvancedQuerySource(&aCriteriaRange
);
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
;
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() :
772 XclImpAutoFilterBuffer::~XclImpAutoFilterBuffer()
774 for( XclImpAutoFilterData
* pData
= _First(); pData
; pData
= _Next() )
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() );
789 pData
->SetAdvancedRange( &rRange
);
792 void XclImpAutoFilterBuffer::AddExtractPos( const ScRange
& rRange
)
794 XclImpAutoFilterData
* pData
= GetByTab( rRange
.aStart
.Tab() );
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
)