1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/dispatch.hxx>
22 #include "uiitems.hxx"
23 #include "rangenam.hxx"
25 #include "reffact.hxx"
26 #include "viewdata.hxx"
27 #include "document.hxx"
29 #include "scresid.hxx"
31 #include "foptmgr.hxx"
33 #include "globstr.hrc"
37 #include "filtdlg.hxx"
39 #include <vcl/msgbox.hxx>
41 // DEFINE --------------------------------------------------------------------
43 #define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
44 ScGlobal::GetRscString(rid) ).Execute()
47 //============================================================================
48 // class ScSpecialFilterDialog
50 //----------------------------------------------------------------------------
52 ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings
* pB
, SfxChildWindow
* pCW
, Window
* pParent
,
53 const SfxItemSet
& rArgSet
)
55 : ScAnyRefDlg ( pB
, pCW
, pParent
, RID_SCDLG_SPEC_FILTER
),
57 aFtFilterArea ( this, ScResId( FT_CRITERIA_AREA
) ),
58 aLbFilterArea ( this, ScResId( LB_CRITERIA_AREA
) ),
59 aEdFilterArea ( this, this, &aFtFilterArea
, ScResId( ED_CRITERIA_AREA
) ),
60 aRbFilterArea ( this, ScResId( RB_CRITERIA_AREA
), &aEdFilterArea
, this ),
62 aFlOptions ( this, ScResId( FL_OPTIONS
) ),
63 aBtnCase ( this, ScResId( BTN_CASE
) ),
64 aBtnRegExp ( this, ScResId( BTN_REGEXP
) ),
65 aBtnHeader ( this, ScResId( BTN_HEADER
) ),
66 aBtnUnique ( this, ScResId( BTN_UNIQUE
) ),
67 aBtnCopyResult ( this, ScResId( BTN_COPY_RESULT
) ),
68 aLbCopyArea ( this, ScResId( LB_COPY_AREA
) ),
69 aEdCopyArea ( this, this, NULL
, ScResId( ED_COPY_AREA
) ),
70 aRbCopyArea ( this, ScResId( RB_COPY_AREA
), &aEdCopyArea
, this ),
71 aBtnDestPers ( this, ScResId( BTN_DEST_PERS
) ),
72 aFtDbAreaLabel ( this, ScResId( FT_DBAREA_LABEL
) ),
73 aFtDbArea ( this, ScResId( FT_DBAREA
) ),
74 aStrUndefined ( SC_RESSTR(SCSTR_UNDEFINED
) ),
75 aBtnOk ( this, ScResId( BTN_OK
) ),
76 aBtnCancel ( this, ScResId( BTN_CANCEL
) ),
77 aBtnHelp ( this, ScResId( BTN_HELP
) ),
78 aBtnMore ( this, ScResId( BTN_MORE
) ),
81 nWhichQuery ( rArgSet
.GetPool()->GetWhich( SID_QUERY
) ),
82 theQueryData ( ((const ScQueryItem
&)
83 rArgSet
.Get( nWhichQuery
)).GetQueryData() ),
87 pRefInputEdit ( NULL
),
88 bRefInputMode ( false ),
92 aEdFilterArea
.GrabFocus();
96 // Hack: RefInput-Kontrolle
98 pTimer
->SetTimeout( 50 ); // 50ms warten
99 pTimer
->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg
, TimeOutHdl
) );
102 aLbCopyArea
.SetAccessibleName(aBtnCopyResult
.GetText());
103 aEdCopyArea
.SetAccessibleName(aBtnCopyResult
.GetText());
104 aLbCopyArea
.SetAccessibleRelationLabeledBy(&aBtnCopyResult
);
105 aEdCopyArea
.SetAccessibleRelationLabeledBy(&aBtnCopyResult
);
109 //----------------------------------------------------------------------------
111 ScSpecialFilterDlg::~ScSpecialFilterDlg()
113 sal_uInt16 nEntries
= aLbFilterArea
.GetEntryCount();
116 for ( i
=1; i
<nEntries
; i
++ )
117 delete (String
*)aLbFilterArea
.GetEntryData( i
);
124 // Hack: RefInput-Kontrolle
130 //----------------------------------------------------------------------------
132 void ScSpecialFilterDlg::Init( const SfxItemSet
& rArgSet
)
134 const ScQueryItem
& rQueryItem
= (const ScQueryItem
&)
135 rArgSet
.Get( nWhichQuery
);
137 aBtnOk
.SetClickHdl ( LINK( this, ScSpecialFilterDlg
, EndDlgHdl
) );
138 aBtnCancel
.SetClickHdl ( LINK( this, ScSpecialFilterDlg
, EndDlgHdl
) );
139 aLbFilterArea
.SetSelectHdl ( LINK( this, ScSpecialFilterDlg
, FilterAreaSelHdl
) );
140 aEdFilterArea
.SetModifyHdl ( LINK( this, ScSpecialFilterDlg
, FilterAreaModHdl
) );
142 pViewData
= rQueryItem
.GetViewData();
143 pDoc
= pViewData
? pViewData
->GetDocument() : NULL
;
145 aEdFilterArea
.SetText( EMPTY_STRING
); // may be overwritten below
147 if ( pViewData
&& pDoc
)
149 if(pDoc
->GetChangeTrack()!=NULL
) aBtnCopyResult
.Disable();
151 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
152 aLbFilterArea
.Clear();
153 aLbFilterArea
.InsertEntry( aStrUndefined
, 0 );
155 if (!pRangeNames
->empty())
157 ScRangeName::const_iterator itr
= pRangeNames
->begin(), itrEnd
= pRangeNames
->end();
158 sal_uInt16 nInsert
= 0;
159 for (; itr
!= itrEnd
; ++itr
)
161 if (!itr
->second
->HasType(RT_CRITERIA
))
164 nInsert
= aLbFilterArea
.InsertEntry(itr
->second
->GetName());
166 itr
->second
->GetSymbol(aSymbol
);
167 aLbFilterArea
.SetEntryData(nInsert
, new String(aSymbol
));
171 // is there a stored source range?
174 if (rQueryItem
.GetAdvancedQuerySource(aAdvSource
))
177 aAdvSource
.Format( aRefStr
, SCR_ABS_3D
, pDoc
, pDoc
->GetAddressConvention() );
178 aEdFilterArea
.SetRefString( aRefStr
);
182 aLbFilterArea
.SelectEntryPos( 0 );
184 // Optionen initialisieren lassen:
186 pOptionsMgr
= new ScFilterOptionsMgr(
204 // Spezialfilter braucht immer Spaltenkoepfe
205 aBtnHeader
.Check(true);
206 aBtnHeader
.Disable();
208 // Modal-Modus einschalten
209 // SetDispatcherLock( true );
210 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
211 //SFX_APPWINDOW->Disable(false); //! allgemeine Methode im ScAnyRefDlg
215 //----------------------------------------------------------------------------
217 sal_Bool
ScSpecialFilterDlg::Close()
220 pViewData
->GetDocShell()->CancelAutoDBRange();
222 return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
226 //----------------------------------------------------------------------------
227 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
228 // neue Selektion im Referenz-Edit angezeigt wird.
230 void ScSpecialFilterDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
232 if ( bRefInputMode
&& pRefInputEdit
) // Nur moeglich, wenn im Referenz-Editmodus
234 if ( rRef
.aStart
!= rRef
.aEnd
)
235 RefInputStart( pRefInputEdit
);
238 const formula::FormulaGrammar::AddressConvention eConv
= pDocP
->GetAddressConvention();
240 if ( pRefInputEdit
== &aEdCopyArea
)
241 rRef
.aStart
.Format( aRefStr
, SCA_ABS_3D
, pDocP
, eConv
);
242 else if ( pRefInputEdit
== &aEdFilterArea
)
243 rRef
.Format( aRefStr
, SCR_ABS_3D
, pDocP
, eConv
);
245 pRefInputEdit
->SetRefString( aRefStr
);
250 //----------------------------------------------------------------------------
252 void ScSpecialFilterDlg::SetActive()
256 if ( pRefInputEdit
== &aEdCopyArea
)
258 aEdCopyArea
.GrabFocus();
259 if ( aEdCopyArea
.GetModifyHdl().IsSet() )
260 ((Link
&)aEdCopyArea
.GetModifyHdl()).Call( &aEdCopyArea
);
262 else if ( pRefInputEdit
== &aEdFilterArea
)
264 aEdFilterArea
.GrabFocus();
265 FilterAreaModHdl( &aEdFilterArea
);
275 //----------------------------------------------------------------------------
277 ScQueryItem
* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam
& rParam
,
278 const ScRange
& rSource
)
280 if ( pOutItem
) DELETEZ( pOutItem
);
281 pOutItem
= new ScQueryItem( nWhichQuery
, &rParam
);
282 pOutItem
->SetAdvancedQuerySource( &rSource
);
288 //----------------------------------------------------------------------------
290 sal_Bool
ScSpecialFilterDlg::IsRefInputMode() const
292 return bRefInputMode
;
296 //----------------------------------------------------------------------------
300 IMPL_LINK( ScSpecialFilterDlg
, EndDlgHdl
, Button
*, pBtn
)
302 OSL_ENSURE( pDoc
&& pViewData
, "Document or ViewData not found. :-/" );
304 if ( (pBtn
== &aBtnOk
) && pDoc
&& pViewData
)
306 String
theCopyStr( aEdCopyArea
.GetText() );
307 String
theAreaStr( aEdFilterArea
.GetText() );
308 ScQueryParam
theOutParam( theQueryData
);
309 ScAddress theAdrCopy
;
310 sal_Bool bEditInputOk
= true;
311 sal_Bool bQueryOk
= false;
312 ScRange theFilterArea
;
313 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
315 if ( aBtnCopyResult
.IsChecked() )
317 xub_StrLen nColonPos
= theCopyStr
.Search( ':' );
319 if ( STRING_NOTFOUND
!= nColonPos
)
320 theCopyStr
.Erase( nColonPos
);
322 sal_uInt16 nResult
= theAdrCopy
.Parse( theCopyStr
, pDoc
, eConv
);
324 if ( SCA_VALID
!= (nResult
& SCA_VALID
) )
326 if ( !aBtnMore
.GetState() )
327 aBtnMore
.SetState( true );
329 ERRORBOX( STR_INVALID_TABREF
);
330 aEdCopyArea
.GrabFocus();
331 bEditInputOk
= false;
337 sal_uInt16 nResult
= ScRange().Parse( theAreaStr
, pDoc
, eConv
);
339 if ( SCA_VALID
!= (nResult
& SCA_VALID
) )
341 ERRORBOX( STR_INVALID_TABREF
);
342 aEdFilterArea
.GrabFocus();
343 bEditInputOk
= false;
350 * Alle Edit-Felder enthalten gueltige Bereiche.
351 * Nun wird versucht aus dem Filterbereich
352 * ein ScQueryParam zu erzeugen:
355 sal_uInt16 nResult
= theFilterArea
.Parse( theAreaStr
, pDoc
, eConv
);
357 if ( SCA_VALID
== (nResult
& SCA_VALID
) )
359 ScAddress
& rStart
= theFilterArea
.aStart
;
360 ScAddress
& rEnd
= theFilterArea
.aEnd
;
362 if ( aBtnCopyResult
.IsChecked() )
364 theOutParam
.bInplace
= false;
365 theOutParam
.nDestTab
= theAdrCopy
.Tab();
366 theOutParam
.nDestCol
= theAdrCopy
.Col();
367 theOutParam
.nDestRow
= theAdrCopy
.Row();
371 theOutParam
.bInplace
= true;
372 theOutParam
.nDestTab
= 0;
373 theOutParam
.nDestCol
= 0;
374 theOutParam
.nDestRow
= 0;
377 theOutParam
.bHasHeader
= aBtnHeader
.IsChecked();
378 theOutParam
.bByRow
= true;
379 theOutParam
.bCaseSens
= aBtnCase
.IsChecked();
380 theOutParam
.bRegExp
= aBtnRegExp
.IsChecked();
381 theOutParam
.bDuplicate
= !aBtnUnique
.IsChecked();
382 theOutParam
.bDestPers
= aBtnDestPers
.IsChecked();
385 pDoc
->CreateQueryParam( rStart
.Col(),
396 SetDispatcherLock( false );
398 GetBindings().GetDispatcher()->Execute( FID_FILTER_OK
,
399 SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
400 GetOutputItem( theOutParam
, theFilterArea
), 0L, 0L );
405 ERRORBOX( STR_INVALID_QUERYAREA
);
406 aEdFilterArea
.GrabFocus();
409 else if ( pBtn
== &aBtnCancel
)
417 //----------------------------------------------------------------------------
419 IMPL_LINK( ScSpecialFilterDlg
, TimeOutHdl
, Timer
*, _pTimer
)
421 // alle 50ms nachschauen, ob RefInputMode noch stimmt
423 if( (_pTimer
== pTimer
) && IsActive() )
425 if( aEdCopyArea
.HasFocus() || aRbCopyArea
.HasFocus() )
427 pRefInputEdit
= &aEdCopyArea
;
428 bRefInputMode
= true;
430 else if( aEdFilterArea
.HasFocus() || aRbFilterArea
.HasFocus() )
432 pRefInputEdit
= &aEdFilterArea
;
433 bRefInputMode
= true;
435 else if( bRefInputMode
)
437 pRefInputEdit
= NULL
;
438 bRefInputMode
= false;
448 //----------------------------------------------------------------------------
450 IMPL_LINK( ScSpecialFilterDlg
, FilterAreaSelHdl
, ListBox
*, pLb
)
452 if ( pLb
== &aLbFilterArea
)
455 sal_uInt16 nSelPos
= aLbFilterArea
.GetSelectEntryPos();
458 aString
= *(String
*)aLbFilterArea
.GetEntryData( nSelPos
);
460 aEdFilterArea
.SetText( aString
);
467 //----------------------------------------------------------------------------
469 IMPL_LINK( ScSpecialFilterDlg
, FilterAreaModHdl
, formula::RefEdit
*, pEd
)
471 if ( pEd
== &aEdFilterArea
)
473 if ( pDoc
&& pViewData
)
475 String theCurAreaStr
= pEd
->GetText();
476 sal_uInt16 nResult
= ScRange().Parse( theCurAreaStr
, pDoc
);
478 if ( SCA_VALID
== (nResult
& SCA_VALID
) )
481 sal_Bool bFound
= false;
483 sal_uInt16 nCount
= aLbFilterArea
.GetEntryCount();
485 for ( i
=1; i
<nCount
&& !bFound
; i
++ )
487 pStr
= (String
*)aLbFilterArea
.GetEntryData( i
);
488 bFound
= (theCurAreaStr
== *pStr
);
492 aLbFilterArea
.SelectEntryPos( --i
);
494 aLbFilterArea
.SelectEntryPos( 0 );
498 aLbFilterArea
.SelectEntryPos( 0 );
505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */