LibreOffice Module dbaccess (master) 1
paramdialog.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 <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>
27#include <vcl/weld.hxx>
28#include <o3tl/safeint.hxx>
29#include <osl/diagnose.h>
31
32namespace dbaui
33{
34
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star::beans;
38 using namespace ::com::sun::star::container;
39 using namespace ::com::sun::star::sdbc;
40 using namespace ::com::sun::star::util;
41 using namespace ::connectivity;
42
43 // OParameterDialog
44
45
47 weld::Window* pParent, const Reference< XIndexAccess > & rParamContainer,
48 const Reference< XConnection > & _rxConnection, const Reference< XComponentContext >& rxContext)
49 : GenericDialogController(pParent, "dbaccess/ui/parametersdialog.ui", "Parameters")
50 , m_nCurrentlySelected(-1)
51 , m_xConnection(_rxConnection)
52 , m_aPredicateInput( rxContext, _rxConnection, getParseContext() )
53 , m_aResetVisitFlag("dbaccess OParameterDialog m_aResetVisitFlag")
54 , m_xAllParams(m_xBuilder->weld_tree_view("allParamTreeview"))
55 , m_xParam(m_xBuilder->weld_entry("paramEntry"))
56 , m_xTravelNext(m_xBuilder->weld_button("next"))
57 , m_xOKBtn(m_xBuilder->weld_button("ok"))
58 , m_xCancelBtn(m_xBuilder->weld_button("cancel"))
59 {
60 m_xAllParams->set_size_request(-1, m_xAllParams->get_height_rows(10));
61
62 if (rxContext.is())
63 m_xFormatter.set( NumberFormatter::create( rxContext ), UNO_QUERY_THROW);
64 else {
65 OSL_FAIL("OParameterDialog::OParameterDialog: need a service factory!");
66 }
67
68 Reference< XNumberFormatsSupplier > xNumberFormats = ::dbtools::getNumberFormats(m_xConnection, true);
69 if (!xNumberFormats.is())
70 ::comphelper::disposeComponent(m_xFormatter);
71 else
72 m_xFormatter->attachNumberFormatsSupplier(xNumberFormats);
73 try
74 {
75 OSL_ENSURE(rParamContainer->getCount(), "OParameterDialog::OParameterDialog : can't handle empty containers !");
76
77 m_aFinalValues.realloc(rParamContainer->getCount());
78 PropertyValue* pValues = m_aFinalValues.getArray();
79
80 for (sal_Int32 i = 0, nCount = rParamContainer->getCount(); i<nCount; ++i, ++pValues)
81 {
82 Reference< XPropertySet > xParamAsSet;
83 rParamContainer->getByIndex(i) >>= xParamAsSet;
84 OSL_ENSURE(xParamAsSet.is(),"Parameter is null!");
85 if(!xParamAsSet.is())
86 continue;
87 pValues->Name = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
88 m_xAllParams->append_text(pValues->Name);
89
91 // not visited, not dirty
92 }
93
94 m_xParams = rParamContainer;
95 }
96 catch(Exception&)
97 {
98 DBG_UNHANDLED_EXCEPTION("dbaccess");
99 }
100
101 Construct();
102
104 }
105
107 {
110 }
111
113 {
114 m_xAllParams->connect_changed(LINK(this, OParameterDialog, OnEntryListBoxSelected));
115 m_xParam->connect_focus_out(LINK(this, OParameterDialog, OnValueLoseFocusHdl));
116 m_xParam->connect_changed(LINK(this, OParameterDialog, OnValueModified));
117 m_xTravelNext->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
118 m_xOKBtn->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
119 m_xCancelBtn->connect_clicked(LINK(this, OParameterDialog, OnButtonClicked));
120
121 if (m_xAllParams->n_children())
122 {
123 m_xAllParams->select(0);
125
126 if (m_xAllParams->n_children() == 1)
127 m_xTravelNext->set_sensitive(false);
128
129 if (m_xAllParams->n_children() > 1)
130 m_xDialog->change_default_widget(m_xOKBtn.get(), m_xTravelNext.get());
131 }
132
133 m_xParam->grab_focus();
134 }
135
136 IMPL_LINK_NOARG(OParameterDialog, OnValueLoseFocusHdl, weld::Widget&, void)
137 {
138 CheckValueForError();
139 }
140
142 {
143 if (m_nCurrentlySelected != -1)
144 {
146 // nothing to do, the value isn't dirty
147 return false;
148 }
149
150 bool bRet = false;
151
152 Reference< XPropertySet > xParamAsSet;
153 m_xParams->getByIndex(m_nCurrentlySelected) >>= xParamAsSet;
154 if (xParamAsSet.is())
155 {
156 if (m_xConnection.is() && m_xFormatter.is())
157 {
158 OUString sParamValue(m_xParam->get_text());
159 bool bValid = m_aPredicateInput.normalizePredicateString( sParamValue, xParamAsSet );
160 m_xParam->set_text(sParamValue);
162 OUString sToolTip;
163 if ( bValid )
164 {
165 // with this the value isn't dirty anymore
166 if (m_nCurrentlySelected != -1)
168 }
169 else
170 {
171 OUString sName;
172 try
173 {
174 sName = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
175 }
176 catch(Exception&)
177 {
178 DBG_UNHANDLED_EXCEPTION("dbaccess");
179 }
180
181 OUString sMessage(DBA_RES(STR_COULD_NOT_CONVERT_PARAM));
182 sToolTip = sMessage.replaceAll( "$name$", sName );
183 m_xParam->grab_focus();
184 bRet = true;
185 }
186 m_xParam->set_tooltip_text(sToolTip);
187 m_xOKBtn->set_sensitive(bValid);
188 }
189 }
190
191 return bRet;
192 }
193
194 IMPL_LINK(OParameterDialog, OnButtonClicked, weld::Button&, rButton, void)
195 {
196 if (m_xCancelBtn.get() == &rButton)
197 {
198 // no interpreting of the given values anymore...
199 m_xParam->connect_focus_out(Link<weld::Widget&, void>()); // no direct call from the control anymore ...
200 m_xDialog->response(RET_CANCEL);
201 }
202 else if (m_xOKBtn.get() == &rButton)
203 {
204 // transfer the current values into the Any
205 if (OnEntrySelected())
206 { // there was an error interpreting the current text
207 return;
208 }
209
210 if (m_xParams.is())
211 {
212 // write the parameters
213 try
214 {
215 PropertyValue* pValues = m_aFinalValues.getArray();
216 for (sal_Int32 i = 0, nCount = m_xParams->getCount(); i<nCount; ++i, ++pValues)
217 {
218 Reference< XPropertySet > xParamAsSet;
219 m_xParams->getByIndex(i) >>= xParamAsSet;
220
221 OUString sValue;
222 pValues->Value >>= sValue;
223 pValues->Value = m_aPredicateInput.getPredicateValue( sValue, xParamAsSet );
224 }
225 }
226 catch(Exception&)
227 {
228 DBG_UNHANDLED_EXCEPTION("dbaccess");
229 }
230
231 }
232 m_xDialog->response(RET_OK);
233 }
234 else if (m_xTravelNext.get() == &rButton)
235 {
236 if (sal_Int32 nCount = m_xAllParams->n_children())
237 {
238 sal_Int32 nCurrent = m_xAllParams->get_selected_index();
239 OSL_ENSURE(static_cast<size_t>(nCount) == m_aVisitedParams.size(), "OParameterDialog::OnButtonClicked : inconsistent lists !");
240
241 // search the next entry in list we haven't visited yet
242 sal_Int32 nNext = (nCurrent + 1) % nCount;
243 while ((nNext != nCurrent) && ( m_aVisitedParams[nNext] & VisitFlags::Visited ))
244 nNext = (nNext + 1) % nCount;
245
246 if ( m_aVisitedParams[nNext] & VisitFlags::Visited )
247 // there is no such "not visited yet" entry -> simply take the next one
248 nNext = (nCurrent + 1) % nCount;
249
250 m_xAllParams->select(nNext);
251 OnEntrySelected();
252 }
253 }
254 }
255
256 IMPL_LINK_NOARG(OParameterDialog, OnEntryListBoxSelected, weld::TreeView&, void)
257 {
258 OnEntrySelected();
259 }
260
262 {
264 {
265 LINK(this, OParameterDialog, OnVisitedTimeout).Call(&m_aResetVisitFlag);
267 }
268 // save the old values
269 if (m_nCurrentlySelected != -1)
270 {
271 // do the transformation of the current text
272 if (CheckValueForError())
273 { // there was an error interpreting the text
275 return true;
276 }
277
278 m_aFinalValues.getArray()[m_nCurrentlySelected].Value <<= m_xParam->get_text();
279 }
280
281 // initialize the controls with the new values
282 sal_Int32 nSelected = m_xAllParams->get_selected_index();
283 OSL_ENSURE(nSelected != -1, "OParameterDialog::OnEntrySelected : no current entry !");
284
285 m_xParam->set_text(::comphelper::getString(m_aFinalValues[nSelected].Value));
286 m_nCurrentlySelected = nSelected;
287
288 // with this the value isn't dirty
289 OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnEntrySelected : invalid current entry !");
291
294
295 return false;
296 }
297
298 IMPL_LINK_NOARG(OParameterDialog, OnVisitedTimeout, Timer*, void)
299 {
300 OSL_ENSURE(m_nCurrentlySelected != -1, "OParameterDialog::OnVisitedTimeout : invalid call !");
301
302 // mark the currently selected entry as visited
303 OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnVisitedTimeout : invalid entry !");
304 m_aVisitedParams[m_nCurrentlySelected] |= VisitFlags::Visited;
305
306 // was it the last "not visited yet" entry ?
307 bool bVisited = false;
308 for (auto const& visitedParam : m_aVisitedParams)
309 {
310 if (!(visitedParam & VisitFlags::Visited))
311 {
312 bVisited = true;
313 break;
314 }
315 }
316
317 if (!bVisited)
318 {
319 // yes, there isn't another one -> change the "default button"
320 m_xDialog->change_default_widget(m_xTravelNext.get(), m_xOKBtn.get());
321 }
322 }
323
324 IMPL_LINK(OParameterDialog, OnValueModified, weld::Entry&, rEdit, void)
325 {
326 // mark the currently selected entry as dirty
327 OSL_ENSURE(o3tl::make_unsigned(m_nCurrentlySelected) < m_aVisitedParams.size(), "OParameterDialog::OnValueModified : invalid entry !");
328 m_aVisitedParams[m_nCurrentlySelected] |= VisitFlags::Dirty;
329 rEdit.set_message_type(weld::EntryMessageType::Normal);
330 }
331
332} // namespace dbaui
333
334/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
OptionalString sName
Reference< XExecutableDialog > m_xDialog
bool IsActive() const
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual void Start(bool bStartTimer=true) override
OParameterDialog(weld::Window *_pParent, const css::uno::Reference< css::container::XIndexAccess > &_rParamContainer, const css::uno::Reference< css::sdbc::XConnection > &_rxConnection, const css::uno::Reference< css::uno::XComponentContext > &rxContext)
Definition: paramdialog.cxx:46
css::uno::Reference< css::sdbc::XConnection > m_xConnection
Definition: paramdialog.hxx:59
css::uno::Reference< css::util::XNumberFormatter > m_xFormatter
Definition: paramdialog.hxx:61
virtual ~OParameterDialog() override
std::vector< VisitFlags > m_aVisitedParams
Definition: paramdialog.hxx:65
std::unique_ptr< weld::Button > m_xOKBtn
Definition: paramdialog.hxx:76
css::uno::Sequence< css::beans::PropertyValue > m_aFinalValues
Definition: paramdialog.hxx:70
std::unique_ptr< weld::Button > m_xTravelNext
Definition: paramdialog.hxx:75
css::uno::Reference< css::container::XIndexAccess > m_xParams
Definition: paramdialog.hxx:57
::dbtools::OPredicateInputController m_aPredicateInput
Definition: paramdialog.hxx:63
std::unique_ptr< weld::Entry > m_xParam
Definition: paramdialog.hxx:74
std::unique_ptr< weld::TreeView > m_xAllParams
the final values as entered by the user
Definition: paramdialog.hxx:73
std::unique_ptr< weld::Button > m_xCancelBtn
Definition: paramdialog.hxx:77
sal_Int32 m_nCurrentlySelected
Definition: paramdialog.hxx:54
bool normalizePredicateString(OUString &_rPredicateValue, const css::uno::Reference< css::beans::XPropertySet > &_rxField, OUString *_pErrorMessage=nullptr) const
std::shared_ptr< weld::Dialog > m_xDialog
#define DBA_RES(id)
int nCount
#define DBG_UNHANDLED_EXCEPTION(...)
@ Exception
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper *, void)
IMPL_LINK(OApplicationController, OnSelectContainer, void *, _pType, void)
Value
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Reference< XConnection > m_xConnection
Definition: objectnames.cxx:79
VisitFlags
Definition: paramdialog.hxx:38
OUString sMessage
Definition: sqlmessage.cxx:159
constexpr OUStringLiteral PROPERTY_NAME(u"Name")
RET_OK
RET_CANCEL