Branch data Line data Source code
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 : :
21 : : #include "paramdialog.hxx"
22 : : #include "paramdialog.hrc"
23 : : #include "dbu_dlg.hrc"
24 : : #include "commontypes.hxx"
25 : : #include "moduledbu.hxx"
26 : : #include <com/sun/star/util/XNumberFormatter.hpp>
27 : : #include <com/sun/star/sdbc/DataType.hpp>
28 : : #include <connectivity/dbtools.hxx>
29 : : #include "dbustrings.hrc"
30 : : #include <vcl/svapp.hxx>
31 : : #include <vcl/msgbox.hxx>
32 : : #include <osl/diagnose.h>
33 : : #include <tools/diagnose_ex.h>
34 : : #include "localresaccess.hxx"
35 : : #include <unotools/syslocale.hxx>
36 : :
37 : : #define EF_VISITED 0x0001
38 : : #define EF_DIRTY 0x0002
39 : :
40 : : //.........................................................................
41 : : namespace dbaui
42 : : {
43 : : //.........................................................................
44 : :
45 : : using namespace ::com::sun::star::uno;
46 : : using namespace ::com::sun::star::lang;
47 : : using namespace ::com::sun::star::beans;
48 : : using namespace ::com::sun::star::container;
49 : : using namespace ::com::sun::star::sdbc;
50 : : using namespace ::com::sun::star::util;
51 : : using namespace ::connectivity;
52 : :
53 : : //==================================================================
54 : : //= OParameterDialog
55 : : //==================================================================
56 : :
57 : : //------------------------------------------------------------------------------
58 : : #define INIT_MEMBERS() \
59 : : :ModalDialog( pParent, ModuleRes(DLG_PARAMETERS)) \
60 : : ,m_aNamesFrame (this, ModuleRes(FL_PARAMS)) \
61 : : ,m_aAllParams (this, ModuleRes(LB_ALLPARAMS)) \
62 : : ,m_aValueFrame (this, ModuleRes(FT_VALUE)) \
63 : : ,m_aParam (this, ModuleRes(ET_PARAM)) \
64 : : ,m_aTravelNext (this, ModuleRes(BT_TRAVELNEXT)) \
65 : : ,m_aOKBtn (this, ModuleRes(BT_OK)) \
66 : : ,m_aCancelBtn (this, ModuleRes(BT_CANCEL)) \
67 : : ,m_nCurrentlySelected(LISTBOX_ENTRY_NOTFOUND) \
68 : : ,m_xConnection(_rxConnection) \
69 : : ,m_aPredicateInput( _rxORB, _rxConnection, getParseContext() ) \
70 : : ,m_bNeedErrorOnCurrent(sal_True) \
71 : :
72 : :
73 : : //------------------------------------------------------------------------------
74 : : DBG_NAME(OParameterDialog)
75 : :
76 : 0 : OParameterDialog::OParameterDialog(
77 : : Window* pParent, const Reference< XIndexAccess > & rParamContainer,
78 : : const Reference< XConnection > & _rxConnection, const Reference< XMultiServiceFactory >& _rxORB)
79 [ # # ][ # # ]: 0 : INIT_MEMBERS()
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
80 : : {
81 : : DBG_CTOR(OParameterDialog,NULL);
82 : :
83 [ # # ]: 0 : if (_rxORB.is())
84 [ # # ]: 0 : m_xFormatter = Reference< XNumberFormatter>(_rxORB->createInstance(
85 [ # # ][ # # ]: 0 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.NumberFormatter"))), UNO_QUERY);
[ # # ][ # # ]
86 : : else {
87 : : OSL_FAIL("OParameterDialog::OParameterDialog: need a service factory!");
88 : : }
89 : :
90 [ # # ]: 0 : Reference< XNumberFormatsSupplier > xNumberFormats = ::dbtools::getNumberFormats(m_xConnection, sal_True);
91 [ # # ]: 0 : if (!xNumberFormats.is())
92 [ # # ]: 0 : ::comphelper::disposeComponent(m_xFormatter);
93 [ # # ]: 0 : else if (m_xFormatter.is())
94 [ # # ][ # # ]: 0 : m_xFormatter->attachNumberFormatsSupplier(xNumberFormats);
95 : : try
96 : : {
97 : : OSL_ENSURE(rParamContainer->getCount(), "OParameterDialog::OParameterDialog : can't handle empty containers !");
98 : :
99 [ # # ][ # # ]: 0 : m_aFinalValues.realloc(rParamContainer->getCount());
[ # # ]
100 [ # # ]: 0 : PropertyValue* pValues = m_aFinalValues.getArray();
101 : :
102 [ # # ][ # # ]: 0 : for (sal_Int32 i = 0, nCount = rParamContainer->getCount(); i<nCount; ++i, ++pValues)
[ # # ]
103 : : {
104 : 0 : Reference< XPropertySet > xParamAsSet;
105 [ # # ][ # # ]: 0 : rParamContainer->getByIndex(i) >>= xParamAsSet;
[ # # ]
106 : : OSL_ENSURE(xParamAsSet.is(),"Parameter is null!");
107 [ # # ]: 0 : if(!xParamAsSet.is())
108 : 0 : continue;
109 [ # # ][ # # ]: 0 : pValues->Name = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
[ # # ][ # # ]
110 [ # # ][ # # ]: 0 : m_aAllParams.InsertEntry(pValues->Name);
[ # # ]
111 : :
112 [ # # ]: 0 : if (!pValues->Value.hasValue())
113 : : // it won't have a value, 'cause it's default constructed. But may be later we support
114 : : // initializing this dialog with values
115 [ # # ]: 0 : pValues->Value = makeAny(::rtl::OUString());
116 : : // default the values to an empty string
117 : :
118 [ # # ][ # # ]: 0 : m_aVisitedParams.push_back(0);
119 : : // not visited, not dirty
120 [ # # ]: 0 : }
121 : :
122 [ # # ]: 0 : m_xParams = rParamContainer;
123 : : }
124 [ # # ]: 0 : catch(Exception&)
125 : : {
126 : : DBG_UNHANDLED_EXCEPTION();
127 : : }
128 : :
129 : :
130 [ # # ]: 0 : Construct();
131 : :
132 [ # # ]: 0 : m_aResetVisitFlag.SetTimeoutHdl(LINK(this, OParameterDialog, OnVisitedTimeout));
133 : :
134 [ # # ]: 0 : FreeResource();
135 : 0 : }
136 : :
137 : : //------------------------------------------------------------------------------
138 [ # # ][ # # ]: 0 : OParameterDialog::~OParameterDialog()
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
139 : : {
140 [ # # ]: 0 : if (m_aResetVisitFlag.IsActive())
141 [ # # ]: 0 : m_aResetVisitFlag.Stop();
142 : :
143 : : DBG_DTOR(OParameterDialog,NULL);
144 [ # # ]: 0 : }
145 : :
146 : : //------------------------------------------------------------------------------
147 : 0 : void OParameterDialog::Construct()
148 : : {
149 : 0 : m_aAllParams.SetSelectHdl(LINK(this, OParameterDialog, OnEntrySelected));
150 : 0 : m_aParam.SetLoseFocusHdl(LINK(this, OParameterDialog, OnValueLoseFocus));
151 : 0 : m_aParam.SetModifyHdl(LINK(this, OParameterDialog, OnValueModified));
152 : 0 : m_aTravelNext.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
153 : 0 : m_aOKBtn.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
154 : 0 : m_aCancelBtn.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
155 : :
156 [ # # ]: 0 : if (m_aAllParams.GetEntryCount())
157 : : {
158 : 0 : m_aAllParams.SelectEntryPos(0);
159 [ # # ]: 0 : LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams);
160 : :
161 [ # # ]: 0 : if (m_aAllParams.GetEntryCount() == 1)
162 : : {
163 : 0 : m_aTravelNext.Enable(sal_False);
164 : : }
165 : :
166 [ # # ]: 0 : if (m_aAllParams.GetEntryCount() > 1)
167 : : {
168 : 0 : m_aOKBtn.SetStyle(m_aOKBtn.GetStyle() & ~WB_DEFBUTTON);
169 : 0 : m_aTravelNext.SetStyle(m_aTravelNext.GetStyle() | WB_DEFBUTTON);
170 : : }
171 : : }
172 : :
173 : 0 : m_aParam.GrabFocus();
174 : 0 : }
175 : :
176 : : //------------------------------------------------------------------------------
177 : 0 : IMPL_LINK(OParameterDialog, OnValueLoseFocus, Control*, /*pSource*/)
178 : : {
179 [ # # ]: 0 : if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
180 : : {
181 [ # # ][ # # ]: 0 : if ( ( m_aVisitedParams[ m_nCurrentlySelected ] & EF_DIRTY ) == 0 )
182 : : // nothing to do, the value isn't dirty
183 : 0 : return 0L;
184 : : }
185 : :
186 : : // transform the current string according to the param field type
187 [ # # ][ # # ]: 0 : ::rtl::OUString sTransformedText(m_aParam.GetText());
[ # # ]
188 : 0 : Reference< XPropertySet > xParamAsSet;
189 [ # # ][ # # ]: 0 : m_xParams->getByIndex(m_nCurrentlySelected) >>= xParamAsSet;
[ # # ]
190 [ # # ]: 0 : if (xParamAsSet.is())
191 : : {
192 [ # # ][ # # ]: 0 : if (m_xConnection.is() && m_xFormatter.is())
[ # # ]
193 : : {
194 [ # # ][ # # ]: 0 : ::rtl::OUString sParamValue( m_aParam.GetText() );
[ # # ]
195 [ # # ]: 0 : sal_Bool bValid = m_aPredicateInput.normalizePredicateString( sParamValue, xParamAsSet );
196 [ # # ][ # # ]: 0 : m_aParam.SetText( sParamValue );
[ # # ]
197 [ # # ]: 0 : if ( bValid )
198 : : {
199 : : // with this the value isn't dirty anymore
200 [ # # ]: 0 : if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
201 [ # # ]: 0 : m_aVisitedParams[m_nCurrentlySelected] &= ~EF_DIRTY;
202 : : }
203 : : else
204 : : {
205 [ # # ]: 0 : if (!m_bNeedErrorOnCurrent)
206 : 0 : return 1L;
207 : :
208 : 0 : m_bNeedErrorOnCurrent = sal_False; // will be reset in OnValueModified
209 : :
210 : 0 : ::rtl::OUString sName;
211 : : try
212 : : {
213 [ # # ][ # # ]: 0 : sName = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
[ # # ][ # # ]
[ # # ]
214 : : }
215 [ # # ]: 0 : catch(Exception&)
216 : : {
217 : : DBG_UNHANDLED_EXCEPTION();
218 : : }
219 : :
220 [ # # ]: 0 : String sMessage;
221 : : {
222 [ # # ]: 0 : LocalResourceAccess aDummy(DLG_PARAMETERS, RSC_MODALDIALOG);
223 [ # # ][ # # ]: 0 : sMessage = String(ModuleRes(STR_COULD_NOT_CONVERT_PARAM));
[ # # ][ # # ]
[ # # ]
224 : : }
225 [ # # ][ # # ]: 0 : sMessage.SearchAndReplaceAll(rtl::OUString("$name$"), sName);
[ # # ][ # # ]
[ # # ]
226 [ # # ][ # # ]: 0 : ErrorBox(NULL, WB_OK, sMessage).Execute();
[ # # ]
227 [ # # ]: 0 : m_aParam.GrabFocus();
228 [ # # ]: 0 : return 1L;
229 [ # # ]: 0 : }
230 : : }
231 : : }
232 : :
233 : 0 : return 0L;
234 : : }
235 : :
236 : : //------------------------------------------------------------------------------
237 : 0 : IMPL_LINK(OParameterDialog, OnButtonClicked, PushButton*, pButton)
238 : : {
239 [ # # ]: 0 : if (&m_aCancelBtn == pButton)
240 : : {
241 : : // no interpreting of the given values anymore ....
242 : 0 : m_aParam.SetLoseFocusHdl(Link()); // no direct call from the control anymore ...
243 : 0 : m_bNeedErrorOnCurrent = sal_False; // in case of any indirect calls -> no error message
244 : 0 : m_aCancelBtn.SetClickHdl(Link());
245 : 0 : m_aCancelBtn.Click();
246 : : }
247 [ # # ]: 0 : else if (&m_aOKBtn == pButton)
248 : : {
249 : : // transfer the current values into the Any
250 [ # # ][ # # ]: 0 : if (LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams) != 0L)
251 : : { // there was an error interpreting the current text
252 : 0 : m_bNeedErrorOnCurrent = sal_True;
253 : : // we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
254 : : // so the next time it is called we need an error message, again ....
255 : : // (TODO : there surely are better solutions for this ...)
256 : 0 : return 1L;
257 : : }
258 : :
259 [ # # ]: 0 : if (m_xParams.is())
260 : : {
261 : : // write the parameters
262 : : try
263 : : {
264 [ # # ]: 0 : PropertyValue* pValues = m_aFinalValues.getArray();
265 [ # # ][ # # ]: 0 : for (sal_Int32 i = 0, nCount = m_xParams->getCount(); i<nCount; ++i, ++pValues)
[ # # ]
266 : : {
267 : 0 : Reference< XPropertySet > xParamAsSet;
268 [ # # ][ # # ]: 0 : m_xParams->getByIndex(i) >>= xParamAsSet;
[ # # ]
269 : :
270 : 0 : ::rtl::OUString sValue;
271 : 0 : pValues->Value >>= sValue;
272 [ # # ][ # # ]: 0 : pValues->Value <<= ::rtl::OUString( m_aPredicateInput.getPredicateValue( sValue, xParamAsSet, sal_False ) );
273 [ # # ]: 0 : }
274 : : }
275 : 0 : catch(Exception&)
276 : : {
277 : : DBG_UNHANDLED_EXCEPTION();
278 : : }
279 : :
280 : : }
281 : : // to close the dialog (which is more code than a simple EndDialog)
282 : 0 : m_aOKBtn.SetClickHdl(Link());
283 : 0 : m_aOKBtn.Click();
284 : : }
285 [ # # ]: 0 : else if (&m_aTravelNext == pButton)
286 : : {
287 : 0 : sal_uInt16 nCurrent = m_aAllParams.GetSelectEntryPos();
288 : 0 : sal_uInt16 nCount = m_aAllParams.GetEntryCount();
289 : : OSL_ENSURE(nCount == m_aVisitedParams.size(), "OParameterDialog::OnButtonClicked : inconsistent lists !");
290 : :
291 : : // search the next entry in list we haven't visited yet
292 : 0 : sal_uInt16 nNext = (nCurrent + 1) % nCount;
293 [ # # ][ # # ]: 0 : while ((nNext != nCurrent) && ( m_aVisitedParams[nNext] & EF_VISITED ))
[ # # ]
294 : 0 : nNext = (nNext + 1) % nCount;
295 : :
296 [ # # ]: 0 : if ( m_aVisitedParams[nNext] & EF_VISITED )
297 : : // there is no such "not visited yet" entry -> simpy take the next one
298 : 0 : nNext = (nCurrent + 1) % nCount;
299 : :
300 : 0 : m_aAllParams.SelectEntryPos(nNext);
301 [ # # ]: 0 : LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams);
302 : 0 : m_bNeedErrorOnCurrent = sal_True;
303 : : // we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
304 : : // so the next time it is called we need an error message, again ....
305 : : // (TODO : there surely are better solutions for this ...)
306 : : }
307 : :
308 : 0 : return 0L;
309 : : }
310 : :
311 : : //------------------------------------------------------------------------------
312 : 0 : IMPL_LINK(OParameterDialog, OnEntrySelected, ListBox*, /*pList*/)
313 : : {
314 [ # # ]: 0 : if (m_aResetVisitFlag.IsActive())
315 : : {
316 [ # # ]: 0 : LINK(this, OParameterDialog, OnVisitedTimeout).Call(&m_aResetVisitFlag);
317 : 0 : m_aResetVisitFlag.Stop();
318 : : }
319 : : // save the old values
320 [ # # ]: 0 : if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
321 : : {
322 : : // do the transformation of the current text
323 [ # # ][ # # ]: 0 : if (LINK(this, OParameterDialog, OnValueLoseFocus).Call(&m_aParam) != 0L)
324 : : { // there was an error interpreting the text
325 : 0 : m_aAllParams.SelectEntryPos(m_nCurrentlySelected);
326 : 0 : return 1L;
327 : : }
328 : :
329 [ # # ][ # # ]: 0 : m_aFinalValues[m_nCurrentlySelected].Value <<= ::rtl::OUString(m_aParam.GetText());
[ # # ]
330 : : }
331 : :
332 : : // initialize the controls with the new values
333 : 0 : sal_uInt16 nSelected = m_aAllParams.GetSelectEntryPos();
334 : : OSL_ENSURE(nSelected != LISTBOX_ENTRY_NOTFOUND, "OParameterDialog::OnEntrySelected : no current entry !");
335 : :
336 [ # # ][ # # ]: 0 : m_aParam.SetText(::comphelper::getString(m_aFinalValues[nSelected].Value));
[ # # ]
337 : 0 : m_nCurrentlySelected = nSelected;
338 : :
339 : : // with this the value isn't dirty
340 : : OSL_ENSURE(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnEntrySelected : invalid current entry !");
341 : 0 : m_aVisitedParams[m_nCurrentlySelected] &= ~EF_DIRTY;
342 : :
343 : 0 : m_aResetVisitFlag.SetTimeout(1000);
344 : 0 : m_aResetVisitFlag.Start();
345 : :
346 : 0 : return 0L;
347 : : }
348 : :
349 : : //------------------------------------------------------------------------------
350 : 0 : IMPL_LINK(OParameterDialog, OnVisitedTimeout, Timer*, /*pTimer*/)
351 : : {
352 : : OSL_ENSURE(m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND, "OParameterDialog::OnVisitedTimeout : invalid call !");
353 : :
354 : : // mark the currently selected entry as visited
355 : : OSL_ENSURE(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnVisitedTimeout : invalid entry !");
356 [ # # ]: 0 : m_aVisitedParams[m_nCurrentlySelected] |= EF_VISITED;
357 : :
358 : : // was it the last "not visited yet" entry ?
359 : 0 : ConstByteVectorIterator aIter;
360 [ # # ]: 0 : for ( aIter = m_aVisitedParams.begin();
[ # # # # ]
[ # # ]
361 : 0 : aIter < m_aVisitedParams.end();
362 : : ++aIter
363 : : )
364 : : {
365 [ # # ][ # # ]: 0 : if (((*aIter) & EF_VISITED) == 0)
366 : 0 : break;
367 : : }
368 [ # # ][ # # ]: 0 : if (aIter == m_aVisitedParams.end())
369 : : { // yes, there isn't another one -> change the "default button"
370 [ # # ][ # # ]: 0 : m_aTravelNext.SetStyle(m_aTravelNext.GetStyle() & ~WB_DEFBUTTON);
371 [ # # ][ # # ]: 0 : m_aOKBtn.SetStyle(m_aOKBtn.GetStyle() | WB_DEFBUTTON);
372 : :
373 : : // set to focus to one of the buttons temporary (with this their "default"-state is really updated)
374 [ # # ]: 0 : Window* pOldFocus = Application::GetFocusWindow();
375 : :
376 : : // if the old focus window is the value edit do some preparations ...
377 : 0 : Selection aSel;
378 [ # # ]: 0 : if (pOldFocus == &m_aParam)
379 : : {
380 [ # # ]: 0 : m_aParam.SetLoseFocusHdl(Link());
381 [ # # ]: 0 : aSel = m_aParam.GetSelection();
382 : : }
383 [ # # ]: 0 : m_aTravelNext.GrabFocus();
384 [ # # ]: 0 : if (pOldFocus)
385 [ # # ]: 0 : pOldFocus->GrabFocus();
386 : :
387 : : // restore the settings for the value edit
388 [ # # ]: 0 : if (pOldFocus == &m_aParam)
389 : : {
390 [ # # ]: 0 : m_aParam.SetLoseFocusHdl(LINK(this, OParameterDialog, OnValueLoseFocus));
391 [ # # ]: 0 : m_aParam.SetSelection(aSel);
392 : : }
393 : : }
394 : :
395 : 0 : return 0L;
396 : : }
397 : :
398 : : //------------------------------------------------------------------------------
399 : 0 : IMPL_LINK(OParameterDialog, OnValueModified, Control*, /*pBox*/)
400 : : {
401 : : // mark the currently selected entry as dirty
402 : : OSL_ENSURE(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnValueModified : invalid entry !");
403 : 0 : m_aVisitedParams[m_nCurrentlySelected] |= EF_DIRTY;
404 : :
405 : 0 : m_bNeedErrorOnCurrent = sal_True;
406 : :
407 : 0 : return 0L;
408 : : }
409 : :
410 : :
411 : : //.........................................................................
412 : : } // namespace dbaui
413 : : //.........................................................................
414 : :
415 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|