LibreOffice Module sc (master) 1
sfiltdlg.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sfx2/dispatch.hxx>
21
22#include <uiitems.hxx>
23#include <rangenam.hxx>
24#include <reffact.hxx>
25#include <viewdata.hxx>
26#include <document.hxx>
27#include <docsh.hxx>
28#include <scresid.hxx>
29
30#include <foptmgr.hxx>
31
32#include <globstr.hrc>
33#include <strings.hrc>
34
35#include <filtdlg.hxx>
36#include <vcl/svapp.hxx>
37#include <vcl/weld.hxx>
38
39// DEFINE --------------------------------------------------------------------
40
41namespace
42{
43 void ERRORBOX(weld::Window* pParent, TranslateId rid)
44 {
45 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
46 VclMessageType::Warning, VclButtonsType::Ok,
47 ScResId(rid)));
48 xBox->run();
49 }
50}
51
52
54 const SfxItemSet& rArgSet )
55
56 : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/advancedfilterdialog.ui", "AdvancedFilterDialog")
57 , aStrUndefined ( ScResId(SCSTR_UNDEFINED) )
58 , nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) )
59 , theQueryData ( static_cast<const ScQueryItem&>(
60 rArgSet.Get( nWhichQuery )).GetQueryData() )
61 , pViewData(nullptr)
62 , pDoc(nullptr)
63 , bRefInputMode(false)
64 , m_pRefInputEdit(nullptr)
65 , m_xLbFilterArea(m_xBuilder->weld_combo_box("lbfilterarea"))
66 , m_xEdFilterArea(new formula::RefEdit(m_xBuilder->weld_entry("edfilterarea")))
67 , m_xRbFilterArea(new formula::RefButton(m_xBuilder->weld_button("rbfilterarea")))
68 , m_xExpander(m_xBuilder->weld_expander("more"))
69 , m_xBtnCase(m_xBuilder->weld_check_button("case"))
70 , m_xBtnRegExp(m_xBuilder->weld_check_button("regexp"))
71 , m_xBtnHeader(m_xBuilder->weld_check_button("header"))
72 , m_xBtnUnique(m_xBuilder->weld_check_button("unique"))
73 , m_xBtnCopyResult(m_xBuilder->weld_check_button("copyresult"))
74 , m_xLbCopyArea(m_xBuilder->weld_combo_box("lbcopyarea"))
75 , m_xEdCopyArea(new formula::RefEdit(m_xBuilder->weld_entry("edcopyarea")))
76 , m_xRbCopyArea(new formula::RefButton(m_xBuilder->weld_button("rbcopyarea")))
77 , m_xBtnDestPers(m_xBuilder->weld_check_button("destpers"))
78 , m_xFtDbAreaLabel(m_xBuilder->weld_label("dbarealabel"))
79 , m_xFtDbArea(m_xBuilder->weld_label("dbarea"))
80 , m_xBtnOk(m_xBuilder->weld_button("ok"))
81 , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
82 , m_xFilterFrame(m_xBuilder->weld_frame("filterframe"))
83 , m_xFilterLabel(m_xFilterFrame->weld_label_widget())
84{
85 m_xEdFilterArea->SetReferences(this, m_xFilterLabel.get());
86 m_xRbFilterArea->SetReferences(this, m_xEdFilterArea.get());
87 m_xEdCopyArea->SetReferences(this, m_xFtDbAreaLabel.get());
88 m_xRbCopyArea->SetReferences(this, m_xEdCopyArea.get());
89
90 Init( rArgSet );
91
92 Link<formula::RefEdit&, void> aLinkEdit = LINK(this, ScSpecialFilterDlg, RefInputEditHdl);
93 Link<formula::RefButton&, void> aLinkButton = LINK(this, ScSpecialFilterDlg, RefInputButtonHdl);
94 m_xEdCopyArea->SetGetFocusHdl(aLinkEdit);
95 m_xRbCopyArea->SetGetFocusHdl(aLinkButton);
96 m_xEdFilterArea->SetGetFocusHdl(aLinkEdit);
97 m_xRbFilterArea->SetGetFocusHdl(aLinkButton);
98 m_xEdCopyArea->SetLoseFocusHdl(aLinkEdit);
99 m_xRbCopyArea->SetLoseFocusHdl(aLinkButton);
100 m_xEdFilterArea->SetLoseFocusHdl(aLinkEdit);
101 m_xRbFilterArea->SetLoseFocusHdl(aLinkButton);
102
103 m_xEdFilterArea->GrabFocus();
104}
105
107{
108 pOptionsMgr.reset();
109
110 pOutItem.reset();
111}
112
114{
115 const ScQueryItem& rQueryItem = static_cast<const ScQueryItem&>(
116 rArgSet.Get( nWhichQuery ));
117
118 m_xBtnOk->connect_clicked( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
119 m_xBtnCancel->connect_clicked( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
120 m_xLbFilterArea->connect_changed( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
121 m_xEdFilterArea->SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );
122
123 pViewData = rQueryItem.GetViewData();
124 pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
125
126 m_xEdFilterArea->SetText( OUString() ); // may be overwritten below
127
128 if ( pViewData && pDoc )
129 {
130 if(pDoc->GetChangeTrack()!=nullptr) m_xBtnCopyResult->set_sensitive(false);
131
132 ScRangeName* pRangeNames = pDoc->GetRangeName();
133 m_xLbFilterArea->clear();
134 m_xLbFilterArea->append_text(aStrUndefined);
135
136 for (const auto& rEntry : *pRangeNames)
137 {
138 if (!rEntry.second->HasType(ScRangeData::Type::Criteria))
139 continue;
140
141 OUString aSymbol = rEntry.second->GetSymbol();
142 m_xLbFilterArea->append(aSymbol, rEntry.second->GetName());
143 }
144
145 // is there a stored source range?
146
147 ScRange aAdvSource;
148 if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
149 {
150 OUString aRefStr(aAdvSource.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, pDoc->GetAddressConvention()));
151 m_xEdFilterArea->SetRefString( aRefStr );
152 }
153 }
154
155 m_xLbFilterArea->set_active( 0 );
156
157 // let options be initialized:
158
160 pViewData,
162 m_xBtnCase.get(),
163 m_xBtnRegExp.get(),
164 m_xBtnHeader.get(),
165 m_xBtnUnique.get(),
166 m_xBtnCopyResult.get(),
167 m_xBtnDestPers.get(),
168 m_xLbCopyArea.get(),
169 m_xEdCopyArea.get(),
170 m_xRbCopyArea.get(),
171 m_xFtDbAreaLabel.get(),
172 m_xFtDbArea.get(),
173 aStrUndefined ) );
174
175 // special filter always needs column headers
176 m_xBtnHeader->set_active(true);
177 m_xBtnHeader->set_sensitive(false);
178
179 // turn on modal mode
180 // SetDispatcherLock( true );
181 //@BugID 54702 enable/disable in base class only
182 //SFX_APPWINDOW->Disable(false); //! general method in ScAnyRefDlg
183}
184
186{
187 if (pViewData)
189
190 DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
191}
192
193// Transfer of a table area selected with the mouse, which is then displayed
194// as a new selection in the reference edit.
195
197{
198 if ( !(bRefInputMode && m_pRefInputEdit) ) // only possible if in the reference edit mode
199 return;
200
201 if ( rRef.aStart != rRef.aEnd )
203
204 OUString aRefStr;
206
207 if (m_pRefInputEdit == m_xEdCopyArea.get())
208 aRefStr = rRef.aStart.Format(ScRefFlags::ADDR_ABS_3D, &rDocP, eConv);
209 else if (m_pRefInputEdit == m_xEdFilterArea.get())
210 aRefStr = rRef.Format(rDocP, ScRefFlags::RANGE_ABS_3D, eConv);
211
212 m_pRefInputEdit->SetRefString( aRefStr );
213}
214
216{
217 if ( bRefInputMode )
218 {
219 if (m_pRefInputEdit == m_xEdCopyArea.get())
220 {
221 m_xEdCopyArea->GrabFocus();
222 m_xEdCopyArea->GetModifyHdl().Call( *m_xEdCopyArea );
223 }
224 else if (m_pRefInputEdit == m_xEdFilterArea.get())
225 {
226 m_xEdFilterArea->GrabFocus();
227 FilterAreaModHdl( *m_xEdFilterArea );
228 }
229 }
230 else
231 m_xDialog->grab_focus();
232
233 RefInputDone();
234}
235
237 const ScRange& rSource )
238{
239 pOutItem.reset(new ScQueryItem( nWhichQuery, &rParam ));
240 pOutItem->SetAdvancedQuerySource( &rSource );
241 return pOutItem.get();
242}
243
245{
246 return bRefInputMode;
247}
248
249// Handler:
250
252{
253 OSL_ENSURE( pDoc && pViewData, "Document or ViewData not found. :-/" );
254
255 if (&rBtn == m_xBtnOk.get() && pDoc && pViewData)
256 {
257 OUString theCopyStr( m_xEdCopyArea->GetText() );
258 OUString theAreaStr( m_xEdFilterArea->GetText() );
259 ScQueryParam theOutParam( theQueryData );
260 ScAddress theAdrCopy;
261 bool bEditInputOk = true;
262 bool bQueryOk = false;
263 ScRange theFilterArea;
264 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
265
266 if ( m_xBtnCopyResult->get_active() )
267 {
268 sal_Int32 nColonPos = theCopyStr.indexOf( ':' );
269
270 if ( -1 != nColonPos )
271 theCopyStr = theCopyStr.copy( 0, nColonPos );
272
273 ScRefFlags nResult = theAdrCopy.Parse( theCopyStr, *pDoc, eConv );
274
275 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::ZERO )
276 {
277 if (!m_xExpander->get_expanded())
278 m_xExpander->set_expanded(true);
279
280 ERRORBOX(m_xDialog.get(), STR_INVALID_TABREF);
281 m_xEdCopyArea->GrabFocus();
282 bEditInputOk = false;
283 }
284 }
285
286 if ( bEditInputOk )
287 {
288 ScRefFlags nResult = ScRange().Parse( theAreaStr, *pDoc, eConv );
289
290 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::ZERO )
291 {
292 ERRORBOX(m_xDialog.get(), STR_INVALID_TABREF);
293 m_xEdFilterArea->GrabFocus();
294 bEditInputOk = false;
295 }
296 }
297
298 if ( bEditInputOk )
299 {
300 /*
301 * All edit fields contain valid areas. Now try to create
302 * a ScQueryParam from the filter area:
303 */
304
305 ScRefFlags nResult = theFilterArea.Parse( theAreaStr, *pDoc, eConv );
306
307 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
308 {
309 ScAddress& rStart = theFilterArea.aStart;
310 ScAddress& rEnd = theFilterArea.aEnd;
311
312 if ( m_xBtnCopyResult->get_active() )
313 {
314 theOutParam.bInplace = false;
315 theOutParam.nDestTab = theAdrCopy.Tab();
316 theOutParam.nDestCol = theAdrCopy.Col();
317 theOutParam.nDestRow = theAdrCopy.Row();
318 }
319 else
320 {
321 theOutParam.bInplace = true;
322 theOutParam.nDestTab = 0;
323 theOutParam.nDestCol = 0;
324 theOutParam.nDestRow = 0;
325 }
326
327 theOutParam.bHasHeader = m_xBtnHeader->get_active();
328 theOutParam.bByRow = true;
329 theOutParam.bCaseSens = m_xBtnCase->get_active();
330 theOutParam.eSearchType = m_xBtnRegExp->get_active() ? utl::SearchParam::SearchType::Regexp :
332 theOutParam.bDuplicate = !m_xBtnUnique->get_active();
333 theOutParam.bDestPers = m_xBtnDestPers->get_active();
334
335 bQueryOk = pDoc->CreateQueryParam(ScRange(rStart,rEnd), theOutParam);
336 }
337 }
338
339 if ( bQueryOk )
340 {
341 SetDispatcherLock( false );
342 SwitchToDocument();
343 GetBindings().GetDispatcher()->ExecuteList(FID_FILTER_OK,
344 SfxCallMode::SLOT | SfxCallMode::RECORD,
345 { GetOutputItem(theOutParam, theFilterArea) });
346 response(RET_OK);
347 }
348 else
349 {
350 ERRORBOX(m_xDialog.get(), STR_INVALID_QUERYAREA);
351 m_xEdFilterArea->GrabFocus();
352 }
353 }
354 else if (&rBtn == m_xBtnCancel.get())
355 {
356 response(RET_CANCEL);
357 }
358}
359
361{
362 RefInputHdl();
363}
364
366{
367 RefInputHdl();
368}
369
371{
372 if (!m_xDialog->has_toplevel_focus())
373 return;
374
375 if( m_xEdCopyArea->GetWidget()->has_focus() || m_xRbCopyArea->GetWidget()->has_focus() )
376 {
378 bRefInputMode = true;
379 }
380 else if( m_xEdFilterArea->GetWidget()->has_focus() || m_xRbFilterArea->GetWidget()->has_focus() )
381 {
383 bRefInputMode = true;
384 }
385 else if( bRefInputMode )
386 {
387 m_pRefInputEdit = nullptr;
388 bRefInputMode = false;
389 }
390}
391
392IMPL_LINK(ScSpecialFilterDlg, FilterAreaSelHdl, weld::ComboBox&, rLb, void)
393{
394 if (&rLb == m_xLbFilterArea.get())
395 {
396 OUString aString;
397 const sal_Int32 nSelPos = m_xLbFilterArea->get_active();
398
399 if ( nSelPos > 0 )
400 aString = m_xLbFilterArea->get_id(nSelPos);
401
402 m_xEdFilterArea->SetText( aString );
403 }
404}
405
406IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit&, rEd, void )
407{
408 if (&rEd != m_xEdFilterArea.get())
409 return;
410
411 if ( pDoc && pViewData )
412 {
413 OUString theCurAreaStr = rEd.GetText();
414 ScRefFlags nResult = ScRange().Parse( theCurAreaStr, *pDoc );
415
416 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
417 {
418 const sal_Int32 nCount = m_xLbFilterArea->get_count();
419 for (sal_Int32 i = 1; i < nCount; ++i)
420 {
421 OUString aStr = m_xLbFilterArea->get_id(i);
422 if (theCurAreaStr == aStr)
423 {
424 m_xLbFilterArea->set_active( i );
425 return;
426 }
427 }
428 m_xLbFilterArea->set_active( 0 );
429 }
430 }
431 else
432 m_xLbFilterArea->set_active( 0 );
433}
434
435/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScRefFlags
Definition: address.hxx:158
Reference< XExecutableDialog > m_xDialog
#define GetWhich(nSlot)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
SCTAB Tab() const
Definition: address.hxx:283
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1537
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
void CancelAutoDBRange()
Definition: docsh5.cxx:368
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:500
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:174
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2487
ScViewData * GetViewData() const
Definition: uiitems.hxx:162
bool GetAdvancedQuerySource(ScRange &rSource) const
Definition: uiitems.cxx:220
OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2170
ScAddress aEnd
Definition: address.hxx:498
ScRefFlags Parse(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, ScAddress::ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1700
ScAddress aStart
Definition: address.hxx:497
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:749
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:779
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:718
virtual bool IsRefInputMode() const override
Definition: sfiltdlg.cxx:244
std::unique_ptr< formula::RefEdit > m_xEdFilterArea
Definition: filtdlg.hxx:206
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: filtdlg.hxx:223
ScQueryItem * GetOutputItem(const ScQueryParam &rParam, const ScRange &rSource)
Definition: sfiltdlg.cxx:236
std::unique_ptr< weld::ComboBox > m_xLbCopyArea
Definition: filtdlg.hxx:215
std::unique_ptr< formula::RefButton > m_xRbFilterArea
Definition: filtdlg.hxx:207
virtual void Close() override
Definition: sfiltdlg.cxx:185
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: sfiltdlg.cxx:196
void Init(const SfxItemSet &rArgSet)
Definition: sfiltdlg.cxx:113
virtual void SetActive() override
Definition: sfiltdlg.cxx:215
std::unique_ptr< ScQueryItem > pOutItem
Definition: filtdlg.hxx:197
std::unique_ptr< formula::RefButton > m_xRbCopyArea
Definition: filtdlg.hxx:217
std::unique_ptr< weld::ComboBox > m_xLbFilterArea
Definition: filtdlg.hxx:205
const ScQueryParam theQueryData
Definition: filtdlg.hxx:196
ScSpecialFilterDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, const SfxItemSet &rArgSet)
Definition: sfiltdlg.cxx:53
std::unique_ptr< formula::RefEdit > m_xEdCopyArea
Definition: filtdlg.hxx:216
std::unique_ptr< weld::Label > m_xFtDbAreaLabel
Definition: filtdlg.hxx:219
std::unique_ptr< weld::CheckButton > m_xBtnRegExp
Definition: filtdlg.hxx:211
ScViewData * pViewData
Definition: filtdlg.hxx:198
formula::RefEdit * m_pRefInputEdit
Definition: filtdlg.hxx:203
std::unique_ptr< weld::Label > m_xFtDbArea
Definition: filtdlg.hxx:220
std::unique_ptr< weld::CheckButton > m_xBtnUnique
Definition: filtdlg.hxx:213
const OUString aStrUndefined
Definition: filtdlg.hxx:191
std::unique_ptr< weld::Button > m_xBtnOk
Definition: filtdlg.hxx:222
std::unique_ptr< ScFilterOptionsMgr > pOptionsMgr
Definition: filtdlg.hxx:193
std::unique_ptr< weld::CheckButton > m_xBtnCopyResult
Definition: filtdlg.hxx:214
std::unique_ptr< weld::CheckButton > m_xBtnDestPers
Definition: filtdlg.hxx:218
virtual ~ScSpecialFilterDlg() override
Definition: sfiltdlg.cxx:106
std::unique_ptr< weld::CheckButton > m_xBtnCase
Definition: filtdlg.hxx:210
ScDocument * pDoc
Definition: filtdlg.hxx:199
const sal_uInt16 nWhichQuery
Definition: filtdlg.hxx:195
std::unique_ptr< weld::Label > m_xFilterLabel
Definition: filtdlg.hxx:226
std::unique_ptr< weld::CheckButton > m_xBtnHeader
Definition: filtdlg.hxx:212
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
SfxDispatcher * GetDispatcher() const
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
void SetRefString(const OUString &rStr)
int nCount
virtual SfxBindings & GetBindings() override
aStr
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
int i
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
IMPL_LINK(ScSpecialFilterDlg, EndDlgHdl, weld::Button &, rBtn, void)
Definition: sfiltdlg.cxx:251
IMPL_LINK_NOARG(ScSpecialFilterDlg, RefInputEditHdl, formula::RefEdit &, void)
Definition: sfiltdlg.cxx:360
utl::SearchParam::SearchType eSearchType
Definition: queryparam.hxx:43
RET_OK
RET_CANCEL