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>
21 #include <vcl/idle.hxx>
23 #include "uiitems.hxx"
24 #include "rangenam.hxx"
26 #include "reffact.hxx"
27 #include "viewdata.hxx"
28 #include "document.hxx"
30 #include "scresid.hxx"
32 #include "foptmgr.hxx"
34 #include "globstr.hrc"
37 #include "filtdlg.hxx"
38 #include <vcl/msgbox.hxx>
40 // DEFINE --------------------------------------------------------------------
42 #define ERRORBOX(rid) ScopedVclPtrInstance<MessageDialog>::Create(this, ScGlobal::GetRscString(rid))->Execute()
44 // class ScSpecialFilterDialog
46 ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings
* pB
, SfxChildWindow
* pCW
, vcl::Window
* pParent
,
47 const SfxItemSet
& rArgSet
)
49 : ScAnyRefDlg ( pB
, pCW
, pParent
, "AdvancedFilterDialog", "modules/scalc/ui/advancedfilterdialog.ui" ),
51 aStrUndefined ( SC_RESSTR(SCSTR_UNDEFINED
) ),
53 nWhichQuery ( rArgSet
.GetPool()->GetWhich( SID_QUERY
) ),
54 theQueryData ( static_cast<const ScQueryItem
&>(
55 rArgSet
.Get( nWhichQuery
)).GetQueryData() ),
59 pRefInputEdit ( NULL
),
60 bRefInputMode ( false ),
63 get(pLbFilterArea
,"lbfilterarea");
64 get(pEdFilterArea
,"edfilterarea");
65 pEdFilterArea
->SetReferences(this, get
<VclFrame
>("filterframe")->get_label_widget());
66 get(pRbFilterArea
,"rbfilterarea");
67 pRbFilterArea
->SetReferences(this, pEdFilterArea
);
69 get(pBtnRegExp
,"regexp");
70 get(pBtnHeader
,"header");
71 get(pBtnUnique
,"unique");
72 get(pBtnCopyResult
,"copyresult");
73 get(pLbCopyArea
,"lbcopyarea");
74 get(pEdCopyArea
,"edcopyarea");
75 pEdCopyArea
->SetReferences(this, pBtnCopyResult
);
76 get(pRbCopyArea
,"rbcopyarea");
77 pRbCopyArea
->SetReferences(this, pEdCopyArea
);
78 get(pBtnDestPers
,"destpers");
79 get(pFtDbAreaLabel
,"dbarealabel");
80 get(pFtDbArea
,"dbarea");
82 get(pBtnCancel
,"cancel");
83 get(pExpander
,"more");
86 pEdFilterArea
->GrabFocus();
88 // Hack: RefInput-Kontrolle
90 // FIXME: this is an abomination
91 pIdle
->SetPriority( SchedulerPriority::LOWEST
);
92 pIdle
->SetIdleHdl( LINK( this, ScSpecialFilterDlg
, TimeOutHdl
) );
95 pLbCopyArea
->SetAccessibleName(pBtnCopyResult
->GetText());
96 pEdCopyArea
->SetAccessibleName(pBtnCopyResult
->GetText());
99 ScSpecialFilterDlg::~ScSpecialFilterDlg()
104 void ScSpecialFilterDlg::dispose()
106 sal_uInt16 nEntries
= pLbFilterArea
->GetEntryCount();
109 for ( i
=1; i
<nEntries
; i
++ )
110 delete static_cast<OUString
*>(pLbFilterArea
->GetEntryData( i
));
117 // Hack: RefInput-Kontrolle
121 pLbFilterArea
.clear();
122 pEdFilterArea
.clear();
123 pRbFilterArea
.clear();
129 pBtnCopyResult
.clear();
133 pBtnDestPers
.clear();
134 pFtDbAreaLabel
.clear();
138 pRefInputEdit
.clear();
139 ScAnyRefDlg::dispose();
142 void ScSpecialFilterDlg::Init( const SfxItemSet
& rArgSet
)
144 const ScQueryItem
& rQueryItem
= static_cast<const ScQueryItem
&>(
145 rArgSet
.Get( nWhichQuery
));
147 pBtnOk
->SetClickHdl ( LINK( this, ScSpecialFilterDlg
, EndDlgHdl
) );
148 pBtnCancel
->SetClickHdl ( LINK( this, ScSpecialFilterDlg
, EndDlgHdl
) );
149 pLbFilterArea
->SetSelectHdl ( LINK( this, ScSpecialFilterDlg
, FilterAreaSelHdl
) );
150 pEdFilterArea
->SetModifyHdl ( LINK( this, ScSpecialFilterDlg
, FilterAreaModHdl
) );
152 pViewData
= rQueryItem
.GetViewData();
153 pDoc
= pViewData
? pViewData
->GetDocument() : NULL
;
155 pEdFilterArea
->SetText( EMPTY_OUSTRING
); // may be overwritten below
157 if ( pViewData
&& pDoc
)
159 if(pDoc
->GetChangeTrack()!=NULL
) pBtnCopyResult
->Disable();
161 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
162 pLbFilterArea
->Clear();
163 pLbFilterArea
->InsertEntry( aStrUndefined
, 0 );
165 if (!pRangeNames
->empty())
167 ScRangeName::const_iterator itr
= pRangeNames
->begin(), itrEnd
= pRangeNames
->end();
168 sal_uInt16 nInsert
= 0;
169 for (; itr
!= itrEnd
; ++itr
)
171 if (!itr
->second
->HasType(RT_CRITERIA
))
174 nInsert
= pLbFilterArea
->InsertEntry(itr
->second
->GetName());
176 itr
->second
->GetSymbol(aSymbol
);
177 pLbFilterArea
->SetEntryData(nInsert
, new OUString(aSymbol
));
181 // is there a stored source range?
184 if (rQueryItem
.GetAdvancedQuerySource(aAdvSource
))
186 OUString
aRefStr(aAdvSource
.Format(SCR_ABS_3D
, pDoc
, pDoc
->GetAddressConvention()));
187 pEdFilterArea
->SetRefString( aRefStr
);
191 pLbFilterArea
->SelectEntryPos( 0 );
193 // Optionen initialisieren lassen:
195 pOptionsMgr
= new ScFilterOptionsMgr(
211 // Spezialfilter braucht immer Spaltenkoepfe
212 pBtnHeader
->Check(true);
213 pBtnHeader
->Disable();
215 // Modal-Modus einschalten
216 // SetDispatcherLock( true );
217 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
218 //SFX_APPWINDOW->Disable(false); //! allgemeine Methode im ScAnyRefDlg
221 bool ScSpecialFilterDlg::Close()
224 pViewData
->GetDocShell()->CancelAutoDBRange();
226 return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
229 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
230 // neue Selektion im Referenz-Edit angezeigt wird.
232 void ScSpecialFilterDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
234 if ( bRefInputMode
&& pRefInputEdit
) // Nur moeglich, wenn im Referenz-Editmodus
236 if ( rRef
.aStart
!= rRef
.aEnd
)
237 RefInputStart( pRefInputEdit
);
240 const formula::FormulaGrammar::AddressConvention eConv
= pDocP
->GetAddressConvention();
242 if ( pRefInputEdit
== pEdCopyArea
)
243 aRefStr
= rRef
.aStart
.Format(SCA_ABS_3D
, pDocP
, eConv
);
244 else if ( pRefInputEdit
== pEdFilterArea
)
245 aRefStr
= rRef
.Format(SCR_ABS_3D
, pDocP
, eConv
);
247 pRefInputEdit
->SetRefString( aRefStr
);
251 void ScSpecialFilterDlg::SetActive()
255 if ( pRefInputEdit
== pEdCopyArea
)
257 pEdCopyArea
->GrabFocus();
258 if ( pEdCopyArea
->GetModifyHdl().IsSet() )
259 ((Link
<>&)pEdCopyArea
->GetModifyHdl()).Call( pEdCopyArea
);
261 else if ( pRefInputEdit
== pEdFilterArea
)
263 pEdFilterArea
->GrabFocus();
264 FilterAreaModHdl( pEdFilterArea
);
273 ScQueryItem
* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam
& rParam
,
274 const ScRange
& rSource
)
276 if ( pOutItem
) DELETEZ( pOutItem
);
277 pOutItem
= new ScQueryItem( nWhichQuery
, &rParam
);
278 pOutItem
->SetAdvancedQuerySource( &rSource
);
283 bool ScSpecialFilterDlg::IsRefInputMode() const
285 return bRefInputMode
;
290 IMPL_LINK( ScSpecialFilterDlg
, EndDlgHdl
, Button
*, pBtn
)
292 OSL_ENSURE( pDoc
&& pViewData
, "Document or ViewData not found. :-/" );
294 if ( (pBtn
== pBtnOk
) && pDoc
&& pViewData
)
296 OUString
theCopyStr( pEdCopyArea
->GetText() );
297 OUString
theAreaStr( pEdFilterArea
->GetText() );
298 ScQueryParam
theOutParam( theQueryData
);
299 ScAddress theAdrCopy
;
300 bool bEditInputOk
= true;
301 bool bQueryOk
= false;
302 ScRange theFilterArea
;
303 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
305 if ( pBtnCopyResult
->IsChecked() )
307 sal_Int32 nColonPos
= theCopyStr
.indexOf( ':' );
309 if ( -1 != nColonPos
)
310 theCopyStr
= theCopyStr
.copy( 0, nColonPos
);
312 sal_uInt16 nResult
= theAdrCopy
.Parse( theCopyStr
, pDoc
, eConv
);
314 if ( SCA_VALID
!= (nResult
& SCA_VALID
) )
316 if (!pExpander
->get_expanded())
317 pExpander
->set_expanded(true);
319 ERRORBOX( STR_INVALID_TABREF
);
320 pEdCopyArea
->GrabFocus();
321 bEditInputOk
= false;
327 sal_uInt16 nResult
= ScRange().Parse( theAreaStr
, pDoc
, eConv
);
329 if ( SCA_VALID
!= (nResult
& SCA_VALID
) )
331 ERRORBOX( STR_INVALID_TABREF
);
332 pEdFilterArea
->GrabFocus();
333 bEditInputOk
= false;
340 * Alle Edit-Felder enthalten gueltige Bereiche.
341 * Nun wird versucht aus dem Filterbereich
342 * ein ScQueryParam zu erzeugen:
345 sal_uInt16 nResult
= theFilterArea
.Parse( theAreaStr
, pDoc
, eConv
);
347 if ( SCA_VALID
== (nResult
& SCA_VALID
) )
349 ScAddress
& rStart
= theFilterArea
.aStart
;
350 ScAddress
& rEnd
= theFilterArea
.aEnd
;
352 if ( pBtnCopyResult
->IsChecked() )
354 theOutParam
.bInplace
= false;
355 theOutParam
.nDestTab
= theAdrCopy
.Tab();
356 theOutParam
.nDestCol
= theAdrCopy
.Col();
357 theOutParam
.nDestRow
= theAdrCopy
.Row();
361 theOutParam
.bInplace
= true;
362 theOutParam
.nDestTab
= 0;
363 theOutParam
.nDestCol
= 0;
364 theOutParam
.nDestRow
= 0;
367 theOutParam
.bHasHeader
= pBtnHeader
->IsChecked();
368 theOutParam
.bByRow
= true;
369 theOutParam
.bCaseSens
= pBtnCase
->IsChecked();
370 theOutParam
.bRegExp
= pBtnRegExp
->IsChecked();
371 theOutParam
.bDuplicate
= !pBtnUnique
->IsChecked();
372 theOutParam
.bDestPers
= pBtnDestPers
->IsChecked();
375 pDoc
->CreateQueryParam( rStart
.Col(),
386 SetDispatcherLock( false );
388 GetBindings().GetDispatcher()->Execute( FID_FILTER_OK
,
389 SfxCallMode::SLOT
| SfxCallMode::RECORD
,
390 GetOutputItem( theOutParam
, theFilterArea
), 0L, 0L );
395 ERRORBOX( STR_INVALID_QUERYAREA
);
396 pEdFilterArea
->GrabFocus();
399 else if ( pBtn
== pBtnCancel
)
406 IMPL_LINK_TYPED( ScSpecialFilterDlg
, TimeOutHdl
, Idle
*, _pIdle
, void )
408 // alle 50ms nachschauen, ob RefInputMode noch stimmt
410 if( (_pIdle
== pIdle
) && IsActive() )
412 if( pEdCopyArea
->HasFocus() || pRbCopyArea
->HasFocus() )
414 pRefInputEdit
= pEdCopyArea
;
415 bRefInputMode
= true;
417 else if( pEdFilterArea
->HasFocus() || pRbFilterArea
->HasFocus() )
419 pRefInputEdit
= pEdFilterArea
;
420 bRefInputMode
= true;
422 else if( bRefInputMode
)
424 pRefInputEdit
= NULL
;
425 bRefInputMode
= false;
432 IMPL_LINK( ScSpecialFilterDlg
, FilterAreaSelHdl
, ListBox
*, pLb
)
434 if ( pLb
== pLbFilterArea
)
437 sal_uInt16 nSelPos
= pLbFilterArea
->GetSelectEntryPos();
440 aString
= *static_cast<OUString
*>(pLbFilterArea
->GetEntryData( nSelPos
));
442 pEdFilterArea
->SetText( aString
);
448 IMPL_LINK( ScSpecialFilterDlg
, FilterAreaModHdl
, formula::RefEdit
*, pEd
)
450 if ( pEd
== pEdFilterArea
)
452 if ( pDoc
&& pViewData
)
454 OUString theCurAreaStr
= pEd
->GetText();
455 sal_uInt16 nResult
= ScRange().Parse( theCurAreaStr
, pDoc
);
457 if ( SCA_VALID
== (nResult
& SCA_VALID
) )
461 sal_uInt16 nCount
= pLbFilterArea
->GetEntryCount();
463 for ( i
=1; i
<nCount
&& !bFound
; i
++ )
465 OUString
* pStr
= static_cast<OUString
*>(pLbFilterArea
->GetEntryData( i
));
466 bFound
= (theCurAreaStr
== *pStr
);
470 pLbFilterArea
->SelectEntryPos( --i
);
472 pLbFilterArea
->SelectEntryPos( 0 );
476 pLbFilterArea
->SelectEntryPos( 0 );
482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */