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>
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)
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
);
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() )
315 if ( wrapper
.Read( xXCB
) )
318 wrapper
.Print( stderr
);
320 wrapper
.ImportCustomToolBar( *pShell
);
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
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();
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 //___________________________________________________________________
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() );
396 pData
->SetAutoOrAdvanced();
399 void ImportExcel8::AutoFilterInfo( void )
401 if( !pExcRoot
->pAutoFilterBuffer
) return;
403 XclImpAutoFilterData
* pData
= pExcRoot
->pAutoFilterBuffer
->GetByTab( GetCurrScTab() );
406 pData
->SetAdvancedRange( NULL
);
411 void ImportExcel8::AutoFilter( void )
413 if( !pExcRoot
->pAutoFilterBuffer
) return;
415 XclImpAutoFilterData
* pData
= pExcRoot
->pAutoFilterBuffer
->GetByTab( GetCurrScTab() );
417 pData
->ReadAutoFilter( aIn
);
422 XclImpAutoFilterData::XclImpAutoFilterData( RootData
* pRoot
, const ScRange
& rRange
, const String
& rName
) :
427 bHasConflict( FALSE
),
429 bAutoOrAdvanced(FALSE
),
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
)
464 BOOL bHasAdv
= pCurrDBData
->GetAdvancedQuerySource( aAdvRange
);
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
);
472 pCurrDBData
->SetAdvancedQuerySource( &aAdvRange
);
475 pCurrDBData
->SetAutoFilter( TRUE
);
481 static void ExcelQueryToOooQuery( ScQueryEntry
& rEntry
)
483 if( ( rEntry
.eOp
!= SC_EQUAL
&& rEntry
.eOp
!= SC_NOT_EQUAL
) || rEntry
.pStr
== NULL
)
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
)
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();
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
) );
544 UINT8 nE
, nType
, nOper
, nBoolErr
, nVal
;
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
;
560 rStrm
>> nType
>> nOper
;
563 case EXC_AFOPER_LESS
:
564 aEntry
.eOp
= SC_LESS
;
566 case EXC_AFOPER_EQUAL
:
567 aEntry
.eOp
= SC_EQUAL
;
569 case EXC_AFOPER_LESSEQUAL
:
570 aEntry
.eOp
= SC_LESS_EQUAL
;
572 case EXC_AFOPER_GREATER
:
573 aEntry
.eOp
= SC_GREATER
;
575 case EXC_AFOPER_NOTEQUAL
:
576 aEntry
.eOp
= SC_NOT_EQUAL
;
578 case EXC_AFOPER_GREATEREQUAL
:
579 aEntry
.eOp
= SC_GREATER_EQUAL
;
582 aEntry
.eOp
= SC_EQUAL
;
590 CreateFromDouble( *aEntry
.pStr
, XclTools::GetDoubleFromRK( nRK
) );
592 case EXC_AFTYPE_DOUBLE
:
594 CreateFromDouble( *aEntry
.pStr
, fVal
);
596 case EXC_AFTYPE_STRING
:
598 rStrm
>> nStrLen
[ nE
];
600 aEntry
.pStr
->Erase();
602 case EXC_AFTYPE_BOOLERR
:
603 rStrm
>> nBoolErr
>> nVal
;
605 aEntry
.pStr
->Assign( String::CreateFromInt32( (sal_Int32
) nVal
) );
606 bIgnore
= (BOOL
) nBoolErr
;
608 case EXC_AFTYPE_EMPTY
:
609 aEntry
.bQueryByString
= FALSE
;
610 aEntry
.nVal
= SC_EMPTYFIELDS
;
611 aEntry
.eOp
= SC_EQUAL
;
613 case EXC_AFTYPE_NOTEMPTY
:
614 aEntry
.bQueryByString
= FALSE
;
615 aEntry
.nVal
= SC_NONEMPTYFIELDS
;
616 aEntry
.eOp
= SC_EQUAL
;
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
)
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
;
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
)
658 aCriteriaRange
= *pRange
;
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
);
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,
689 // for (size_t j=0; j<nRows; ++j)
691 // if ((pFlags[j] & CR_HIDDEN) && !(pFlags[j] & CR_FILTERED))
692 // pExcRoot->pDoc->SetRowFlags( nRow1 + j, Tab(),
693 // pFlags[j] | CR_FILTERED );
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() );
709 AmendAFName(bUseUnNamed
);
711 pCurrDBData
= new ScDBData( aFilterName
, Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
717 EnableRemoveFilter();
719 pCurrDBData
->SetQueryParam( aParam
);
720 pCurrDBData
->SetAdvancedQuerySource(&aCriteriaRange
);
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
;
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() :
761 XclImpAutoFilterBuffer::~XclImpAutoFilterBuffer()
763 for( XclImpAutoFilterData
* pData
= _First(); pData
; pData
= _Next() )
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() );
778 pData
->SetAdvancedRange( &rRange
);
781 void XclImpAutoFilterBuffer::AddExtractPos( const ScRange
& rRange
)
783 XclImpAutoFilterData
* pData
= GetByTab( rRange
.aStart
.Tab() );
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
)