tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / dbaccess / source / ui / dlg / paramdialog.cxx
blob299ab845459468b864071c7103ab2c0aeedcb364
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 <core_resource.hxx>
21 #include <paramdialog.hxx>
22 #include <strings.hrc>
23 #include <strings.hxx>
24 #include <com/sun/star/util/NumberFormatter.hpp>
25 #include <comphelper/types.hxx>
26 #include <connectivity/dbtools.hxx>
27 #include <vcl/weld.hxx>
28 #include <o3tl/safeint.hxx>
29 #include <osl/diagnose.h>
30 #include <comphelper/diagnose_ex.hxx>
32 namespace dbaui
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::beans;
37 using namespace ::com::sun::star::container;
38 using namespace ::com::sun::star::sdbc;
39 using namespace ::com::sun::star::util;
41 // OParameterDialog
44 OParameterDialog::OParameterDialog(
45 weld::Window* pParent, const Reference< XIndexAccess > & rParamContainer,
46 const Reference< XConnection > & _rxConnection, const Reference< XComponentContext >& rxContext)
47 : GenericDialogController(pParent, u"dbaccess/ui/parametersdialog.ui"_ustr, u"Parameters"_ustr)
48 , m_nCurrentlySelected(-1)
49 , m_xConnection(_rxConnection)
50 , m_aPredicateInput( rxContext, _rxConnection, getParseContext() )
51 , m_aResetVisitFlag("dbaccess OParameterDialog m_aResetVisitFlag")
52 , m_xAllParams(m_xBuilder->weld_tree_view(u"allParamTreeview"_ustr))
53 , m_xParam(m_xBuilder->weld_entry(u"paramEntry"_ustr))
54 , m_xTravelNext(m_xBuilder->weld_button(u"next"_ustr))
55 , m_xOKBtn(m_xBuilder->weld_button(u"ok"_ustr))
56 , m_xCancelBtn(m_xBuilder->weld_button(u"cancel"_ustr))
58 m_xAllParams->set_size_request(-1, m_xAllParams->get_height_rows(10));
60 if (rxContext.is())
61 m_xFormatter.set( NumberFormatter::create( rxContext ), UNO_QUERY_THROW);
62 else {
63 OSL_FAIL("OParameterDialog::OParameterDialog: need a service factory!");
66 Reference< XNumberFormatsSupplier > xNumberFormats = ::dbtools::getNumberFormats(m_xConnection, true);
67 if (!xNumberFormats.is())
68 ::comphelper::disposeComponent(m_xFormatter);
69 else
70 m_xFormatter->attachNumberFormatsSupplier(xNumberFormats);
71 try
73 OSL_ENSURE(rParamContainer->getCount(), "OParameterDialog::OParameterDialog : can't handle empty containers !");
75 m_aFinalValues.realloc(rParamContainer->getCount());
76 PropertyValue* pValues = m_aFinalValues.getArray();
78 for (sal_Int32 i = 0, nCount = rParamContainer->getCount(); i<nCount; ++i, ++pValues)
80 Reference< XPropertySet > xParamAsSet;
81 rParamContainer->getByIndex(i) >>= xParamAsSet;
82 OSL_ENSURE(xParamAsSet.is(),"Parameter is null!");
83 if(!xParamAsSet.is())
84 continue;
85 pValues->Name = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
86 m_xAllParams->append_text(pValues->Name);
88 m_aVisitedParams.push_back(VisitFlags::NONE);
89 // not visited, not dirty
92 m_xParams = rParamContainer;
94 catch(Exception&)
96 DBG_UNHANDLED_EXCEPTION("dbaccess");
99 Construct();
101 m_aResetVisitFlag.SetInvokeHandler(LINK(this, OParameterDialog, OnVisitedTimeout));
104 OParameterDialog::~OParameterDialog()
106 if (m_aResetVisitFlag.IsActive())
107 m_aResetVisitFlag.Stop();
110 void OParameterDialog::Construct()
112 m_xAllParams->connect_selection_changed(
113 LINK(this, OParameterDialog, OnEntryListBoxSelected));
114 m_xParam->connect_focus_out(LINK(this, OParameterDialog, OnValueLoseFocusHdl));
115 m_xParam->connect_changed(LINK(this, OParameterDialog, OnValueModified));
116 m_xTravelNext->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
117 m_xOKBtn->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
118 m_xCancelBtn->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
120 if (m_xAllParams->n_children())
122 m_xAllParams->select(0);
123 OnEntrySelected();
125 if (m_xAllParams->n_children() == 1)
126 m_xTravelNext->set_sensitive(false);
128 if (m_xAllParams->n_children() > 1)
129 m_xDialog->change_default_widget(m_xOKBtn.get(), m_xTravelNext.get());
132 m_xParam->grab_focus();
135 IMPL_LINK_NOARG(OParameterDialog, OnValueLoseFocusHdl, weld::Widget&, void)
137 CheckValueForError();
140 bool OParameterDialog::CheckValueForError()
142 if (m_nCurrentlySelected != -1)
144 if ( !( m_aVisitedParams[ m_nCurrentlySelected ] & VisitFlags::Dirty ) )
145 // nothing to do, the value isn't dirty
146 return false;
149 bool bRet = false;
151 Reference< XPropertySet > xParamAsSet;
152 m_xParams->getByIndex(m_nCurrentlySelected) >>= xParamAsSet;
153 if (xParamAsSet.is())
155 if (m_xConnection.is() && m_xFormatter.is())
157 OUString sParamValue(m_xParam->get_text());
158 bool bValid = m_aPredicateInput.normalizePredicateString( sParamValue, xParamAsSet );
159 m_xParam->set_text(sParamValue);
160 m_xParam->set_message_type(bValid ? weld::EntryMessageType::Normal : weld::EntryMessageType::Error);
161 OUString sToolTip;
162 if ( bValid )
164 // with this the value isn't dirty anymore
165 if (m_nCurrentlySelected != -1)
166 m_aVisitedParams[m_nCurrentlySelected] &= ~VisitFlags::Dirty;
168 else
170 OUString sName;
173 sName = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
175 catch(Exception&)
177 DBG_UNHANDLED_EXCEPTION("dbaccess");
180 OUString sMessage(DBA_RES(STR_COULD_NOT_CONVERT_PARAM));
181 sToolTip = sMessage.replaceAll( "$name$", sName );
182 m_xParam->grab_focus();
183 bRet = true;
185 m_xParam->set_tooltip_text(sToolTip);
186 m_xOKBtn->set_sensitive(bValid);
190 return bRet;
193 IMPL_LINK(OParameterDialog, OnButtonClicked, weld::Button&, rButton, void)
195 if (m_xCancelBtn.get() == &rButton)
197 // no interpreting of the given values anymore...
198 m_xParam->connect_focus_out(Link<weld::Widget&, void>()); // no direct call from the control anymore ...
199 m_xDialog->response(RET_CANCEL);
201 else if (m_xOKBtn.get() == &rButton)
203 // transfer the current values into the Any
204 if (OnEntrySelected())
205 { // there was an error interpreting the current text
206 return;
209 if (m_xParams.is())
211 // write the parameters
214 PropertyValue* pValues = m_aFinalValues.getArray();
215 for (sal_Int32 i = 0, nCount = m_xParams->getCount(); i<nCount; ++i, ++pValues)
217 Reference< XPropertySet > xParamAsSet;
218 m_xParams->getByIndex(i) >>= xParamAsSet;
220 OUString sValue;
221 pValues->Value >>= sValue;
222 pValues->Value = m_aPredicateInput.getPredicateValue( sValue, xParamAsSet );
225 catch(Exception&)
227 DBG_UNHANDLED_EXCEPTION("dbaccess");
231 m_xDialog->response(RET_OK);
233 else if (m_xTravelNext.get() == &rButton)
235 if (sal_Int32 nCount = m_xAllParams->n_children())
237 sal_Int32 nCurrent = m_xAllParams->get_selected_index();
238 OSL_ENSURE(static_cast<size_t>(nCount) == m_aVisitedParams.size(), "OParameterDialog::OnButtonClicked : inconsistent lists !");
240 // search the next entry in list we haven't visited yet
241 sal_Int32 nNext = (nCurrent + 1) % nCount;
242 while ((nNext != nCurrent) && ( m_aVisitedParams[nNext] & VisitFlags::Visited ))
243 nNext = (nNext + 1) % nCount;
245 if ( m_aVisitedParams[nNext] & VisitFlags::Visited )
246 // there is no such "not visited yet" entry -> simply take the next one
247 nNext = (nCurrent + 1) % nCount;
249 m_xAllParams->select(nNext);
250 OnEntrySelected();
255 IMPL_LINK_NOARG(OParameterDialog, OnEntryListBoxSelected, weld::TreeView&, void)
257 OnEntrySelected();
260 bool OParameterDialog::OnEntrySelected()
262 if (m_aResetVisitFlag.IsActive())
264 LINK(this, OParameterDialog, OnVisitedTimeout).Call(&m_aResetVisitFlag);
265 m_aResetVisitFlag.Stop();
267 // save the old values
268 if (m_nCurrentlySelected != -1)
270 // do the transformation of the current text
271 if (CheckValueForError())
272 { // there was an error interpreting the text
273 m_xAllParams->select(m_nCurrentlySelected);
274 return true;
277 m_aFinalValues.getArray()[m_nCurrentlySelected].Value <<= m_xParam->get_text();
280 // initialize the controls with the new values
281 sal_Int32 nSelected = m_xAllParams->get_selected_index();
282 OSL_ENSURE(nSelected != -1, "OParameterDialog::OnEntrySelected : no current entry !");
284 m_xParam->set_text(::comphelper::getString(m_aFinalValues[nSelected].Value));
285 m_nCurrentlySelected = nSelected;
287 // with this the value isn't dirty
288 OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnEntrySelected : invalid current entry !");
289 m_aVisitedParams[m_nCurrentlySelected] &= ~VisitFlags::Dirty;
291 m_aResetVisitFlag.SetTimeout(1000);
292 m_aResetVisitFlag.Start();
294 return false;
297 IMPL_LINK_NOARG(OParameterDialog, OnVisitedTimeout, Timer*, void)
299 OSL_ENSURE(m_nCurrentlySelected != -1, "OParameterDialog::OnVisitedTimeout : invalid call !");
301 // mark the currently selected entry as visited
302 OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnVisitedTimeout : invalid entry !");
303 m_aVisitedParams[m_nCurrentlySelected] |= VisitFlags::Visited;
305 // was it the last "not visited yet" entry ?
306 bool bVisited = false;
307 for (auto const& visitedParam : m_aVisitedParams)
309 if (!(visitedParam & VisitFlags::Visited))
311 bVisited = true;
312 break;
316 if (!bVisited)
318 // yes, there isn't another one -> change the "default button"
319 m_xDialog->change_default_widget(m_xTravelNext.get(), m_xOKBtn.get());
323 IMPL_LINK(OParameterDialog, OnValueModified, weld::Entry&, rEdit, void)
325 // mark the currently selected entry as dirty
326 OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnValueModified : invalid entry !");
327 m_aVisitedParams[m_nCurrentlySelected] |= VisitFlags::Dirty;
328 rEdit.set_message_type(weld::EntryMessageType::Normal);
331 } // namespace dbaui
333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */