blob: 388c6c33640359f1a23922982f830185eaf47c9a [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
// System - Includes ---------------------------------------------------------
// INCLUDE -------------------------------------------------------------------
#include <sfx2/dispatch.hxx>
#include "uiitems.hxx"
#include "rangenam.hxx"
#include "dbcolect.hxx"
#include "reffact.hxx"
#include "viewdata.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "scresid.hxx"
#include "foptmgr.hxx"
#include "globstr.hrc"
#include "filter.hrc"
#define _SFILTDLG_CXX
#include "filtdlg.hxx"
#undef _SFILTDLG_CXX
#include <vcl/msgbox.hxx>
// DEFINE --------------------------------------------------------------------
#define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
ScGlobal::GetRscString(rid) ).Execute()
//============================================================================
// class ScSpecialFilterDialog
//----------------------------------------------------------------------------
ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
const SfxItemSet& rArgSet )
: ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SPEC_FILTER ),
//
aFtFilterArea ( this, ScResId( FT_CRITERIA_AREA ) ),
aLbFilterArea ( this, ScResId( LB_CRITERIA_AREA ) ),
aEdFilterArea ( this, this, ScResId( ED_CRITERIA_AREA ) ),
aRbFilterArea ( this, ScResId( RB_CRITERIA_AREA ), &aEdFilterArea, this ),
//
aFlOptions ( this, ScResId( FL_OPTIONS ) ),
_INIT_COMMON_FILTER_RSCOBJS
aBtnOk ( this, ScResId( BTN_OK ) ),
aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
aBtnHelp ( this, ScResId( BTN_HELP ) ),
aBtnMore ( this, ScResId( BTN_MORE ) ),
//
pOptionsMgr ( NULL ),
nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
theQueryData ( ((const ScQueryItem&)
rArgSet.Get( nWhichQuery )).GetQueryData() ),
pOutItem ( NULL ),
pViewData ( NULL ),
pDoc ( NULL ),
pRefInputEdit ( NULL ),
bRefInputMode ( sal_False ),
pTimer ( NULL )
{
Init( rArgSet );
aEdFilterArea.GrabFocus();
FreeResource();
// Hack: RefInput-Kontrolle
pTimer = new Timer;
pTimer->SetTimeout( 50 ); // 50ms warten
pTimer->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) );
pTimer->Start();
aLbCopyArea.SetAccessibleName(aBtnCopyResult.GetText());
aEdCopyArea.SetAccessibleName(aBtnCopyResult.GetText());
aLbCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
aEdCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
}
//----------------------------------------------------------------------------
__EXPORT ScSpecialFilterDlg::~ScSpecialFilterDlg()
{
sal_uInt16 nEntries = aLbFilterArea.GetEntryCount();
sal_uInt16 i;
for ( i=1; i<nEntries; i++ )
delete (String*)aLbFilterArea.GetEntryData( i );
delete pOptionsMgr;
if ( pOutItem )
delete pOutItem;
// Hack: RefInput-Kontrolle
pTimer->Stop();
delete pTimer;
}
//----------------------------------------------------------------------------
void __EXPORT ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
{
const ScQueryItem& rQueryItem = (const ScQueryItem&)
rArgSet.Get( nWhichQuery );
aBtnOk.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
aBtnCancel.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
aLbFilterArea.SetSelectHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
aEdFilterArea.SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );
pViewData = rQueryItem.GetViewData();
pDoc = pViewData ? pViewData->GetDocument() : NULL;
aEdFilterArea.SetText( EMPTY_STRING ); // may be overwritten below
if ( pViewData && pDoc )
{
if(pDoc->GetChangeTrack()!=NULL) aBtnCopyResult.Disable();
ScRangeName* pRangeNames = pDoc->GetRangeName();
const sal_uInt16 nCount = pRangeNames ? pRangeNames->GetCount() : 0;
/*
* Aus den RangeNames des Dokumentes werden nun die
* gemerkt, bei denen es sich um Filter-Bereiche handelt
*/
aLbFilterArea.Clear();
aLbFilterArea.InsertEntry( aStrUndefined, 0 );
if ( nCount > 0 )
{
String aString;
ScRangeData* pData = NULL;
sal_uInt16 nInsert = 0;
for ( sal_uInt16 i=0; i<nCount; i++ )
{
pData = (ScRangeData*)(pRangeNames->At( i ));
if ( pData )
{
if ( pData->HasType( RT_CRITERIA ) )
{
pData->GetName( aString );
nInsert = aLbFilterArea.InsertEntry( aString );
pData->GetSymbol( aString );
aLbFilterArea.SetEntryData( nInsert,
new String( aString ) );
}
}
}
}
// is there a stored source range?
ScRange aAdvSource;
if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
{
String aRefStr;
aAdvSource.Format( aRefStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
aEdFilterArea.SetRefString( aRefStr );
}
}
aLbFilterArea.SelectEntryPos( 0 );
// Optionen initialisieren lassen:
pOptionsMgr = new ScFilterOptionsMgr(
this,
pViewData,
theQueryData,
aBtnMore,
aBtnCase,
aBtnRegExp,
aBtnHeader,
aBtnUnique,
aBtnCopyResult,
aBtnDestPers,
aLbCopyArea,
aEdCopyArea,
aRbCopyArea,
aFtDbAreaLabel,
aFtDbArea,
aFlOptions,
aStrNoName,
aStrUndefined );
// #35206# Spezialfilter braucht immer Spaltenkoepfe
aBtnHeader.Check(sal_True);
aBtnHeader.Disable();
// Modal-Modus einschalten
// SetDispatcherLock( sal_True );
//@BugID 54702 Enablen/Disablen nur noch in Basisklasse
//SFX_APPWINDOW->Disable(sal_False); //! allgemeine Methode im ScAnyRefDlg
}
//----------------------------------------------------------------------------
sal_Bool __EXPORT ScSpecialFilterDlg::Close()
{
if (pViewData)
pViewData->GetDocShell()->CancelAutoDBRange();
return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
}
//----------------------------------------------------------------------------
// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
// neue Selektion im Referenz-Edit angezeigt wird.
void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
{
if ( bRefInputMode && pRefInputEdit ) // Nur moeglich, wenn im Referenz-Editmodus
{
if ( rRef.aStart != rRef.aEnd )
RefInputStart( pRefInputEdit );
String aRefStr;
const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
if ( pRefInputEdit == &aEdCopyArea)
rRef.aStart.Format( aRefStr, SCA_ABS_3D, pDocP, eConv );
else if ( pRefInputEdit == &aEdFilterArea)
rRef.Format( aRefStr, SCR_ABS_3D, pDocP, eConv );
pRefInputEdit->SetRefString( aRefStr );
}
}
//----------------------------------------------------------------------------
void ScSpecialFilterDlg::SetActive()
{
if ( bRefInputMode )
{
if ( pRefInputEdit == &aEdCopyArea )
{
aEdCopyArea.GrabFocus();
if ( aEdCopyArea.GetModifyHdl().IsSet() )
((Link&)aEdCopyArea.GetModifyHdl()).Call( &aEdCopyArea );
}
else if ( pRefInputEdit == &aEdFilterArea )
{
aEdFilterArea.GrabFocus();
FilterAreaModHdl( &aEdFilterArea );
}
}
else
GrabFocus();
RefInputDone();
}
//----------------------------------------------------------------------------
ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
const ScRange& rSource )
{
if ( pOutItem ) DELETEZ( pOutItem );
pOutItem = new ScQueryItem( nWhichQuery, &rParam );
pOutItem->SetAdvancedQuerySource( &rSource );
return pOutItem;
}
//----------------------------------------------------------------------------
sal_Bool ScSpecialFilterDlg::IsRefInputMode() const
{
return bRefInputMode;
}
//----------------------------------------------------------------------------
// Handler:
// ========
IMPL_LINK( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn )
{
DBG_ASSERT( pDoc && pViewData, "Document or ViewData not found. :-/" );
if ( (pBtn == &aBtnOk) && pDoc && pViewData )
{
String theCopyStr( aEdCopyArea.GetText() );
String theAreaStr( aEdFilterArea.GetText() );
ScQueryParam theOutParam( theQueryData );
ScAddress theAdrCopy;
sal_Bool bEditInputOk = sal_True;
sal_Bool bQueryOk = sal_False;
ScRange theFilterArea;
const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
if ( aBtnCopyResult.IsChecked() )
{
xub_StrLen nColonPos = theCopyStr.Search( ':' );
if ( STRING_NOTFOUND != nColonPos )
theCopyStr.Erase( nColonPos );
sal_uInt16 nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv );
if ( SCA_VALID != (nResult & SCA_VALID) )
{
if ( !aBtnMore.GetState() )
aBtnMore.SetState( sal_True );
ERRORBOX( STR_INVALID_TABREF );
aEdCopyArea.GrabFocus();
bEditInputOk = sal_False;
}
}
if ( bEditInputOk )
{
sal_uInt16 nResult = ScRange().Parse( theAreaStr, pDoc, eConv );
if ( SCA_VALID != (nResult & SCA_VALID) )
{
ERRORBOX( STR_INVALID_TABREF );
aEdFilterArea.GrabFocus();
bEditInputOk = sal_False;
}
}
if ( bEditInputOk )
{
/*
* Alle Edit-Felder enthalten gueltige Bereiche.
* Nun wird versucht aus dem Filterbereich
* ein ScQueryParam zu erzeugen:
*/
sal_uInt16 nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv );
if ( SCA_VALID == (nResult & SCA_VALID) )
{
ScAddress& rStart = theFilterArea.aStart;
ScAddress& rEnd = theFilterArea.aEnd;
if ( aBtnCopyResult.IsChecked() )
{
theOutParam.bInplace = sal_False;
theOutParam.nDestTab = theAdrCopy.Tab();
theOutParam.nDestCol = theAdrCopy.Col();
theOutParam.nDestRow = theAdrCopy.Row();
}
else
{
theOutParam.bInplace = sal_True;
theOutParam.nDestTab = 0;
theOutParam.nDestCol = 0;
theOutParam.nDestRow = 0;
}
theOutParam.bHasHeader = aBtnHeader.IsChecked();
theOutParam.bByRow = sal_True;
theOutParam.bCaseSens = aBtnCase.IsChecked();
theOutParam.bRegExp = aBtnRegExp.IsChecked();
theOutParam.bDuplicate = !aBtnUnique.IsChecked();
theOutParam.bDestPers = aBtnDestPers.IsChecked();
bQueryOk =
pDoc->CreateQueryParam( rStart.Col(),
rStart.Row(),
rEnd.Col(),
rEnd.Row(),
rStart.Tab(),
theOutParam );
// an der DB-Collection koennen nur MAXQUERY Filter-Eintraege
// gespeichert werden
if ( bQueryOk && theOutParam.GetEntryCount() > MAXQUERY &&
theOutParam.GetEntry(MAXQUERY).bDoQuery )
{
bQueryOk = sal_False; // zu viele
//! andere Fehlermeldung ??
}
}
}
if ( bQueryOk )
{
SetDispatcherLock( sal_False );
SwitchToDocument();
GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
GetOutputItem( theOutParam, theFilterArea ), 0L, 0L );
Close();
}
else
{
ERRORBOX( STR_INVALID_QUERYAREA );
aEdFilterArea.GrabFocus();
}
}
else if ( pBtn == &aBtnCancel )
{
Close();
}
return 0;
}
//----------------------------------------------------------------------------
IMPL_LINK( ScSpecialFilterDlg, TimeOutHdl, Timer*, _pTimer )
{
// alle 50ms nachschauen, ob RefInputMode noch stimmt
if( (_pTimer == pTimer) && IsActive() )
{
if( aEdCopyArea.HasFocus() || aRbCopyArea.HasFocus() )
{
pRefInputEdit = &aEdCopyArea;
bRefInputMode = sal_True;
}
else if( aEdFilterArea.HasFocus() || aRbFilterArea.HasFocus() )
{
pRefInputEdit = &aEdFilterArea;
bRefInputMode = sal_True;
}
else if( bRefInputMode )
{
pRefInputEdit = NULL;
bRefInputMode = sal_False;
}
}
pTimer->Start();
return 0;
}
//----------------------------------------------------------------------------
IMPL_LINK( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox*, pLb )
{
if ( pLb == &aLbFilterArea )
{
String aString;
sal_uInt16 nSelPos = aLbFilterArea.GetSelectEntryPos();
if ( nSelPos > 0 )
aString = *(String*)aLbFilterArea.GetEntryData( nSelPos );
aEdFilterArea.SetText( aString );
}
return 0;
}
//----------------------------------------------------------------------------
IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit*, pEd )
{
if ( pEd == &aEdFilterArea )
{
if ( pDoc && pViewData )
{
String theCurAreaStr = pEd->GetText();
sal_uInt16 nResult = ScRange().Parse( theCurAreaStr, pDoc );
if ( SCA_VALID == (nResult & SCA_VALID) )
{
String* pStr = NULL;
sal_Bool bFound = sal_False;
sal_uInt16 i = 0;
sal_uInt16 nCount = aLbFilterArea.GetEntryCount();
for ( i=1; i<nCount && !bFound; i++ )
{
pStr = (String*)aLbFilterArea.GetEntryData( i );
bFound = (theCurAreaStr == *pStr);
}
if ( bFound )
aLbFilterArea.SelectEntryPos( --i );
else
aLbFilterArea.SelectEntryPos( 0 );
}
}
else
aLbFilterArea.SelectEntryPos( 0 );
}
return 0;
}