tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / dbgui / sfiltdlg.cxx
blob33c1955e6e0dc9585b765571514fd315c12e9c2a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
24 #include <reffact.hxx>
25 #include <viewdata.hxx>
26 #include <document.hxx>
27 #include <docsh.hxx>
28 #include <scresid.hxx>
30 #include <foptmgr.hxx>
32 #include <globstr.hrc>
33 #include <strings.hrc>
35 #include <filtdlg.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/weld.hxx>
39 // DEFINE --------------------------------------------------------------------
41 namespace
43 void ERRORBOX(weld::Window* pParent, TranslateId rid)
45 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
46 VclMessageType::Warning, VclButtonsType::Ok,
47 ScResId(rid)));
48 xBox->run();
53 ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, weld::Window* pParent,
54 const SfxItemSet& rArgSet )
56 : ScAnyRefDlgController(pB, pCW, pParent, u"modules/scalc/ui/advancedfilterdialog.ui"_ustr, u"AdvancedFilterDialog"_ustr)
57 , aStrUndefined ( ScResId(SCSTR_UNDEFINED) )
58 , nWhichQuery ( rArgSet.GetPool()->GetWhichIDFromSlotID( 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(u"lbfilterarea"_ustr))
66 , m_xEdFilterArea(new formula::RefEdit(m_xBuilder->weld_entry(u"edfilterarea"_ustr)))
67 , m_xRbFilterArea(new formula::RefButton(m_xBuilder->weld_button(u"rbfilterarea"_ustr)))
68 , m_xExpander(m_xBuilder->weld_expander(u"more"_ustr))
69 , m_xBtnCase(m_xBuilder->weld_check_button(u"case"_ustr))
70 , m_xBtnRegExp(m_xBuilder->weld_check_button(u"regexp"_ustr))
71 , m_xBtnHeader(m_xBuilder->weld_check_button(u"header"_ustr))
72 , m_xBtnUnique(m_xBuilder->weld_check_button(u"unique"_ustr))
73 , m_xBtnCopyResult(m_xBuilder->weld_check_button(u"copyresult"_ustr))
74 , m_xLbCopyArea(m_xBuilder->weld_combo_box(u"lbcopyarea"_ustr))
75 , m_xEdCopyArea(new formula::RefEdit(m_xBuilder->weld_entry(u"edcopyarea"_ustr)))
76 , m_xRbCopyArea(new formula::RefButton(m_xBuilder->weld_button(u"rbcopyarea"_ustr)))
77 , m_xBtnDestPers(m_xBuilder->weld_check_button(u"destpers"_ustr))
78 , m_xFtDbAreaLabel(m_xBuilder->weld_label(u"dbarealabel"_ustr))
79 , m_xFtDbArea(m_xBuilder->weld_label(u"dbarea"_ustr))
80 , m_xBtnOk(m_xBuilder->weld_button(u"ok"_ustr))
81 , m_xBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr))
82 , m_xFilterFrame(m_xBuilder->weld_frame(u"filterframe"_ustr))
83 , m_xFilterLabel(m_xFilterFrame->weld_label_widget())
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());
90 Init( rArgSet );
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);
103 m_xEdFilterArea->GrabFocus();
106 ScSpecialFilterDlg::~ScSpecialFilterDlg()
108 pOptionsMgr.reset();
110 pOutItem.reset();
113 void ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
115 const ScQueryItem& rQueryItem = static_cast<const ScQueryItem&>(
116 rArgSet.Get( nWhichQuery ));
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 ) );
123 pViewData = rQueryItem.GetViewData();
124 pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
126 m_xEdFilterArea->SetText( OUString() ); // may be overwritten below
128 if ( pViewData && pDoc )
130 if(pDoc->GetChangeTrack()!=nullptr) m_xBtnCopyResult->set_sensitive(false);
132 ScRangeName* pRangeNames = pDoc->GetRangeName();
133 m_xLbFilterArea->clear();
134 m_xLbFilterArea->append_text(aStrUndefined);
136 for (const auto& rEntry : *pRangeNames)
138 if (!rEntry.second->HasType(ScRangeData::Type::Criteria))
139 continue;
141 OUString aSymbol = rEntry.second->GetSymbol();
142 m_xLbFilterArea->append(aSymbol, rEntry.second->GetName());
145 // is there a stored source range?
147 ScRange aAdvSource;
148 if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
150 OUString aRefStr(aAdvSource.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, pDoc->GetAddressConvention()));
151 m_xEdFilterArea->SetRefString( aRefStr );
155 m_xLbFilterArea->set_active( 0 );
157 // let options be initialized:
159 pOptionsMgr.reset( new ScFilterOptionsMgr(
160 pViewData,
161 theQueryData,
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 ) );
175 // special filter always needs column headers
176 m_xBtnHeader->set_active(true);
177 m_xBtnHeader->set_sensitive(false);
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
185 void ScSpecialFilterDlg::Close()
187 if (pViewData)
188 pViewData->GetDocShell()->CancelAutoDBRange();
190 DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
193 // Transfer of a table area selected with the mouse, which is then displayed
194 // as a new selection in the reference edit.
196 void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument& rDocP )
198 if ( !(bRefInputMode && m_pRefInputEdit) ) // only possible if in the reference edit mode
199 return;
201 if ( rRef.aStart != rRef.aEnd )
202 RefInputStart( m_pRefInputEdit );
204 OUString aRefStr;
205 const formula::FormulaGrammar::AddressConvention eConv = rDocP.GetAddressConvention();
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);
212 m_pRefInputEdit->SetRefString( aRefStr );
215 void ScSpecialFilterDlg::SetActive()
217 if ( bRefInputMode )
219 if (m_pRefInputEdit == m_xEdCopyArea.get())
221 m_xEdCopyArea->GrabFocus();
222 m_xEdCopyArea->GetModifyHdl().Call( *m_xEdCopyArea );
224 else if (m_pRefInputEdit == m_xEdFilterArea.get())
226 m_xEdFilterArea->GrabFocus();
227 FilterAreaModHdl( *m_xEdFilterArea );
230 else
231 m_xDialog->grab_focus();
233 RefInputDone();
236 ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
237 const ScRange& rSource )
239 pOutItem.reset(new ScQueryItem( nWhichQuery, &rParam ));
240 pOutItem->SetAdvancedQuerySource( &rSource );
241 return pOutItem.get();
244 bool ScSpecialFilterDlg::IsRefInputMode() const
246 return bRefInputMode;
249 // Handler:
251 IMPL_LINK(ScSpecialFilterDlg, EndDlgHdl, weld::Button&, rBtn, void)
253 OSL_ENSURE( pDoc && pViewData, "Document or ViewData not found. :-/" );
255 if (&rBtn == m_xBtnOk.get() && pDoc && pViewData)
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();
266 if ( m_xBtnCopyResult->get_active() )
268 sal_Int32 nColonPos = theCopyStr.indexOf( ':' );
270 if ( -1 != nColonPos )
271 theCopyStr = theCopyStr.copy( 0, nColonPos );
273 ScRefFlags nResult = theAdrCopy.Parse( theCopyStr, *pDoc, eConv );
275 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::ZERO )
277 if (!m_xExpander->get_expanded())
278 m_xExpander->set_expanded(true);
280 ERRORBOX(m_xDialog.get(), STR_INVALID_TABREF);
281 m_xEdCopyArea->GrabFocus();
282 bEditInputOk = false;
286 if ( bEditInputOk )
288 ScRefFlags nResult = ScRange().Parse( theAreaStr, *pDoc, eConv );
290 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::ZERO )
292 ERRORBOX(m_xDialog.get(), STR_INVALID_TABREF);
293 m_xEdFilterArea->GrabFocus();
294 bEditInputOk = false;
298 if ( bEditInputOk )
301 * All edit fields contain valid areas. Now try to create
302 * a ScQueryParam from the filter area:
305 ScRefFlags nResult = theFilterArea.Parse( theAreaStr, *pDoc, eConv );
307 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
309 ScAddress& rStart = theFilterArea.aStart;
310 ScAddress& rEnd = theFilterArea.aEnd;
312 if ( m_xBtnCopyResult->get_active() )
314 theOutParam.bInplace = false;
315 theOutParam.nDestTab = theAdrCopy.Tab();
316 theOutParam.nDestCol = theAdrCopy.Col();
317 theOutParam.nDestRow = theAdrCopy.Row();
319 else
321 theOutParam.bInplace = true;
322 theOutParam.nDestTab = 0;
323 theOutParam.nDestCol = 0;
324 theOutParam.nDestRow = 0;
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 :
331 utl::SearchParam::SearchType::Normal;
332 theOutParam.bDuplicate = !m_xBtnUnique->get_active();
333 theOutParam.bDestPers = m_xBtnDestPers->get_active();
335 bQueryOk = pDoc->CreateQueryParam(ScRange(rStart,rEnd), theOutParam);
339 if ( bQueryOk )
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);
348 else
350 ERRORBOX(m_xDialog.get(), STR_INVALID_QUERYAREA);
351 m_xEdFilterArea->GrabFocus();
354 else if (&rBtn == m_xBtnCancel.get())
356 response(RET_CANCEL);
360 IMPL_LINK_NOARG(ScSpecialFilterDlg, RefInputEditHdl, formula::RefEdit&, void)
362 RefInputHdl();
365 IMPL_LINK_NOARG(ScSpecialFilterDlg, RefInputButtonHdl, formula::RefButton&, void)
367 RefInputHdl();
370 void ScSpecialFilterDlg::RefInputHdl()
372 if (!m_xDialog->has_toplevel_focus())
373 return;
375 if( m_xEdCopyArea->GetWidget()->has_focus() || m_xRbCopyArea->GetWidget()->has_focus() )
377 m_pRefInputEdit = m_xEdCopyArea.get();
378 bRefInputMode = true;
380 else if( m_xEdFilterArea->GetWidget()->has_focus() || m_xRbFilterArea->GetWidget()->has_focus() )
382 m_pRefInputEdit = m_xEdFilterArea.get();
383 bRefInputMode = true;
385 else if( bRefInputMode )
387 m_pRefInputEdit = nullptr;
388 bRefInputMode = false;
392 IMPL_LINK(ScSpecialFilterDlg, FilterAreaSelHdl, weld::ComboBox&, rLb, void)
394 if (&rLb == m_xLbFilterArea.get())
396 OUString aString;
397 const sal_Int32 nSelPos = m_xLbFilterArea->get_active();
399 if ( nSelPos > 0 )
400 aString = m_xLbFilterArea->get_id(nSelPos);
402 m_xEdFilterArea->SetText( aString );
406 IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit&, rEd, void )
408 if (&rEd != m_xEdFilterArea.get())
409 return;
411 if ( pDoc && pViewData )
413 OUString theCurAreaStr = rEd.GetText();
414 ScRefFlags nResult = ScRange().Parse( theCurAreaStr, *pDoc );
416 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
418 const sal_Int32 nCount = m_xLbFilterArea->get_count();
419 for (sal_Int32 i = 1; i < nCount; ++i)
421 OUString aStr = m_xLbFilterArea->get_id(i);
422 if (theCurAreaStr == aStr)
424 m_xLbFilterArea->set_active( i );
425 return;
428 m_xLbFilterArea->set_active( 0 );
431 else
432 m_xLbFilterArea->set_active( 0 );
435 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */