Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / dbaccess / source / ui / dlg / paramdialog.cxx
blobd5803492992a6ab65edcba8864ae72f91d49d440
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "paramdialog.hxx"
31 #include "paramdialog.hrc"
32 #include "dbu_dlg.hrc"
33 #include "commontypes.hxx"
34 #include "moduledbu.hxx"
35 #include <com/sun/star/util/XNumberFormatter.hpp>
36 #include <com/sun/star/sdbc/DataType.hpp>
37 #include <connectivity/dbtools.hxx>
38 #include "dbustrings.hrc"
39 #include <vcl/svapp.hxx>
40 #include <vcl/msgbox.hxx>
41 #include <osl/diagnose.h>
42 #include <tools/diagnose_ex.h>
43 #include "localresaccess.hxx"
44 #include <unotools/syslocale.hxx>
46 #define EF_VISITED 0x0001
47 #define EF_DIRTY 0x0002
49 //.........................................................................
50 namespace dbaui
52 //.........................................................................
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::beans;
57 using namespace ::com::sun::star::container;
58 using namespace ::com::sun::star::sdbc;
59 using namespace ::com::sun::star::util;
60 using namespace ::connectivity;
62 //==================================================================
63 //= OParameterDialog
64 //==================================================================
66 //------------------------------------------------------------------------------
67 #define INIT_MEMBERS() \
68 :ModalDialog( pParent, ModuleRes(DLG_PARAMETERS)) \
69 ,m_aNamesFrame (this, ModuleRes(FL_PARAMS)) \
70 ,m_aAllParams (this, ModuleRes(LB_ALLPARAMS)) \
71 ,m_aValueFrame (this, ModuleRes(FT_VALUE)) \
72 ,m_aParam (this, ModuleRes(ET_PARAM)) \
73 ,m_aTravelNext (this, ModuleRes(BT_TRAVELNEXT)) \
74 ,m_aOKBtn (this, ModuleRes(BT_OK)) \
75 ,m_aCancelBtn (this, ModuleRes(BT_CANCEL)) \
76 ,m_nCurrentlySelected(LISTBOX_ENTRY_NOTFOUND) \
77 ,m_xConnection(_rxConnection) \
78 ,m_aPredicateInput( _rxORB, _rxConnection, getParseContext() ) \
79 ,m_bNeedErrorOnCurrent(sal_True) \
82 //------------------------------------------------------------------------------
83 DBG_NAME(OParameterDialog)
85 OParameterDialog::OParameterDialog(
86 Window* pParent, const Reference< XIndexAccess > & rParamContainer,
87 const Reference< XConnection > & _rxConnection, const Reference< XMultiServiceFactory >& _rxORB)
88 INIT_MEMBERS()
90 DBG_CTOR(OParameterDialog,NULL);
92 if (_rxORB.is())
93 m_xFormatter = Reference< XNumberFormatter>(_rxORB->createInstance(
94 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.NumberFormatter"))), UNO_QUERY);
95 else {
96 OSL_FAIL("OParameterDialog::OParameterDialog: need a service factory!");
99 Reference< XNumberFormatsSupplier > xNumberFormats = ::dbtools::getNumberFormats(m_xConnection, sal_True);
100 if (!xNumberFormats.is())
101 ::comphelper::disposeComponent(m_xFormatter);
102 else if (m_xFormatter.is())
103 m_xFormatter->attachNumberFormatsSupplier(xNumberFormats);
106 OSL_ENSURE(rParamContainer->getCount(), "OParameterDialog::OParameterDialog : can't handle empty containers !");
108 m_aFinalValues.realloc(rParamContainer->getCount());
109 PropertyValue* pValues = m_aFinalValues.getArray();
111 for (sal_Int32 i = 0, nCount = rParamContainer->getCount(); i<nCount; ++i, ++pValues)
113 Reference< XPropertySet > xParamAsSet;
114 rParamContainer->getByIndex(i) >>= xParamAsSet;
115 OSL_ENSURE(xParamAsSet.is(),"Parameter is null!");
116 if(!xParamAsSet.is())
117 continue;
118 pValues->Name = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
119 m_aAllParams.InsertEntry(pValues->Name);
121 if (!pValues->Value.hasValue())
122 // it won't have a value, 'cause it's default constructed. But may be later we support
123 // initializing this dialog with values
124 pValues->Value = makeAny(::rtl::OUString());
125 // default the values to an empty string
127 m_aVisitedParams.push_back(0);
128 // not visited, not dirty
131 m_xParams = rParamContainer;
133 catch(Exception&)
135 DBG_UNHANDLED_EXCEPTION();
139 Construct();
141 m_aResetVisitFlag.SetTimeoutHdl(LINK(this, OParameterDialog, OnVisitedTimeout));
143 FreeResource();
146 //------------------------------------------------------------------------------
147 OParameterDialog::~OParameterDialog()
149 if (m_aResetVisitFlag.IsActive())
150 m_aResetVisitFlag.Stop();
152 DBG_DTOR(OParameterDialog,NULL);
155 //------------------------------------------------------------------------------
156 void OParameterDialog::Construct()
158 m_aAllParams.SetSelectHdl(LINK(this, OParameterDialog, OnEntrySelected));
159 m_aParam.SetLoseFocusHdl(LINK(this, OParameterDialog, OnValueLoseFocus));
160 m_aParam.SetModifyHdl(LINK(this, OParameterDialog, OnValueModified));
161 m_aTravelNext.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
162 m_aOKBtn.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
163 m_aCancelBtn.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
165 if (m_aAllParams.GetEntryCount())
167 m_aAllParams.SelectEntryPos(0);
168 LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams);
170 if (m_aAllParams.GetEntryCount() == 1)
172 m_aTravelNext.Enable(sal_False);
175 if (m_aAllParams.GetEntryCount() > 1)
177 m_aOKBtn.SetStyle(m_aOKBtn.GetStyle() & ~WB_DEFBUTTON);
178 m_aTravelNext.SetStyle(m_aTravelNext.GetStyle() | WB_DEFBUTTON);
182 m_aParam.GrabFocus();
185 //------------------------------------------------------------------------------
186 IMPL_LINK(OParameterDialog, OnValueLoseFocus, Control*, /*pSource*/)
188 if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
190 if ( ( m_aVisitedParams[ m_nCurrentlySelected ] & EF_DIRTY ) == 0 )
191 // nothing to do, the value isn't dirty
192 return 0L;
195 // transform the current string according to the param field type
196 ::rtl::OUString sTransformedText(m_aParam.GetText());
197 Reference< XPropertySet > xParamAsSet;
198 m_xParams->getByIndex(m_nCurrentlySelected) >>= xParamAsSet;
199 if (xParamAsSet.is())
201 if (m_xConnection.is() && m_xFormatter.is())
203 ::rtl::OUString sParamValue( m_aParam.GetText() );
204 sal_Bool bValid = m_aPredicateInput.normalizePredicateString( sParamValue, xParamAsSet );
205 m_aParam.SetText( sParamValue );
206 if ( bValid )
208 // with this the value isn't dirty anymore
209 if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
210 m_aVisitedParams[m_nCurrentlySelected] &= ~EF_DIRTY;
212 else
214 if (!m_bNeedErrorOnCurrent)
215 return 1L;
217 m_bNeedErrorOnCurrent = sal_False; // will be reset in OnValueModified
219 ::rtl::OUString sName;
222 sName = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
224 catch(Exception&)
226 DBG_UNHANDLED_EXCEPTION();
229 String sMessage;
231 LocalResourceAccess aDummy(DLG_PARAMETERS, RSC_MODALDIALOG);
232 sMessage = String(ModuleRes(STR_COULD_NOT_CONVERT_PARAM));
234 sMessage.SearchAndReplaceAll(String::CreateFromAscii("$name$"), sName.getStr());
235 ErrorBox(NULL, WB_OK, sMessage).Execute();
236 m_aParam.GrabFocus();
237 return 1L;
242 return 0L;
245 //------------------------------------------------------------------------------
246 IMPL_LINK(OParameterDialog, OnButtonClicked, PushButton*, pButton)
248 if (&m_aCancelBtn == pButton)
250 // no interpreting of the given values anymore ....
251 m_aParam.SetLoseFocusHdl(Link()); // no direct call from the control anymore ...
252 m_bNeedErrorOnCurrent = sal_False; // in case of any indirect calls -> no error message
253 m_aCancelBtn.SetClickHdl(Link());
254 m_aCancelBtn.Click();
256 else if (&m_aOKBtn == pButton)
258 // transfer the current values into the Any
259 if (LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams) != 0L)
260 { // there was an error interpreting the current text
261 m_bNeedErrorOnCurrent = sal_True;
262 // we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
263 // so the next time it is called we need an error message, again ....
264 // (TODO : there surely are better solutions for this ...)
265 return 1L;
268 if (m_xParams.is())
270 // write the parameters
273 PropertyValue* pValues = m_aFinalValues.getArray();
274 for (sal_Int32 i = 0, nCount = m_xParams->getCount(); i<nCount; ++i, ++pValues)
276 Reference< XPropertySet > xParamAsSet;
277 m_xParams->getByIndex(i) >>= xParamAsSet;
279 ::rtl::OUString sValue;
280 pValues->Value >>= sValue;
281 pValues->Value <<= ::rtl::OUString( m_aPredicateInput.getPredicateValue( sValue, xParamAsSet, sal_False ) );
284 catch(Exception&)
286 DBG_UNHANDLED_EXCEPTION();
290 // to close the dialog (which is more code than a simple EndDialog)
291 m_aOKBtn.SetClickHdl(Link());
292 m_aOKBtn.Click();
294 else if (&m_aTravelNext == pButton)
296 sal_uInt16 nCurrent = m_aAllParams.GetSelectEntryPos();
297 sal_uInt16 nCount = m_aAllParams.GetEntryCount();
298 OSL_ENSURE(nCount == m_aVisitedParams.size(), "OParameterDialog::OnButtonClicked : inconsistent lists !");
300 // search the next entry in list we haven't visited yet
301 sal_uInt16 nNext = (nCurrent + 1) % nCount;
302 while ((nNext != nCurrent) && ( m_aVisitedParams[nNext] & EF_VISITED ))
303 nNext = (nNext + 1) % nCount;
305 if ( m_aVisitedParams[nNext] & EF_VISITED )
306 // there is no such "not visited yet" entry -> simpy take the next one
307 nNext = (nCurrent + 1) % nCount;
309 m_aAllParams.SelectEntryPos(nNext);
310 LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams);
311 m_bNeedErrorOnCurrent = sal_True;
312 // we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
313 // so the next time it is called we need an error message, again ....
314 // (TODO : there surely are better solutions for this ...)
317 return 0L;
320 //------------------------------------------------------------------------------
321 IMPL_LINK(OParameterDialog, OnEntrySelected, ListBox*, /*pList*/)
323 if (m_aResetVisitFlag.IsActive())
325 LINK(this, OParameterDialog, OnVisitedTimeout).Call(&m_aResetVisitFlag);
326 m_aResetVisitFlag.Stop();
328 // save the old values
329 if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
331 // do the transformation of the current text
332 if (LINK(this, OParameterDialog, OnValueLoseFocus).Call(&m_aParam) != 0L)
333 { // there was an error interpreting the text
334 m_aAllParams.SelectEntryPos(m_nCurrentlySelected);
335 return 1L;
338 m_aFinalValues[m_nCurrentlySelected].Value <<= ::rtl::OUString(m_aParam.GetText());
341 // initialize the controls with the new values
342 sal_uInt16 nSelected = m_aAllParams.GetSelectEntryPos();
343 OSL_ENSURE(nSelected != LISTBOX_ENTRY_NOTFOUND, "OParameterDialog::OnEntrySelected : no current entry !");
345 m_aParam.SetText(::comphelper::getString(m_aFinalValues[nSelected].Value));
346 m_nCurrentlySelected = nSelected;
348 // with this the value isn't dirty
349 OSL_ENSURE(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnEntrySelected : invalid current entry !");
350 m_aVisitedParams[m_nCurrentlySelected] &= ~EF_DIRTY;
352 m_aResetVisitFlag.SetTimeout(1000);
353 m_aResetVisitFlag.Start();
355 return 0L;
358 //------------------------------------------------------------------------------
359 IMPL_LINK(OParameterDialog, OnVisitedTimeout, Timer*, /*pTimer*/)
361 OSL_ENSURE(m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND, "OParameterDialog::OnVisitedTimeout : invalid call !");
363 // mark the currently selected entry as visited
364 OSL_ENSURE(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnVisitedTimeout : invalid entry !");
365 m_aVisitedParams[m_nCurrentlySelected] |= EF_VISITED;
367 // was it the last "not visited yet" entry ?
368 ConstByteVectorIterator aIter;
369 for ( aIter = m_aVisitedParams.begin();
370 aIter < m_aVisitedParams.end();
371 ++aIter
374 if (((*aIter) & EF_VISITED) == 0)
375 break;
377 if (aIter == m_aVisitedParams.end())
378 { // yes, there isn't another one -> change the "default button"
379 m_aTravelNext.SetStyle(m_aTravelNext.GetStyle() & ~WB_DEFBUTTON);
380 m_aOKBtn.SetStyle(m_aOKBtn.GetStyle() | WB_DEFBUTTON);
382 // set to focus to one of the buttons temporary (with this their "default"-state is really updated)
383 Window* pOldFocus = Application::GetFocusWindow();
385 // if the old focus window is the value edit do some preparations ...
386 Selection aSel;
387 if (pOldFocus == &m_aParam)
389 m_aParam.SetLoseFocusHdl(Link());
390 aSel = m_aParam.GetSelection();
392 m_aTravelNext.GrabFocus();
393 if (pOldFocus)
394 pOldFocus->GrabFocus();
396 // restore the settings for the value edit
397 if (pOldFocus == &m_aParam)
399 m_aParam.SetLoseFocusHdl(LINK(this, OParameterDialog, OnValueLoseFocus));
400 m_aParam.SetSelection(aSel);
404 return 0L;
407 //------------------------------------------------------------------------------
408 IMPL_LINK(OParameterDialog, OnValueModified, Control*, /*pBox*/)
410 // mark the currently selected entry as dirty
411 OSL_ENSURE(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnValueModified : invalid entry !");
412 m_aVisitedParams[m_nCurrentlySelected] |= EF_DIRTY;
414 m_bNeedErrorOnCurrent = sal_True;
416 return 0L;
420 //.........................................................................
421 } // namespace dbaui
422 //.........................................................................
424 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */