1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: paramdialog.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #ifndef _DBAUI_PARAMDIALOG_HXX_
35 #include "paramdialog.hxx"
37 #ifndef _DBAUI_PARAMDIALOG_HRC_
38 #include "paramdialog.hrc"
41 #include "dbu_dlg.hrc"
43 #ifndef _DBAUI_COMMON_TYPES_HXX_
44 #include "commontypes.hxx"
46 #ifndef _DBAUI_MODULE_DBU_HXX_
47 #include "moduledbu.hxx"
49 #ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
50 #include <com/sun/star/util/XNumberFormatter.hpp>
52 #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
53 #include <com/sun/star/sdbc/DataType.hpp>
55 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
56 #include <connectivity/dbtools.hxx>
58 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
59 #include "dbustrings.hrc"
62 #include <vcl/svapp.hxx>
64 #ifndef _SV_MSGBOX_HXX
65 #include <vcl/msgbox.hxx>
67 #ifndef _TOOLS_DEBUG_HXX
68 #include <tools/debug.hxx>
70 #include <tools/diagnose_ex.h>
71 #ifndef _DBAUI_LOCALRESACCESS_HXX_
72 #include "localresaccess.hxx"
74 #ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
75 #include <svtools/syslocale.hxx>
78 #define EF_VISITED 0x0001
79 #define EF_DIRTY 0x0002
81 //.........................................................................
84 //.........................................................................
86 using namespace ::com::sun::star::uno
;
87 using namespace ::com::sun::star::lang
;
88 using namespace ::com::sun::star::beans
;
89 using namespace ::com::sun::star::container
;
90 using namespace ::com::sun::star::sdbc
;
91 using namespace ::com::sun::star::util
;
92 using namespace ::connectivity
;
94 //==================================================================
96 //==================================================================
98 //------------------------------------------------------------------------------
99 #define INIT_MEMBERS() \
100 :ModalDialog( pParent, ModuleRes(DLG_PARAMETERS)) \
101 ,m_aNamesFrame (this, ModuleRes(FL_PARAMS)) \
102 ,m_aAllParams (this, ModuleRes(LB_ALLPARAMS)) \
103 ,m_aValueFrame (this, ModuleRes(FT_VALUE)) \
104 ,m_aParam (this, ModuleRes(ET_PARAM)) \
105 ,m_aTravelNext (this, ModuleRes(BT_TRAVELNEXT)) \
106 ,m_aOKBtn (this, ModuleRes(BT_OK)) \
107 ,m_aCancelBtn (this, ModuleRes(BT_CANCEL)) \
108 ,m_nCurrentlySelected(LISTBOX_ENTRY_NOTFOUND) \
109 ,m_xConnection(_rxConnection) \
110 ,m_aPredicateInput( _rxORB, _rxConnection, getParseContext() ) \
111 ,m_bNeedErrorOnCurrent(sal_True) \
114 //------------------------------------------------------------------------------
115 DBG_NAME(OParameterDialog
)
117 OParameterDialog::OParameterDialog(
118 Window
* pParent
, const Reference
< XIndexAccess
> & rParamContainer
,
119 const Reference
< XConnection
> & _rxConnection
, const Reference
< XMultiServiceFactory
>& _rxORB
)
122 DBG_CTOR(OParameterDialog
,NULL
);
125 m_xFormatter
= Reference
< XNumberFormatter
>(_rxORB
->createInstance(
126 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.NumberFormatter"))), UNO_QUERY
);
128 DBG_ERROR("OParameterDialog::OParameterDialog: need a service factory!");
131 Reference
< XNumberFormatsSupplier
> xNumberFormats
= ::dbtools::getNumberFormats(m_xConnection
, sal_True
);
132 if (!xNumberFormats
.is())
133 ::comphelper::disposeComponent(m_xFormatter
);
134 else if (m_xFormatter
.is())
135 m_xFormatter
->attachNumberFormatsSupplier(xNumberFormats
);
138 DBG_ASSERT(rParamContainer
->getCount(), "OParameterDialog::OParameterDialog : can't handle empty containers !");
140 m_aFinalValues
.realloc(rParamContainer
->getCount());
141 PropertyValue
* pValues
= m_aFinalValues
.getArray();
143 for (sal_Int32 i
= 0, nCount
= rParamContainer
->getCount(); i
<nCount
; ++i
, ++pValues
)
145 Reference
< XPropertySet
> xParamAsSet
;
146 rParamContainer
->getByIndex(i
) >>= xParamAsSet
;
147 OSL_ENSURE(xParamAsSet
.is(),"Parameter is null!");
148 if(!xParamAsSet
.is())
150 pValues
->Name
= ::comphelper::getString(xParamAsSet
->getPropertyValue(PROPERTY_NAME
));
151 m_aAllParams
.InsertEntry(pValues
->Name
);
153 if (!pValues
->Value
.hasValue())
154 // it won't have a value, 'cause it's default constructed. But may be later we support
155 // initializing this dialog with values
156 pValues
->Value
= makeAny(::rtl::OUString());
157 // default the values to an empty string
159 m_aVisitedParams
.push_back(0);
160 // not visited, not dirty
163 m_xParams
= rParamContainer
;
167 DBG_UNHANDLED_EXCEPTION();
173 m_aResetVisitFlag
.SetTimeoutHdl(LINK(this, OParameterDialog
, OnVisitedTimeout
));
178 //------------------------------------------------------------------------------
179 OParameterDialog::~OParameterDialog()
181 if (m_aResetVisitFlag
.IsActive())
182 m_aResetVisitFlag
.Stop();
184 DBG_DTOR(OParameterDialog
,NULL
);
187 //------------------------------------------------------------------------------
188 void OParameterDialog::Construct()
190 m_aAllParams
.SetSelectHdl(LINK(this, OParameterDialog
, OnEntrySelected
));
191 m_aParam
.SetLoseFocusHdl(LINK(this, OParameterDialog
, OnValueLoseFocus
));
192 m_aParam
.SetModifyHdl(LINK(this, OParameterDialog
, OnValueModified
));
193 m_aTravelNext
.SetClickHdl(LINK(this, OParameterDialog
, OnButtonClicked
));
194 m_aOKBtn
.SetClickHdl(LINK(this, OParameterDialog
, OnButtonClicked
));
195 m_aCancelBtn
.SetClickHdl(LINK(this, OParameterDialog
, OnButtonClicked
));
197 if (m_aAllParams
.GetEntryCount())
199 m_aAllParams
.SelectEntryPos(0);
200 LINK(this, OParameterDialog
, OnEntrySelected
).Call(&m_aAllParams
);
202 if (m_aAllParams
.GetEntryCount() == 1)
204 m_aTravelNext
.Enable(sal_False
);
207 if (m_aAllParams
.GetEntryCount() > 1)
209 m_aOKBtn
.SetStyle(m_aOKBtn
.GetStyle() & ~WB_DEFBUTTON
);
210 m_aTravelNext
.SetStyle(m_aTravelNext
.GetStyle() | WB_DEFBUTTON
);
214 m_aParam
.GrabFocus();
217 //------------------------------------------------------------------------------
218 IMPL_LINK(OParameterDialog
, OnValueLoseFocus
, Control
*, /*pSource*/)
220 if (m_nCurrentlySelected
!= LISTBOX_ENTRY_NOTFOUND
)
222 if ( ( m_aVisitedParams
[ m_nCurrentlySelected
] & EF_DIRTY
) == 0 )
223 // nothing to do, the value isn't dirty
227 // transform the current string according to the param field type
228 ::rtl::OUString
sTransformedText(m_aParam
.GetText());
229 Reference
< XPropertySet
> xParamAsSet
;
230 m_xParams
->getByIndex(m_nCurrentlySelected
) >>= xParamAsSet
;
231 if (xParamAsSet
.is())
233 if (m_xConnection
.is() && m_xFormatter
.is())
235 ::rtl::OUString
sParamValue( m_aParam
.GetText() );
236 sal_Bool bValid
= m_aPredicateInput
.normalizePredicateString( sParamValue
, xParamAsSet
);
237 m_aParam
.SetText( sParamValue
);
240 // with this the value isn't dirty anymore
241 if (m_nCurrentlySelected
!= LISTBOX_ENTRY_NOTFOUND
)
242 m_aVisitedParams
[m_nCurrentlySelected
] &= ~EF_DIRTY
;
246 if (!m_bNeedErrorOnCurrent
)
249 m_bNeedErrorOnCurrent
= sal_False
; // will be reset in OnValueModified
251 ::rtl::OUString sName
;
254 sName
= ::comphelper::getString(xParamAsSet
->getPropertyValue(PROPERTY_NAME
));
258 DBG_UNHANDLED_EXCEPTION();
263 LocalResourceAccess
aDummy(DLG_PARAMETERS
, RSC_MODALDIALOG
);
264 sMessage
= String(ModuleRes(STR_COULD_NOT_CONVERT_PARAM
));
266 sMessage
.SearchAndReplaceAll(String::CreateFromAscii("$name$"), sName
.getStr());
267 ErrorBox(NULL
, WB_OK
, sMessage
).Execute();
268 m_aParam
.GrabFocus();
277 //------------------------------------------------------------------------------
278 IMPL_LINK(OParameterDialog
, OnButtonClicked
, PushButton
*, pButton
)
280 if (&m_aCancelBtn
== pButton
)
282 // no interpreting of the given values anymore ....
283 m_aParam
.SetLoseFocusHdl(Link()); // no direct call from the control anymore ...
284 m_bNeedErrorOnCurrent
= sal_False
; // in case of any indirect calls -> no error message
285 m_aCancelBtn
.SetClickHdl(Link());
286 m_aCancelBtn
.Click();
288 else if (&m_aOKBtn
== pButton
)
290 // transfer the current values into the Any
291 if (LINK(this, OParameterDialog
, OnEntrySelected
).Call(&m_aAllParams
) != 0L)
292 { // there was an error interpreting the current text
293 m_bNeedErrorOnCurrent
= sal_True
;
294 // we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
295 // so the next time it is called we need an error message, again ....
296 // (TODO : there surely are better solutions for this ...)
302 // write the parameters
305 ::rtl::OUString sError
;
306 PropertyValue
* pValues
= m_aFinalValues
.getArray();
307 for (sal_Int32 i
= 0, nCount
= m_xParams
->getCount(); i
<nCount
; ++i
, ++pValues
)
309 Reference
< XPropertySet
> xParamAsSet
;
310 m_xParams
->getByIndex(i
) >>= xParamAsSet
;
312 ::rtl::OUString sValue
;
313 pValues
->Value
>>= sValue
;
314 pValues
->Value
<<= ::rtl::OUString( m_aPredicateInput
.getPredicateValue( sValue
, xParamAsSet
, sal_False
) );
319 DBG_UNHANDLED_EXCEPTION();
323 // to close the dialog (which is more code than a simple EndDialog)
324 m_aOKBtn
.SetClickHdl(Link());
327 else if (&m_aTravelNext
== pButton
)
329 sal_uInt16 nCurrent
= m_aAllParams
.GetSelectEntryPos();
330 sal_uInt16 nCount
= m_aAllParams
.GetEntryCount();
331 DBG_ASSERT(nCount
== m_aVisitedParams
.size(), "OParameterDialog::OnButtonClicked : inconsistent lists !");
333 // search the next entry in list we haven't visited yet
334 sal_uInt16 nNext
= (nCurrent
+ 1) % nCount
;
335 while ((nNext
!= nCurrent
) && ( m_aVisitedParams
[nNext
] & EF_VISITED
))
336 nNext
= (nNext
+ 1) % nCount
;
338 if ( m_aVisitedParams
[nNext
] & EF_VISITED
)
339 // there is no such "not visited yet" entry -> simpy take the next one
340 nNext
= (nCurrent
+ 1) % nCount
;
342 m_aAllParams
.SelectEntryPos(nNext
);
343 LINK(this, OParameterDialog
, OnEntrySelected
).Call(&m_aAllParams
);
344 m_bNeedErrorOnCurrent
= sal_True
;
345 // we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
346 // so the next time it is called we need an error message, again ....
347 // (TODO : there surely are better solutions for this ...)
353 //------------------------------------------------------------------------------
354 IMPL_LINK(OParameterDialog
, OnEntrySelected
, ListBox
*, /*pList*/)
356 if (m_aResetVisitFlag
.IsActive())
358 LINK(this, OParameterDialog
, OnVisitedTimeout
).Call(&m_aResetVisitFlag
);
359 m_aResetVisitFlag
.Stop();
361 // save the old values
362 if (m_nCurrentlySelected
!= LISTBOX_ENTRY_NOTFOUND
)
364 // do the transformation of the current text
365 if (LINK(this, OParameterDialog
, OnValueLoseFocus
).Call(&m_aParam
) != 0L)
366 { // there was an error interpreting the text
367 m_aAllParams
.SelectEntryPos(m_nCurrentlySelected
);
371 m_aFinalValues
[m_nCurrentlySelected
].Value
<<= ::rtl::OUString(m_aParam
.GetText());
374 // initialize the controls with the new values
375 sal_uInt16 nSelected
= m_aAllParams
.GetSelectEntryPos();
376 DBG_ASSERT(nSelected
!= LISTBOX_ENTRY_NOTFOUND
, "OParameterDialog::OnEntrySelected : no current entry !");
378 m_aParam
.SetText(::comphelper::getString(m_aFinalValues
[nSelected
].Value
));
379 m_nCurrentlySelected
= nSelected
;
381 // with this the value isn't dirty
382 DBG_ASSERT(m_nCurrentlySelected
< m_aVisitedParams
.size(), "OParameterDialog::OnEntrySelected : invalid current entry !");
383 m_aVisitedParams
[m_nCurrentlySelected
] &= ~EF_DIRTY
;
385 m_aResetVisitFlag
.SetTimeout(1000);
386 m_aResetVisitFlag
.Start();
391 //------------------------------------------------------------------------------
392 IMPL_LINK(OParameterDialog
, OnVisitedTimeout
, Timer
*, /*pTimer*/)
394 DBG_ASSERT(m_nCurrentlySelected
!= LISTBOX_ENTRY_NOTFOUND
, "OParameterDialog::OnVisitedTimeout : invalid call !");
396 // mark the currently selected entry as visited
397 DBG_ASSERT(m_nCurrentlySelected
< m_aVisitedParams
.size(), "OParameterDialog::OnVisitedTimeout : invalid entry !");
398 m_aVisitedParams
[m_nCurrentlySelected
] |= EF_VISITED
;
400 // was it the last "not visited yet" entry ?
401 ConstByteVectorIterator aIter
;
402 for ( aIter
= m_aVisitedParams
.begin();
403 aIter
< m_aVisitedParams
.end();
407 if (((*aIter
) & EF_VISITED
) == 0)
410 if (aIter
== m_aVisitedParams
.end())
411 { // yes, there isn't another one -> change the "default button"
412 m_aTravelNext
.SetStyle(m_aTravelNext
.GetStyle() & ~WB_DEFBUTTON
);
413 m_aOKBtn
.SetStyle(m_aOKBtn
.GetStyle() | WB_DEFBUTTON
);
415 // set to focus to one of the buttons temporary (with this their "default"-state is really updated)
416 Window
* pOldFocus
= Application::GetFocusWindow();
418 // if the old focus window is the value edit do some preparations ...
420 if (pOldFocus
== &m_aParam
)
422 m_aParam
.SetLoseFocusHdl(Link());
423 aSel
= m_aParam
.GetSelection();
425 m_aTravelNext
.GrabFocus();
427 pOldFocus
->GrabFocus();
429 // restore the settings for the value edit
430 if (pOldFocus
== &m_aParam
)
432 m_aParam
.SetLoseFocusHdl(LINK(this, OParameterDialog
, OnValueLoseFocus
));
433 m_aParam
.SetSelection(aSel
);
440 //------------------------------------------------------------------------------
441 IMPL_LINK(OParameterDialog
, OnValueModified
, Control
*, /*pBox*/)
443 // mark the currently selected entry as dirty
444 DBG_ASSERT(m_nCurrentlySelected
< m_aVisitedParams
.size(), "OParameterDialog::OnValueModified : invalid entry !");
445 m_aVisitedParams
[m_nCurrentlySelected
] |= EF_DIRTY
;
447 m_bNeedErrorOnCurrent
= sal_True
;
453 //.........................................................................
455 //.........................................................................