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: sfiltdlg.cxx,v $
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 // System - Includes ---------------------------------------------------------
38 // INCLUDE -------------------------------------------------------------------
39 #include <sfx2/dispatch.hxx>
41 #include "uiitems.hxx"
42 #include "rangenam.hxx"
43 #include "dbcolect.hxx"
44 #include "reffact.hxx"
45 #include "viewdata.hxx"
46 #include "document.hxx"
48 #include "scresid.hxx"
50 #include "foptmgr.hxx"
52 #include "globstr.hrc"
56 #include "filtdlg.hxx"
58 #include <vcl/msgbox.hxx>
60 // DEFINE --------------------------------------------------------------------
62 #define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
63 ScGlobal::GetRscString(rid) ).Execute()
66 //============================================================================
67 // class ScSpecialFilterDialog
69 //----------------------------------------------------------------------------
71 ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings
* pB
, SfxChildWindow
* pCW
, Window
* pParent
,
72 const SfxItemSet
& rArgSet
)
74 : ScAnyRefDlg ( pB
, pCW
, pParent
, RID_SCDLG_SPEC_FILTER
),
76 aLbFilterArea ( this, ScResId( LB_CRITERIA_AREA
) ),
77 aFtFilterArea ( this, ScResId( FT_CRITERIA_AREA
) ),
78 aEdFilterArea ( this, this, ScResId( ED_CRITERIA_AREA
) ),
79 aRbFilterArea ( this, ScResId( RB_CRITERIA_AREA
), &aEdFilterArea
, this ),
81 aFlOptions ( this, ScResId( FL_OPTIONS
) ),
82 _INIT_COMMON_FILTER_RSCOBJS
83 aBtnOk ( this, ScResId( BTN_OK
) ),
84 aBtnCancel ( this, ScResId( BTN_CANCEL
) ),
85 aBtnHelp ( this, ScResId( BTN_HELP
) ),
86 aBtnMore ( this, ScResId( BTN_MORE
) ),
89 nWhichQuery ( rArgSet
.GetPool()->GetWhich( SID_QUERY
) ),
90 theQueryData ( ((const ScQueryItem
&)
91 rArgSet
.Get( nWhichQuery
)).GetQueryData() ),
95 pRefInputEdit ( NULL
),
96 bRefInputMode ( FALSE
),
100 aEdFilterArea
.GrabFocus();
104 // Hack: RefInput-Kontrolle
106 pTimer
->SetTimeout( 50 ); // 50ms warten
107 pTimer
->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg
, TimeOutHdl
) );
112 //----------------------------------------------------------------------------
114 __EXPORT
ScSpecialFilterDlg::~ScSpecialFilterDlg()
116 USHORT nEntries
= aLbFilterArea
.GetEntryCount();
119 for ( i
=1; i
<nEntries
; i
++ )
120 delete (String
*)aLbFilterArea
.GetEntryData( i
);
127 // Hack: RefInput-Kontrolle
133 //----------------------------------------------------------------------------
135 void __EXPORT
ScSpecialFilterDlg::Init( const SfxItemSet
& rArgSet
)
137 const ScQueryItem
& rQueryItem
= (const ScQueryItem
&)
138 rArgSet
.Get( nWhichQuery
);
140 aBtnOk
.SetClickHdl ( LINK( this, ScSpecialFilterDlg
, EndDlgHdl
) );
141 aBtnCancel
.SetClickHdl ( LINK( this, ScSpecialFilterDlg
, EndDlgHdl
) );
142 aLbFilterArea
.SetSelectHdl ( LINK( this, ScSpecialFilterDlg
, FilterAreaSelHdl
) );
143 aEdFilterArea
.SetModifyHdl ( LINK( this, ScSpecialFilterDlg
, FilterAreaModHdl
) );
145 pViewData
= rQueryItem
.GetViewData();
146 pDoc
= pViewData
? pViewData
->GetDocument() : NULL
;
148 aEdFilterArea
.SetText( EMPTY_STRING
); // may be overwritten below
150 if ( pViewData
&& pDoc
)
152 if(pDoc
->GetChangeTrack()!=NULL
) aBtnCopyResult
.Disable();
154 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
155 const USHORT nCount
= pRangeNames
? pRangeNames
->GetCount() : 0;
158 * Aus den RangeNames des Dokumentes werden nun die
159 * gemerkt, bei denen es sich um Filter-Bereiche handelt
162 aLbFilterArea
.Clear();
163 aLbFilterArea
.InsertEntry( aStrUndefined
, 0 );
168 ScRangeData
* pData
= NULL
;
171 for ( USHORT i
=0; i
<nCount
; i
++ )
173 pData
= (ScRangeData
*)(pRangeNames
->At( i
));
176 if ( pData
->HasType( RT_CRITERIA
) )
178 pData
->GetName( aString
);
179 nInsert
= aLbFilterArea
.InsertEntry( aString
);
180 pData
->GetSymbol( aString
);
181 aLbFilterArea
.SetEntryData( nInsert
,
182 new String( aString
) );
188 // is there a stored source range?
191 if (rQueryItem
.GetAdvancedQuerySource(aAdvSource
))
194 aAdvSource
.Format( aRefStr
, SCR_ABS_3D
, pDoc
, pDoc
->GetAddressConvention() );
195 aEdFilterArea
.SetRefString( aRefStr
);
199 aLbFilterArea
.SelectEntryPos( 0 );
201 // Optionen initialisieren lassen:
203 pOptionsMgr
= new ScFilterOptionsMgr(
223 // #35206# Spezialfilter braucht immer Spaltenkoepfe
224 aBtnHeader
.Check(TRUE
);
225 aBtnHeader
.Disable();
227 // Modal-Modus einschalten
228 // SetDispatcherLock( TRUE );
229 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
230 //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
234 //----------------------------------------------------------------------------
236 BOOL __EXPORT
ScSpecialFilterDlg::Close()
239 pViewData
->GetDocShell()->CancelAutoDBRange();
241 return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
245 //----------------------------------------------------------------------------
246 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
247 // neue Selektion im Referenz-Edit angezeigt wird.
249 void ScSpecialFilterDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
251 if ( bRefInputMode
&& pRefInputEdit
) // Nur moeglich, wenn im Referenz-Editmodus
253 if ( rRef
.aStart
!= rRef
.aEnd
)
254 RefInputStart( pRefInputEdit
);
257 const formula::FormulaGrammar::AddressConvention eConv
= pDocP
->GetAddressConvention();
259 if ( pRefInputEdit
== &aEdCopyArea
)
260 rRef
.aStart
.Format( aRefStr
, SCA_ABS_3D
, pDocP
, eConv
);
261 else if ( pRefInputEdit
== &aEdFilterArea
)
262 rRef
.Format( aRefStr
, SCR_ABS_3D
, pDocP
, eConv
);
264 pRefInputEdit
->SetRefString( aRefStr
);
269 //----------------------------------------------------------------------------
271 void ScSpecialFilterDlg::SetActive()
275 if ( pRefInputEdit
== &aEdCopyArea
)
277 aEdCopyArea
.GrabFocus();
278 if ( aEdCopyArea
.GetModifyHdl().IsSet() )
279 ((Link
&)aEdCopyArea
.GetModifyHdl()).Call( &aEdCopyArea
);
281 else if ( pRefInputEdit
== &aEdFilterArea
)
283 aEdFilterArea
.GrabFocus();
284 FilterAreaModHdl( &aEdFilterArea
);
294 //----------------------------------------------------------------------------
296 ScQueryItem
* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam
& rParam
,
297 const ScRange
& rSource
)
299 if ( pOutItem
) DELETEZ( pOutItem
);
300 pOutItem
= new ScQueryItem( nWhichQuery
, &rParam
);
301 pOutItem
->SetAdvancedQuerySource( &rSource
);
307 //----------------------------------------------------------------------------
309 BOOL
ScSpecialFilterDlg::IsRefInputMode() const
311 return bRefInputMode
;
315 //----------------------------------------------------------------------------
319 IMPL_LINK( ScSpecialFilterDlg
, EndDlgHdl
, Button
*, pBtn
)
321 DBG_ASSERT( pDoc
&& pViewData
, "Document or ViewData not found. :-/" );
323 if ( (pBtn
== &aBtnOk
) && pDoc
&& pViewData
)
325 String
theCopyStr( aEdCopyArea
.GetText() );
326 String
theAreaStr( aEdFilterArea
.GetText() );
327 ScQueryParam
theOutParam( theQueryData
);
328 ScAddress theAdrCopy
;
329 BOOL bEditInputOk
= TRUE
;
330 BOOL bQueryOk
= FALSE
;
331 ScRange theFilterArea
;
332 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
334 if ( aBtnCopyResult
.IsChecked() )
336 xub_StrLen nColonPos
= theCopyStr
.Search( ':' );
338 if ( STRING_NOTFOUND
!= nColonPos
)
339 theCopyStr
.Erase( nColonPos
);
341 USHORT nResult
= theAdrCopy
.Parse( theCopyStr
, pDoc
, eConv
);
343 if ( SCA_VALID
!= (nResult
& SCA_VALID
) )
345 if ( !aBtnMore
.GetState() )
346 aBtnMore
.SetState( TRUE
);
348 ERRORBOX( STR_INVALID_TABREF
);
349 aEdCopyArea
.GrabFocus();
350 bEditInputOk
= FALSE
;
356 USHORT nResult
= ScRange().Parse( theAreaStr
, pDoc
, eConv
);
358 if ( SCA_VALID
!= (nResult
& SCA_VALID
) )
360 ERRORBOX( STR_INVALID_TABREF
);
361 aEdFilterArea
.GrabFocus();
362 bEditInputOk
= FALSE
;
369 * Alle Edit-Felder enthalten gueltige Bereiche.
370 * Nun wird versucht aus dem Filterbereich
371 * ein ScQueryParam zu erzeugen:
374 USHORT nResult
= theFilterArea
.Parse( theAreaStr
, pDoc
, eConv
);
376 if ( SCA_VALID
== (nResult
& SCA_VALID
) )
378 ScAddress
& rStart
= theFilterArea
.aStart
;
379 ScAddress
& rEnd
= theFilterArea
.aEnd
;
381 if ( aBtnCopyResult
.IsChecked() )
383 theOutParam
.bInplace
= FALSE
;
384 theOutParam
.nDestTab
= theAdrCopy
.Tab();
385 theOutParam
.nDestCol
= theAdrCopy
.Col();
386 theOutParam
.nDestRow
= theAdrCopy
.Row();
390 theOutParam
.bInplace
= TRUE
;
391 theOutParam
.nDestTab
= 0;
392 theOutParam
.nDestCol
= 0;
393 theOutParam
.nDestRow
= 0;
396 theOutParam
.bHasHeader
= aBtnHeader
.IsChecked();
397 theOutParam
.bByRow
= TRUE
;
398 theOutParam
.bCaseSens
= aBtnCase
.IsChecked();
399 theOutParam
.bRegExp
= aBtnRegExp
.IsChecked();
400 theOutParam
.bDuplicate
= !aBtnUnique
.IsChecked();
401 theOutParam
.bDestPers
= aBtnDestPers
.IsChecked();
404 pDoc
->CreateQueryParam( rStart
.Col(),
411 // an der DB-Collection koennen nur MAXQUERY Filter-Eintraege
412 // gespeichert werden
414 if ( bQueryOk
&& theOutParam
.GetEntryCount() > MAXQUERY
&&
415 theOutParam
.GetEntry(MAXQUERY
).bDoQuery
)
417 bQueryOk
= FALSE
; // zu viele
418 //! andere Fehlermeldung ??
425 SetDispatcherLock( FALSE
);
427 GetBindings().GetDispatcher()->Execute( FID_FILTER_OK
,
428 SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
429 GetOutputItem( theOutParam
, theFilterArea
), 0L, 0L );
434 ERRORBOX( STR_INVALID_QUERYAREA
);
435 aEdFilterArea
.GrabFocus();
438 else if ( pBtn
== &aBtnCancel
)
446 //----------------------------------------------------------------------------
448 IMPL_LINK( ScSpecialFilterDlg
, TimeOutHdl
, Timer
*, _pTimer
)
450 // alle 50ms nachschauen, ob RefInputMode noch stimmt
452 if( (_pTimer
== pTimer
) && IsActive() )
454 if( aEdCopyArea
.HasFocus() || aRbCopyArea
.HasFocus() )
456 pRefInputEdit
= &aEdCopyArea
;
457 bRefInputMode
= TRUE
;
459 else if( aEdFilterArea
.HasFocus() || aRbFilterArea
.HasFocus() )
461 pRefInputEdit
= &aEdFilterArea
;
462 bRefInputMode
= TRUE
;
464 else if( bRefInputMode
)
466 pRefInputEdit
= NULL
;
467 bRefInputMode
= FALSE
;
477 //----------------------------------------------------------------------------
479 IMPL_LINK( ScSpecialFilterDlg
, FilterAreaSelHdl
, ListBox
*, pLb
)
481 if ( pLb
== &aLbFilterArea
)
484 USHORT nSelPos
= aLbFilterArea
.GetSelectEntryPos();
487 aString
= *(String
*)aLbFilterArea
.GetEntryData( nSelPos
);
489 aEdFilterArea
.SetText( aString
);
496 //----------------------------------------------------------------------------
498 IMPL_LINK( ScSpecialFilterDlg
, FilterAreaModHdl
, formula::RefEdit
*, pEd
)
500 if ( pEd
== &aEdFilterArea
)
502 if ( pDoc
&& pViewData
)
504 String theCurAreaStr
= pEd
->GetText();
505 USHORT nResult
= ScRange().Parse( theCurAreaStr
, pDoc
);
507 if ( SCA_VALID
== (nResult
& SCA_VALID
) )
512 USHORT nCount
= aLbFilterArea
.GetEntryCount();
514 for ( i
=1; i
<nCount
&& !bFound
; i
++ )
516 pStr
= (String
*)aLbFilterArea
.GetEntryData( i
);
517 bFound
= (theCurAreaStr
== *pStr
);
521 aLbFilterArea
.SelectEntryPos( --i
);
523 aLbFilterArea
.SelectEntryPos( 0 );
527 aLbFilterArea
.SelectEntryPos( 0 );