xref: /trunk/main/dbaccess/source/ui/browser/brwctrlr.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 
32 
33 #include "browserids.hxx"
34 #include "brwctrlr.hxx"
35 #include "brwview.hxx"
36 #include "dbu_brw.hrc"
37 #include "dbustrings.hrc"
38 #include "queryfilter.hxx"
39 #include "queryorder.hxx"
40 #include "sqlmessage.hxx"
41 
42 /** === begin UNO includes === **/
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 #include <com/sun/star/container/XNamed.hpp>
46 #include <com/sun/star/form/FormButtonType.hpp>
47 #include <com/sun/star/form/FormSubmitEncoding.hpp>
48 #include <com/sun/star/form/FormSubmitMethod.hpp>
49 #include <com/sun/star/form/XApproveActionBroadcaster.hpp>
50 #include <com/sun/star/form/XBoundControl.hpp>
51 #include <com/sun/star/form/XChangeBroadcaster.hpp>
52 #include <com/sun/star/form/XChangeListener.hpp>
53 #include <com/sun/star/form/XDatabaseParameterBroadcaster.hpp>
54 #include <com/sun/star/form/XLoadable.hpp>
55 #include <com/sun/star/form/XReset.hpp>
56 #include <com/sun/star/form/XResetListener.hpp>
57 #include <com/sun/star/form/XSubmit.hpp>
58 #include <com/sun/star/form/XSubmitListener.hpp>
59 #include <com/sun/star/form/runtime/XFormController.hpp>
60 #include <com/sun/star/sdb/CommandType.hpp>
61 #include <com/sun/star/sdb/ErrorCondition.hpp>
62 #include <com/sun/star/sdb/ParametersRequest.hpp>
63 #include <com/sun/star/sdb/SQLContext.hpp>
64 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
65 #include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
66 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
67 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
68 #include <com/sun/star/sdbc/XConnection.hpp>
69 #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
70 #include <com/sun/star/sdbc/XRowSetListener.hpp>
71 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
72 #include <com/sun/star/sdbcx/Privilege.hpp>
73 #include <com/sun/star/sdbcx/XRowLocate.hpp>
74 #include <com/sun/star/task/XInteractionHandler.hpp>
75 #include <com/sun/star/uno/TypeClass.hpp>
76 #include <com/sun/star/util/XCancellable.hpp>
77 /** === end UNO includes === **/
78 
79 #include <comphelper/enumhelper.hxx>
80 #include <comphelper/extract.hxx>
81 #include <comphelper/interaction.hxx>
82 #include <comphelper/sequence.hxx>
83 #include <connectivity/dbexception.hxx>
84 #include <connectivity/dbtools.hxx>
85 #include <connectivity/sqlerror.hxx>
86 #include <cppuhelper/exc_hlp.hxx>
87 #include <cppuhelper/implbase2.hxx>
88 #include <cppuhelper/typeprovider.hxx>
89 #include <osl/mutex.hxx>
90 #include <rtl/logfile.hxx>
91 #include <sfx2/app.hxx>
92 #include <sfx2/sfx.hrc>
93 #include <svx/fmsearch.hxx>
94 #include <svx/svxdlg.hxx>
95 #include <tools/color.hxx>
96 #include <tools/diagnose_ex.h>
97 #include <vcl/msgbox.hxx>
98 #include <vcl/waitobj.hxx>
99 
100 using namespace ::com::sun::star::uno;
101 using namespace ::com::sun::star::awt;
102 using namespace ::com::sun::star::sdb;
103 using namespace ::com::sun::star::sdbc;
104 using namespace ::com::sun::star::sdbcx;
105 using namespace ::com::sun::star::task;
106 using namespace ::com::sun::star::beans;
107 using namespace ::com::sun::star::frame;
108 using namespace ::com::sun::star::form;
109 using namespace ::com::sun::star::util;
110 using namespace ::com::sun::star::lang;
111 using namespace ::com::sun::star::container;
112 using namespace ::dbtools;
113 using namespace ::comphelper;
114 using namespace ::svt;
115 
116 #define HANDLE_SQL_ERRORS( action, successflag, context, message )          \
117     try                                                                     \
118     {                                                                       \
119         successflag = sal_False;                                            \
120         action;                                                             \
121         successflag = sal_True;                                             \
122     }                                                                       \
123     catch(SQLException& e)                                                  \
124     {                                                                       \
125         SQLException aError = ::dbtools::prependErrorInfo(e, *this, context); \
126         ::com::sun::star::sdb::SQLErrorEvent aEvent;                        \
127         aEvent.Reason <<= aError;                                           \
128         errorOccured(aEvent);                                               \
129     }                                                                       \
130     catch(Exception&)                                                       \
131     {                                                                       \
132         DBG_UNHANDLED_EXCEPTION();                                          \
133     }                                                                       \
134 
135 #define DO_SAFE( action, message ) try { action; } catch(Exception&) { DBG_ERROR(message); } ;
136 
137 //..................................................................
138 namespace dbaui
139 {
140 //..................................................................
141 
142 //==================================================================
143 // OParameterContinuation
144 //==================================================================
145 class OParameterContinuation : public OInteraction< XInteractionSupplyParameters >
146 {
147     Sequence< PropertyValue >       m_aValues;
148 
149 public:
150     OParameterContinuation() { }
151 
152     Sequence< PropertyValue >   getValues() const { return m_aValues; }
153 
154 // XInteractionSupplyParameters
155     virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException);
156 };
157 
158 //------------------------------------------------------------------
159 void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException)
160 {
161     m_aValues = _rValues;
162 }
163 
164 
165 //==============================================================================
166 // a helper class implementing a runtime::XFormController, will be aggregated by SbaXDataBrowserController
167 // (we can't derive from XFormController as it's base class is XTabController and the XTabController::getModel collides
168 // with the XController::getModel implemented in our base class SbaXDataBrowserController)
169 class SbaXDataBrowserController::FormControllerImpl
170     : public ::cppu::WeakAggImplHelper2< ::com::sun::star::form::runtime::XFormController,
171                                          ::com::sun::star::frame::XFrameActionListener >
172 {
173     friend class SbaXDataBrowserController;
174     ::cppu::OInterfaceContainerHelper   m_aActivateListeners;
175     SbaXDataBrowserController*          m_pOwner;
176 
177 public:
178     FormControllerImpl(SbaXDataBrowserController* pOwner);
179 
180     // XFormController
181     virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormOperations > SAL_CALL getFormOperations() throw (::com::sun::star::uno::RuntimeException);
182     virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >  SAL_CALL getCurrentControl(void) throw( ::com::sun::star::uno::RuntimeException );
183     virtual void SAL_CALL addActivateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException );
184     virtual void SAL_CALL removeActivateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException );
185     virtual void SAL_CALL addChildController( const ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormController >& _ChildController ) throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );
186     virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormControllerContext > SAL_CALL getContext() throw (::com::sun::star::uno::RuntimeException);
187     virtual void SAL_CALL setContext( const ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormControllerContext >& _context ) throw (::com::sun::star::uno::RuntimeException);
188     virtual ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > SAL_CALL getInteractionHandler() throw (::com::sun::star::uno::RuntimeException);
189     virtual void SAL_CALL setInteractionHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _interactionHandler ) throw (::com::sun::star::uno::RuntimeException);
190 
191     // XChild, base of XFormController
192     virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent(  ) throw (::com::sun::star::uno::RuntimeException);
193     virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
194 
195     // XComponent, base of XFormController
196     virtual void SAL_CALL dispose(  ) throw (::com::sun::star::uno::RuntimeException);
197     virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
198     virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
199 
200     // XIndexAccess, base of XFormController
201     virtual ::sal_Int32 SAL_CALL getCount(  ) throw (::com::sun::star::uno::RuntimeException);
202     virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
203 
204     // XElementAccess, base of XIndexAccess
205     virtual ::com::sun::star::uno::Type SAL_CALL getElementType(  ) throw (::com::sun::star::uno::RuntimeException);
206     virtual ::sal_Bool SAL_CALL hasElements(  ) throw (::com::sun::star::uno::RuntimeException);
207 
208     // XEnumerationAccess, base of XElementAccess
209     virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration(  ) throw (::com::sun::star::uno::RuntimeException);
210 
211     // XModifyBroadcaster, base of XFormController
212     virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
213     virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
214 
215     // XConfirmDeleteBroadcaster, base of XFormController
216     virtual void SAL_CALL addConfirmDeleteListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XConfirmDeleteListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
217     virtual void SAL_CALL removeConfirmDeleteListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XConfirmDeleteListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
218 
219     // XSQLErrorBroadcaster, base of XFormController
220     virtual void SAL_CALL addSQLErrorListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
221     virtual void SAL_CALL removeSQLErrorListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
222 
223     // XRowSetApproveBroadcaster, base of XFormController
224     virtual void SAL_CALL addRowSetApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
225     virtual void SAL_CALL removeRowSetApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
226 
227     // XDatabaseParameterBroadcaster2, base of XFormController
228     virtual void SAL_CALL addDatabaseParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
229     virtual void SAL_CALL removeDatabaseParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
230 
231     // XDatabaseParameterBroadcaster, base of XDatabaseParameterBroadcaster2
232     virtual void SAL_CALL addParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
233     virtual void SAL_CALL removeParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
234 
235     // XModeSelector, base of XFormController
236     virtual void SAL_CALL setMode( const ::rtl::OUString& aMode ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
237     virtual ::rtl::OUString SAL_CALL getMode(  ) throw (::com::sun::star::uno::RuntimeException);
238     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedModes(  ) throw (::com::sun::star::uno::RuntimeException);
239     virtual ::sal_Bool SAL_CALL supportsMode( const ::rtl::OUString& aMode ) throw (::com::sun::star::uno::RuntimeException);
240 
241     // XTabController, base of XFormController
242     virtual void SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel > & Model) throw( ::com::sun::star::uno::RuntimeException );
243     virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel >  SAL_CALL getModel(void) throw( ::com::sun::star::uno::RuntimeException );
244     virtual void SAL_CALL setContainer(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > & _Container) throw( ::com::sun::star::uno::RuntimeException );
245     virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer >  SAL_CALL getContainer(void) throw( ::com::sun::star::uno::RuntimeException );
246     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >  > SAL_CALL getControls(void) throw( ::com::sun::star::uno::RuntimeException );
247     virtual void SAL_CALL autoTabOrder(void) throw( ::com::sun::star::uno::RuntimeException );
248     virtual void SAL_CALL activateTabOrder(void) throw( ::com::sun::star::uno::RuntimeException );
249     virtual void SAL_CALL activateFirst(void) throw( ::com::sun::star::uno::RuntimeException );
250     virtual void SAL_CALL activateLast(void) throw( ::com::sun::star::uno::RuntimeException );
251 
252     // XFrameActionListener
253     virtual void SAL_CALL frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( ::com::sun::star::uno::RuntimeException );
254 
255     // XEventListener
256     virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( ::com::sun::star::uno::RuntimeException );
257 
258 protected:
259     ~FormControllerImpl();
260 };
261 
262 
263 DBG_NAME(FormControllerImpl)
264 //------------------------------------------------------------------
265 SbaXDataBrowserController::FormControllerImpl::FormControllerImpl(SbaXDataBrowserController* _pOwner)
266     :m_aActivateListeners(_pOwner->getMutex())
267     ,m_pOwner(_pOwner)
268 {
269     DBG_CTOR(FormControllerImpl,NULL);
270 
271     OSL_ENSURE(m_pOwner, "SbaXDataBrowserController::FormControllerImpl::FormControllerImpl : invalid Owner !");
272 }
273 
274 //------------------------------------------------------------------
275 SbaXDataBrowserController::FormControllerImpl::~FormControllerImpl()
276 {
277 
278     DBG_DTOR(FormControllerImpl,NULL);
279 }
280 
281 //------------------------------------------------------------------
282 Reference< runtime::XFormOperations > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getFormOperations() throw (RuntimeException)
283 {
284     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::getFormOperations: not supported!" );
285     return NULL;
286 }
287 
288 //------------------------------------------------------------------
289 Reference< ::com::sun::star::awt::XControl >  SbaXDataBrowserController::FormControllerImpl::getCurrentControl(void) throw( RuntimeException )
290 {
291     return m_pOwner->getBrowserView() ? m_pOwner->getBrowserView()->getGridControl() : Reference< ::com::sun::star::awt::XControl > ();
292 }
293 
294 //------------------------------------------------------------------
295 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addActivateListener(const Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( RuntimeException )
296 {
297     m_aActivateListeners.addInterface(l);
298 }
299 
300 //------------------------------------------------------------------
301 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeActivateListener(const Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( RuntimeException )
302 {
303     m_aActivateListeners.removeInterface(l);
304 }
305 
306 //------------------------------------------------------------------
307 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addChildController( const Reference< runtime::XFormController >& /*_ChildController*/ ) throw( RuntimeException, IllegalArgumentException )
308 {
309     // not supported
310     throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
311 }
312 
313 //------------------------------------------------------------------
314 Reference< runtime::XFormControllerContext > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getContext() throw (RuntimeException)
315 {
316     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::getContext: no support!!" );
317     return NULL;
318 }
319 
320 //------------------------------------------------------------------
321 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setContext( const Reference< runtime::XFormControllerContext >& /*_context*/ ) throw (RuntimeException)
322 {
323     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::setContext: no support!!" );
324 }
325 
326 //------------------------------------------------------------------
327 Reference< XInteractionHandler > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getInteractionHandler() throw (RuntimeException)
328 {
329     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::getInteractionHandler: no support!!" );
330     return NULL;
331 }
332 
333 //------------------------------------------------------------------
334 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setInteractionHandler( const Reference< XInteractionHandler >& /*_interactionHandler*/ ) throw (RuntimeException)
335 {
336     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::setInteractionHandler: no support!!" );
337 }
338 
339 //------------------------------------------------------------------
340 Reference< XInterface > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getParent(  ) throw (RuntimeException)
341 {
342     // don't have any parent form controllers
343     return NULL;
344 }
345 
346 //------------------------------------------------------------------
347 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setParent( const Reference< XInterface >& /*Parent*/ ) throw (NoSupportException, RuntimeException)
348 {
349     throw NoSupportException( ::rtl::OUString(), *this );
350 }
351 
352 //------------------------------------------------------------------
353 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::dispose(  ) throw (RuntimeException)
354 {
355     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::dispose: no, you do *not* want to do this!" );
356 }
357 
358 //------------------------------------------------------------------
359 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addEventListener( const Reference< XEventListener >& /*xListener*/ ) throw (RuntimeException)
360 {
361     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addEventListener: no support!!" );
362 }
363 
364 //------------------------------------------------------------------
365 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeEventListener( const Reference< XEventListener >& /*aListener*/ ) throw (RuntimeException)
366 {
367     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeEventListener: no support!!" );
368 }
369 
370 //------------------------------------------------------------------
371 ::sal_Int32 SAL_CALL SbaXDataBrowserController::FormControllerImpl::getCount(  ) throw (RuntimeException)
372 {
373     // no sub controllers, never
374     return 0;
375 }
376 
377 //------------------------------------------------------------------
378 Any SAL_CALL SbaXDataBrowserController::FormControllerImpl::getByIndex( ::sal_Int32 /*Index*/ ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
379 {
380     // no sub controllers, never
381     throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
382 }
383 
384 //------------------------------------------------------------------
385 Type SAL_CALL SbaXDataBrowserController::FormControllerImpl::getElementType(  ) throw (RuntimeException)
386 {
387     return ::cppu::UnoType< runtime::XFormController >::get();
388 }
389 
390 //------------------------------------------------------------------
391 ::sal_Bool SAL_CALL SbaXDataBrowserController::FormControllerImpl::hasElements(  ) throw (RuntimeException)
392 {
393     // no sub controllers, never
394     return false;
395 }
396 
397 //------------------------------------------------------------------
398 Reference< XEnumeration > SAL_CALL SbaXDataBrowserController::FormControllerImpl::createEnumeration(  ) throw (RuntimeException)
399 {
400     return new ::comphelper::OEnumerationByIndex( this );
401 }
402 
403 //------------------------------------------------------------------
404 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addModifyListener( const Reference< XModifyListener >& /*_Listener*/ ) throw (RuntimeException)
405 {
406     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addModifyListener: no support!" );
407 }
408 
409 //------------------------------------------------------------------
410 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeModifyListener( const Reference< XModifyListener >& /*_Listener*/ ) throw (RuntimeException)
411 {
412     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeModifyListener: no support!" );
413 }
414 
415 //------------------------------------------------------------------
416 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addConfirmDeleteListener( const Reference< XConfirmDeleteListener >& /*_Listener*/ ) throw (RuntimeException)
417 {
418     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addConfirmDeleteListener: no support!" );
419 }
420 
421 //------------------------------------------------------------------
422 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeConfirmDeleteListener( const Reference< XConfirmDeleteListener >& /*_Listener*/ ) throw (RuntimeException)
423 {
424     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeConfirmDeleteListener: no support!" );
425 }
426 
427 //------------------------------------------------------------------
428 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addSQLErrorListener( const Reference< XSQLErrorListener >& /*_Listener*/ ) throw (RuntimeException)
429 {
430     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addSQLErrorListener: no support!" );
431 }
432 
433 //------------------------------------------------------------------
434 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeSQLErrorListener( const Reference< XSQLErrorListener >& /*_Listener*/ ) throw (RuntimeException)
435 {
436     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeSQLErrorListener: no support!" );
437 }
438 
439 //------------------------------------------------------------------
440 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addRowSetApproveListener( const Reference< XRowSetApproveListener >& /*_Listener*/ ) throw (RuntimeException)
441 {
442     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addRowSetApproveListener: no support!" );
443 }
444 
445 //------------------------------------------------------------------
446 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeRowSetApproveListener( const Reference< XRowSetApproveListener >& /*_Listener*/ ) throw (RuntimeException)
447 {
448     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeRowSetApproveListener: no support!" );
449 }
450 
451 //------------------------------------------------------------------
452 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addDatabaseParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException)
453 {
454     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addDatabaseParameterListener: no support!" );
455 }
456 
457 //------------------------------------------------------------------
458 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeDatabaseParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException)
459 {
460     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeDatabaseParameterListener: no support!" );
461 }
462 
463 //------------------------------------------------------------------
464 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException)
465 {
466     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addParameterListener: no support!" );
467 }
468 
469 //------------------------------------------------------------------
470 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException)
471 {
472     OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeParameterListener: no support!" );
473 }
474 
475 //------------------------------------------------------------------
476 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setMode( const ::rtl::OUString& _rMode ) throw (NoSupportException, RuntimeException)
477 {
478     if ( !supportsMode( _rMode ) )
479         throw NoSupportException();
480 }
481 
482 //------------------------------------------------------------------
483 ::rtl::OUString SAL_CALL SbaXDataBrowserController::FormControllerImpl::getMode(  ) throw (RuntimeException)
484 {
485     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) );
486 }
487 
488 //------------------------------------------------------------------
489 Sequence< ::rtl::OUString > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getSupportedModes(  ) throw (RuntimeException)
490 {
491     Sequence< ::rtl::OUString > aModes(1);
492     aModes[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) );
493     return aModes;
494 }
495 
496 //------------------------------------------------------------------
497 ::sal_Bool SAL_CALL SbaXDataBrowserController::FormControllerImpl::supportsMode( const ::rtl::OUString& aMode ) throw (RuntimeException)
498 {
499     return aMode.compareToAscii( "DataMode" ) == 0;
500 }
501 
502 //------------------------------------------------------------------
503 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setModel(const Reference< ::com::sun::star::awt::XTabControllerModel > & /*Model*/) throw( RuntimeException )
504 {
505     OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::setModel : invalid call, can't change my model !");
506 }
507 
508 //------------------------------------------------------------------
509 Reference< ::com::sun::star::awt::XTabControllerModel >  SAL_CALL SbaXDataBrowserController::FormControllerImpl::getModel(void) throw( RuntimeException )
510 {
511     return Reference< XTabControllerModel >(m_pOwner->getRowSet(), UNO_QUERY);
512 }
513 
514 //------------------------------------------------------------------
515 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setContainer(const Reference< ::com::sun::star::awt::XControlContainer > & /*_Container*/) throw( RuntimeException )
516 {
517     OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::setContainer : invalid call, can't change my container !");
518 }
519 
520 //------------------------------------------------------------------
521 Reference< ::com::sun::star::awt::XControlContainer >  SAL_CALL SbaXDataBrowserController::FormControllerImpl::getContainer(void) throw( RuntimeException )
522 {
523     if (m_pOwner->getBrowserView())
524         return m_pOwner->getBrowserView()->getContainer();
525     return Reference< ::com::sun::star::awt::XControlContainer > ();
526 }
527 
528 //------------------------------------------------------------------
529 Sequence< Reference< ::com::sun::star::awt::XControl > > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getControls(void) throw( RuntimeException )
530 {
531     if (m_pOwner->getBrowserView())
532     {
533         Reference< ::com::sun::star::awt::XControl >  xGrid = m_pOwner->getBrowserView()->getGridControl();
534         return Sequence< Reference< ::com::sun::star::awt::XControl > >(&xGrid, 1);
535     }
536     return Sequence< Reference< ::com::sun::star::awt::XControl > >();
537 }
538 
539 //------------------------------------------------------------------
540 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::autoTabOrder(void) throw( RuntimeException )
541 {
542     OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::autoTabOrder : nothing to do (always have only one control) !");
543 }
544 
545 //------------------------------------------------------------------
546 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateTabOrder(void) throw( RuntimeException )
547 {
548     OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::activateTabOrder : nothing to do (always have only one control) !");
549 }
550 
551 //------------------------------------------------------------------
552 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateFirst(void) throw( RuntimeException )
553 {
554     if (m_pOwner->getBrowserView())
555         m_pOwner->getBrowserView()->getVclControl()->ActivateCell();
556 }
557 
558 //------------------------------------------------------------------
559 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateLast(void) throw( RuntimeException )
560 {
561     if (m_pOwner->getBrowserView())
562         m_pOwner->getBrowserView()->getVclControl()->ActivateCell();
563 }
564 
565 //------------------------------------------------------------------
566 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::frameAction(const ::com::sun::star::frame::FrameActionEvent& /*aEvent*/) throw( RuntimeException )
567 {
568 }
569 
570 //------------------------------------------------------------------
571 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::disposing(const ::com::sun::star::lang::EventObject& /*Source*/) throw( RuntimeException )
572 {
573     // nothing to do
574     // we don't add ourself as listener to any broadcasters, so we are not resposible for removing us
575 }
576 
577 //==================================================================
578 //= SbaXDataBrowserController
579 //==================================================================
580 //------------------------------------------------------------------
581 Sequence< Type > SAL_CALL SbaXDataBrowserController::getTypes(  ) throw (RuntimeException)
582 {
583     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getTypes" );
584     return ::comphelper::concatSequences(
585         SbaXDataBrowserController_Base::getTypes(),
586         m_pFormControllerImpl->getTypes()
587     );
588 }
589 
590 //------------------------------------------------------------------
591 Sequence< sal_Int8 > SAL_CALL SbaXDataBrowserController::getImplementationId(  ) throw (RuntimeException)
592 {
593     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getImplementationId" );
594     static ::cppu::OImplementationId * pId = 0;
595     if (! pId)
596     {
597         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
598         if (! pId)
599         {
600             static ::cppu::OImplementationId aId;
601             pId = &aId;
602         }
603     }
604     return pId->getImplementationId();
605 }
606 
607 //------------------------------------------------------------------
608 Any SAL_CALL SbaXDataBrowserController::queryInterface(const Type& _rType) throw (RuntimeException)
609 {
610     // check for our additional interfaces
611     Any aRet = SbaXDataBrowserController_Base::queryInterface(_rType);
612 
613     // check for our aggregate (implementing the XFormController)
614     if (!aRet.hasValue())
615         aRet = m_xFormControllerImpl->queryAggregation(_rType);
616 
617     // no more to offer
618     return aRet;
619 }
620 
621 DBG_NAME(SbaXDataBrowserController)
622 //------------------------------------------------------------------------------
623 SbaXDataBrowserController::SbaXDataBrowserController(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
624     :SbaXDataBrowserController_Base(_rM)
625     ,m_nRowSetPrivileges(0)
626     ,m_pClipbordNotifier( NULL )
627     ,m_aAsyncGetCellFocus(LINK(this, SbaXDataBrowserController, OnAsyncGetCellFocus))
628     ,m_aAsyncDisplayError( LINK( this, SbaXDataBrowserController, OnAsyncDisplayError ) )
629     ,m_sStateSaveRecord(ModuleRes(RID_STR_SAVE_CURRENT_RECORD))
630     ,m_sStateUndoRecord(ModuleRes(RID_STR_UNDO_MODIFY_RECORD))
631     ,m_sModuleIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataSourceBrowser" ) ) )
632     ,m_pFormControllerImpl(NULL)
633     ,m_nPendingLoadFinished(0)
634     ,m_nFormActionNestingLevel(0)
635     ,m_bLoadCanceled( sal_False )
636     ,m_bClosingKillOpen( sal_False )
637     ,m_bCannotSelectUnfiltered( true )
638 {
639     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SbaXDataBrowserController" );
640     DBG_CTOR(SbaXDataBrowserController,NULL);
641 
642     // create the form controller aggregate
643     ::comphelper::increment(m_refCount);
644     {
645         m_pFormControllerImpl = new FormControllerImpl(this);
646         m_xFormControllerImpl = m_pFormControllerImpl;
647         m_xFormControllerImpl->setDelegator(*this);
648     }
649     ::comphelper::decrement(m_refCount);
650 
651     m_aInvalidateClipboard.SetTimeoutHdl(LINK(this, SbaXDataBrowserController, OnInvalidateClipboard));
652     m_aInvalidateClipboard.SetTimeout(300);
653 }
654 
655 //------------------------------------------------------------------------------
656 SbaXDataBrowserController::~SbaXDataBrowserController()
657 {
658     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::~SbaXDataBrowserController" );
659     //  deleteView();
660     // release the aggregated form controller
661     if (m_xFormControllerImpl.is())
662     {
663         Reference< XInterface >  xEmpty;
664         m_xFormControllerImpl->setDelegator(xEmpty);
665     }
666 
667     DBG_DTOR(SbaXDataBrowserController,NULL);
668 }
669 
670 // -----------------------------------------------------------------------
671 void SbaXDataBrowserController::startFrameListening( const Reference< XFrame >& _rxFrame )
672 {
673     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::startFrameListening" );
674     SbaXDataBrowserController_Base::startFrameListening( _rxFrame );
675 
676     Reference< XFrameActionListener >   xAggListener;
677     if ( m_xFormControllerImpl.is() )
678         m_xFormControllerImpl->queryAggregation( XFrameActionListener::static_type() ) >>= xAggListener;
679 
680     if ( _rxFrame.is() && xAggListener.is() )
681         _rxFrame->addFrameActionListener( xAggListener );
682 }
683 
684 // -----------------------------------------------------------------------
685 void SbaXDataBrowserController::stopFrameListening( const Reference< XFrame >& _rxFrame )
686 {
687     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::stopFrameListening" );
688     SbaXDataBrowserController_Base::stopFrameListening( _rxFrame );
689 
690     Reference< XFrameActionListener >   xAggListener;
691     if ( m_xFormControllerImpl.is() )
692         m_xFormControllerImpl->queryAggregation( XFrameActionListener::static_type() ) >>= xAggListener;
693 
694     if ( _rxFrame.is() && xAggListener.is() )
695         _rxFrame->removeFrameActionListener( xAggListener );
696 }
697 
698 // -----------------------------------------------------------------------------
699 void SbaXDataBrowserController::onStartLoading( const Reference< XLoadable >& _rxLoadable )
700 {
701     m_bLoadCanceled = sal_False;
702     m_bCannotSelectUnfiltered = false;
703 
704     Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY );
705     if ( xWarnings.is() )
706         xWarnings->clearWarnings();
707 }
708 
709 // -----------------------------------------------------------------------------
710 void SbaXDataBrowserController::impl_checkForCannotSelectUnfiltered( const SQLExceptionInfo& _rError )
711 {
712     ::connectivity::SQLError aError( getORB() );
713     ::connectivity::ErrorCode nErrorCode( aError.getErrorCode( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED ) );
714     if ( ((const SQLException*)_rError)->ErrorCode == nErrorCode )
715     {
716         m_bCannotSelectUnfiltered = true;
717         InvalidateFeature( ID_BROWSER_FILTERCRIT );
718     }
719 }
720 
721 // -----------------------------------------------------------------------------
722 sal_Bool SbaXDataBrowserController::reloadForm( const Reference< XLoadable >& _rxLoadable )
723 {
724     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloadForm" );
725     WaitObject aWO(getBrowserView());
726 
727     onStartLoading( _rxLoadable );
728 
729     FormErrorHelper aReportError(this);
730     if (_rxLoadable->isLoaded())
731         _rxLoadable->reload();
732     else
733         _rxLoadable->load();
734 
735     m_xParser.clear();
736     const Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
737     if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)))
738         xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser;
739 #if 0
740     {
741         const Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY );
742         const Reference< XSingleSelectQueryAnalyzer > xAnalyzer( xRowSetProps->getPropertyValue( PROPERTY_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY );
743         if ( xAnalyzer.is() )
744         {
745             const Reference< XIndexAccess > xOrderColumns( xAnalyzer->getOrderColumns(), UNO_SET_THROW );
746             const sal_Int32 nOrderColumns( xOrderColumns->getCount() );
747             for ( sal_Int32 c=0; c<nOrderColumns; ++c )
748             {
749                 const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW );
750                 ::rtl::OUString sColumnName;
751                 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName);
752                 ::rtl::OUString sTableName;
753                 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName);
754                 (void)sColumnName;
755                 (void)sTableName;
756             }
757         }
758     }
759 #endif
760 
761     Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY );
762     if ( xWarnings.is() )
763     {
764         try
765         {
766             SQLExceptionInfo aInfo( xWarnings->getWarnings() );
767             if ( aInfo.isValid() )
768             {
769                 showError( aInfo );
770                 impl_checkForCannotSelectUnfiltered( aInfo );
771             }
772         }
773         catch(const SQLException& e)
774         {
775             (void)e;
776         }
777     }
778 
779     return _rxLoadable->isLoaded();
780 }
781 
782 // -----------------------------------------------------------------------------
783 void SbaXDataBrowserController::initFormatter()
784 {
785     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::initFormatter" );
786     // ---------------------------------------------------------------
787     // create a formatter working with the connections format supplier
788     Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier(::dbtools::getNumberFormats(::dbtools::getConnection(m_xRowSet), sal_True,getORB()));
789 
790     if(xSupplier.is())
791     {
792         // create a new formatter
793         m_xFormatter = Reference< ::com::sun::star::util::XNumberFormatter > (
794             getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
795         if (m_xFormatter.is())
796             m_xFormatter->attachNumberFormatsSupplier(xSupplier);
797     }
798     else // clear the formatter
799         m_xFormatter = NULL;
800 }
801 // -----------------------------------------------------------------------------
802 void SbaXDataBrowserController::describeSupportedFeatures()
803 {
804     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::describeSupportedFeatures" );
805     SbaXDataBrowserController_Base::describeSupportedFeatures();
806     implDescribeSupportedFeature( ".uno:FormSlots/undoRecord",      ID_BROWSER_UNDORECORD,  CommandGroup::CONTROLS );
807     implDescribeSupportedFeature( ".uno:FormController/undoRecord", ID_BROWSER_UNDORECORD,  CommandGroup::CONTROLS );
808     implDescribeSupportedFeature( ".uno:RecUndo",                   ID_BROWSER_UNDORECORD,  CommandGroup::CONTROLS );
809     implDescribeSupportedFeature( ".uno:FormSlots/saveRecord",      ID_BROWSER_SAVERECORD,  CommandGroup::CONTROLS );
810     implDescribeSupportedFeature( ".uno:FormController/saveRecord", ID_BROWSER_SAVERECORD,  CommandGroup::CONTROLS );
811     implDescribeSupportedFeature( ".uno:RecSave",                   ID_BROWSER_SAVERECORD,  CommandGroup::CONTROLS );
812     implDescribeSupportedFeature( ".uno:Save",                      ID_BROWSER_SAVERECORD,  CommandGroup::DOCUMENT );
813     implDescribeSupportedFeature( ".uno:RecSearch",                 SID_FM_SEARCH,          CommandGroup::CONTROLS );
814     implDescribeSupportedFeature( ".uno:AutoFilter",                SID_FM_AUTOFILTER,      CommandGroup::CONTROLS );
815     implDescribeSupportedFeature( ".uno:Refresh",                   SID_FM_REFRESH,         CommandGroup::CONTROLS );
816     implDescribeSupportedFeature( ".uno:OrderCrit",                 SID_FM_ORDERCRIT,       CommandGroup::CONTROLS );
817     implDescribeSupportedFeature( ".uno:RemoveFilterSort",          SID_FM_REMOVE_FILTER_SORT,CommandGroup::CONTROLS );
818     implDescribeSupportedFeature( ".uno:FormFiltered",              SID_FM_FORM_FILTERED,   CommandGroup::CONTROLS );
819     implDescribeSupportedFeature( ".uno:FilterCrit",                SID_FM_FILTERCRIT,      CommandGroup::CONTROLS );
820     implDescribeSupportedFeature( ".uno:Sortup",                    ID_BROWSER_SORTUP,      CommandGroup::CONTROLS );
821     implDescribeSupportedFeature( ".uno:SortDown",                  ID_BROWSER_SORTDOWN,    CommandGroup::CONTROLS );
822     implDescribeSupportedFeature( ".uno:FormSlots/deleteRecord",    SID_FM_DELETEROWS,      CommandGroup::EDIT );
823     implDescribeSupportedFeature( ".uno:FormSlots/insertRecord",    ID_BROWSER_INSERT_ROW,  CommandGroup::INSERT );
824 }
825 //------------------------------------------------------------------------------
826 sal_Bool SbaXDataBrowserController::Construct(Window* pParent)
827 {
828     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::Construct" );
829     // ---------------------------------------------
830     // create/initialize the form and the grid model
831     m_xRowSet = CreateForm();
832     if (!m_xRowSet.is())
833         return sal_False;
834 
835     m_xColumnsSupplier.set(m_xRowSet,UNO_QUERY);
836     m_xLoadable.set(m_xRowSet,UNO_QUERY);
837 
838     Reference< XPropertySet > xFormProperties( m_xRowSet, UNO_QUERY );
839     if ( !InitializeForm( xFormProperties ) )
840         return sal_False;
841 
842     m_xGridModel = CreateGridModel();
843     if (!m_xGridModel.is())
844         return sal_False;
845 
846     // set the formatter if available
847     initFormatter();
848     // ---------------------------------------------------------------
849 
850     // we want to have a grid with a "flat" border
851     Reference< XPropertySet >  xGridSet(m_xGridModel, UNO_QUERY);
852     if ( xGridSet.is() )
853         xGridSet->setPropertyValue(PROPERTY_BORDER, makeAny((sal_Int16)2));
854 
855     // ----------
856     // marry them
857     Reference< ::com::sun::star::container::XNameContainer >  xNameCont(m_xRowSet, UNO_QUERY);
858     {
859         String sText(ModuleRes(STR_DATASOURCE_GRIDCONTROL_NAME));
860         xNameCont->insertByName(::rtl::OUString(sText), makeAny(m_xGridModel));
861     }
862 
863     // ---------------
864     // create the view
865     setView( * new UnoDataBrowserView( pParent, *this, getORB() ) );
866     if (!getBrowserView())
867         return sal_False;
868 
869     // late construction
870     sal_Bool bSuccess = sal_False;
871     try
872     {
873         getBrowserView()->Construct(getControlModel());
874         bSuccess = sal_True;
875     }
876     catch(SQLException&)
877     {
878     }
879     catch(Exception&)
880     {
881         DBG_ERROR("SbaXDataBrowserController::Construct : the construction of UnoDataBrowserView failed !");
882     }
883 
884     if (!bSuccess)
885     {
886         //  deleteView();
887         return sal_False;
888     }
889 
890     // now that we have a view we can create the clipboard listener
891     m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() );
892     m_aSystemClipboard.StartClipboardListening( );
893 
894     m_pClipbordNotifier = new TransferableClipboardListener( LINK( this, SbaXDataBrowserController, OnClipboardChanged ) );
895     m_pClipbordNotifier->acquire();
896     m_pClipbordNotifier->AddRemoveListener( getView(), sal_True );
897 
898     // this call create the toolbox
899     SbaXDataBrowserController_Base::Construct(pParent);
900 
901     getBrowserView()->Show();
902 
903     // set the callbacks for the grid control
904     SbaGridControl* pVclGrid = getBrowserView()->getVclControl();
905     DBG_ASSERT(pVclGrid, "SbaXDataBrowserController::Construct : have no VCL control !");
906     pVclGrid->SetMasterListener(this);
907 
908     // --------------------------
909     // add listeners ...
910 
911     // ... to the form model
912     Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
913     if (xFormSet.is())
914     {
915         xFormSet->addPropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
916         xFormSet->addPropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
917         xFormSet->addPropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
918         xFormSet->addPropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
919         xFormSet->addPropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
920         xFormSet->addPropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
921         xFormSet->addPropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
922         xFormSet->addPropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
923     }
924     Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster >  xFormError(getRowSet(), UNO_QUERY);
925     if (xFormError.is())
926         xFormError->addSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
927 
928     if (m_xLoadable.is())
929         m_xLoadable->addLoadListener(this);
930 
931     Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster >  xFormParameter(getRowSet(), UNO_QUERY);
932     if (xFormParameter.is())
933         xFormParameter->addParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this);
934 
935     addModelListeners(getControlModel());
936     addControlListeners(getBrowserView()->getGridControl());
937 
938     // -------------
939     // load the form
940     return LoadForm();
941 }
942 
943 //------------------------------------------------------------------------------
944 sal_Bool SbaXDataBrowserController::LoadForm()
945 {
946     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::LoadForm" );
947     reloadForm( m_xLoadable );
948     return sal_True;
949 }
950 //------------------------------------------------------------------------------
951 void SbaXDataBrowserController::AddColumnListener(const Reference< XPropertySet > & /*xCol*/)
952 {
953     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::AddColumnListener" );
954     // we're not interested in any column properties ...
955 }
956 
957 //------------------------------------------------------------------------------
958 void SbaXDataBrowserController::RemoveColumnListener(const Reference< XPropertySet > & /*xCol*/)
959 {
960     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::RemoveColumnListener" );
961 }
962 //------------------------------------------------------------------------------
963 Reference< XRowSet >  SbaXDataBrowserController::CreateForm()
964 {
965     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CreateForm" );
966     return Reference< XRowSet > (getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.component.Form")), UNO_QUERY);
967 }
968 
969 //------------------------------------------------------------------------------
970 Reference< ::com::sun::star::form::XFormComponent >  SbaXDataBrowserController::CreateGridModel()
971 {
972     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CreateGridModel" );
973     return Reference< ::com::sun::star::form::XFormComponent > (getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.component.GridControl")), UNO_QUERY);
974 }
975 
976 // -------------------------------------------------------------------------
977 void SbaXDataBrowserController::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
978 {
979     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addModelListeners" );
980     // ... all the grid columns
981     addColumnListeners(_xGridControlModel);
982 
983     // (we are interested in all columns the grid has (and only in these) so we have to listen to the container, too)
984     Reference< ::com::sun::star::container::XContainer >  xColContainer(_xGridControlModel, UNO_QUERY);
985     if (xColContainer.is())
986         xColContainer->addContainerListener((::com::sun::star::container::XContainerListener*)this);
987 
988     Reference< ::com::sun::star::form::XReset >  xReset(_xGridControlModel, UNO_QUERY);
989     if (xReset.is())
990         xReset->addResetListener((::com::sun::star::form::XResetListener*)this);
991 }
992 
993 // -------------------------------------------------------------------------
994 void SbaXDataBrowserController::removeModelListeners(const Reference< XControlModel > & _xGridControlModel)
995 {
996     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::removeModelListeners" );
997     // every single column model
998     Reference< XIndexContainer >  xColumns(_xGridControlModel, UNO_QUERY);
999     if (xColumns.is())
1000     {
1001         sal_Int32 nCount = xColumns->getCount();
1002         for (sal_uInt16 i=0; i < nCount; ++i)
1003         {
1004             Reference< XPropertySet >  xCol(xColumns->getByIndex(i),UNO_QUERY);
1005             RemoveColumnListener(xCol);
1006         }
1007     }
1008 
1009     Reference< XContainer >  xColContainer(_xGridControlModel, UNO_QUERY);
1010     if (xColContainer.is())
1011         xColContainer->removeContainerListener( this );
1012 
1013     Reference< XReset >  xReset(_xGridControlModel, UNO_QUERY);
1014     if (xReset.is())
1015         xReset->removeResetListener( this );
1016 }
1017 
1018 // -------------------------------------------------------------------------
1019 void SbaXDataBrowserController::addControlListeners(const Reference< ::com::sun::star::awt::XControl > & _xGridControl)
1020 {
1021     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addControlListeners" );
1022     // to ge the 'modified' for the current cell
1023     Reference< XModifyBroadcaster >  xBroadcaster(getBrowserView()->getGridControl(), UNO_QUERY);
1024     if (xBroadcaster.is())
1025         xBroadcaster->addModifyListener(static_cast<XModifyListener*>(this));
1026 
1027     // introduce ourself as dispatch provider for the grid
1028     Reference< XDispatchProviderInterception >  xInterception(getBrowserView()->getGridControl(), UNO_QUERY);
1029     if (xInterception.is())
1030         xInterception->registerDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this));
1031 
1032     // add as focus listener to the control (needed for the form controller functionality)
1033     Reference< XWindow >  xWindow(_xGridControl, UNO_QUERY);
1034     if (xWindow.is())
1035         xWindow->addFocusListener(this);
1036 }
1037 
1038 // -------------------------------------------------------------------------
1039 void SbaXDataBrowserController::removeControlListeners(const Reference< ::com::sun::star::awt::XControl > & _xGridControl)
1040 {
1041     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::removeControlListeners" );
1042     Reference< XModifyBroadcaster >  xBroadcaster(_xGridControl, UNO_QUERY);
1043     if (xBroadcaster.is())
1044         xBroadcaster->removeModifyListener(static_cast<XModifyListener*>(this));
1045 
1046     Reference< XDispatchProviderInterception >  xInterception(_xGridControl, UNO_QUERY);
1047     if (xInterception.is())
1048         xInterception->releaseDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this));
1049 
1050     Reference< XWindow >  xWindow(_xGridControl, UNO_QUERY);
1051     if (xWindow.is())
1052         xWindow->removeFocusListener(this);
1053 }
1054 
1055 //------------------------------------------------------------------
1056 void SAL_CALL SbaXDataBrowserController::focusGained(const FocusEvent& /*e*/) throw( RuntimeException )
1057 {
1058     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::focusGained" );
1059     // notify our activate listeners (registered on the form controller aggregate)
1060     EventObject aEvt(*this);
1061     ::cppu::OInterfaceIteratorHelper aIter(m_pFormControllerImpl->m_aActivateListeners);
1062     while (aIter.hasMoreElements())
1063         static_cast<XFormControllerListener*>(aIter.next())->formActivated(aEvt);
1064 }
1065 
1066 //------------------------------------------------------------------
1067 void SAL_CALL SbaXDataBrowserController::focusLost(const FocusEvent& e) throw( RuntimeException )
1068 {
1069     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::focusLost" );
1070     // some general checks
1071     if (!getBrowserView() || !getBrowserView()->getGridControl().is())
1072         return;
1073     Reference< XVclWindowPeer >  xMyGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
1074     if (!xMyGridPeer.is())
1075         return;
1076     Reference< XWindowPeer >  xNextControlPeer(e.NextFocus, UNO_QUERY);
1077     if (!xNextControlPeer.is())
1078         return;
1079 
1080     // don't do a notification if it remains in the family (i.e. a child of the grid control gets the focus)
1081     if (xMyGridPeer->isChild(xNextControlPeer))
1082         return;
1083 
1084     if (xMyGridPeer == xNextControlPeer)
1085         return;
1086 
1087     // notify the listeners that the "form" we represent has been deactivated
1088     EventObject aEvt(*this);
1089     ::cppu::OInterfaceIteratorHelper aIter(m_pFormControllerImpl->m_aActivateListeners);
1090     while (aIter.hasMoreElements())
1091         static_cast<XFormControllerListener*>(aIter.next())->formDeactivated(aEvt);
1092 
1093     // commit the changes of the grid control (as we're deactivated)
1094     Reference< XBoundComponent >  xCommitable(getBrowserView()->getGridControl(), UNO_QUERY);
1095     if (xCommitable.is())
1096         xCommitable->commit();
1097     else
1098         OSL_ENSURE(sal_False, "SbaXDataBrowserController::focusLost : why is my control not commitable ?");
1099 }
1100 
1101 // -------------------------------------------------------------------------
1102 void SbaXDataBrowserController::disposingGridControl(const ::com::sun::star::lang::EventObject& /*Source*/)
1103 {
1104     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingGridControl" );
1105     removeControlListeners(getBrowserView()->getGridControl());
1106 }
1107 
1108 // -------------------------------------------------------------------------
1109 void SbaXDataBrowserController::disposingGridModel(const ::com::sun::star::lang::EventObject& /*Source*/)
1110 {
1111     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingGridModel" );
1112     removeModelListeners(getControlModel());
1113 }
1114 
1115 // -------------------------------------------------------------------------
1116 void SbaXDataBrowserController::disposingFormModel(const ::com::sun::star::lang::EventObject& Source)
1117 {
1118     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingFormModel" );
1119     Reference< XPropertySet >  xSourceSet(Source.Source, UNO_QUERY);
1120     if (xSourceSet.is())
1121     {
1122         xSourceSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
1123         xSourceSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
1124         xSourceSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
1125         xSourceSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
1126         xSourceSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
1127         xSourceSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
1128         xSourceSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
1129         xSourceSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
1130     }
1131 
1132     Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster >  xFormError(Source.Source, UNO_QUERY);
1133     if (xFormError.is())
1134         xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
1135 
1136     if (m_xLoadable.is())
1137         m_xLoadable->removeLoadListener(this);
1138 
1139     Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster >  xFormParameter(Source.Source, UNO_QUERY);
1140     if (xFormParameter.is())
1141         xFormParameter->removeParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this);
1142 }
1143 
1144 // -------------------------------------------------------------------------
1145 void SbaXDataBrowserController::disposingColumnModel(const ::com::sun::star::lang::EventObject& Source)
1146 {
1147     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingColumnModel" );
1148     RemoveColumnListener(Reference< XPropertySet > (Source.Source, UNO_QUERY));
1149 }
1150 
1151 // -------------------------------------------------------------------------
1152 void SbaXDataBrowserController::disposing(const EventObject& Source) throw( RuntimeException )
1153 {
1154     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposing" );
1155     // if it's a component other than our aggregate, forward it to the aggregate
1156     if ( m_xFormControllerImpl != Source.Source )
1157     {
1158         Reference< XEventListener > xAggListener;
1159         m_xFormControllerImpl->queryAggregation( ::getCppuType( &xAggListener ) ) >>= xAggListener;
1160         if ( xAggListener.is( ))
1161             xAggListener->disposing( Source );
1162     }
1163 
1164     // is it the grid control ?
1165     if (getBrowserView())
1166     {
1167         Reference< ::com::sun::star::awt::XControl >  xSourceControl(Source.Source, UNO_QUERY);
1168         if (xSourceControl == getBrowserView()->getGridControl())
1169             disposingGridControl(Source);
1170     }
1171 
1172     // it's model (the container of the columns) ?
1173     if (getControlModel() == Source.Source)
1174         disposingGridModel(Source);
1175 
1176     // the form's model ?
1177     if ((getRowSet() == Source.Source))
1178         disposingFormModel(Source);
1179 
1180     // from a single column model ?
1181     Reference< XPropertySet >  xSourceSet(Source.Source, UNO_QUERY);
1182     if (xSourceSet.is())
1183     {
1184         Reference< XPropertySetInfo >  xInfo = xSourceSet->getPropertySetInfo();
1185         // we assume that columns have a Width property and all other sets we are listening to don't have
1186         if (xInfo->hasPropertyByName(PROPERTY_WIDTH))
1187             disposingColumnModel(Source);
1188     }
1189     SbaXDataBrowserController_Base::OGenericUnoController::disposing( Source );
1190 }
1191 
1192 // -----------------------------------------------------------------------
1193 void SAL_CALL SbaXDataBrowserController::setIdentifier( const ::rtl::OUString& _Identifier ) throw (RuntimeException)
1194 {
1195     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setIdentifier" );
1196     ::osl::MutexGuard aGuard( getMutex() );
1197     m_sModuleIdentifier = _Identifier;
1198 }
1199 
1200 // -----------------------------------------------------------------------
1201 ::rtl::OUString SAL_CALL SbaXDataBrowserController::getIdentifier(  ) throw (RuntimeException)
1202 {
1203     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getIdentifier" );
1204     ::osl::MutexGuard aGuard( getMutex() );
1205     return m_sModuleIdentifier;
1206 }
1207 
1208 // -----------------------------------------------------------------------
1209 void SbaXDataBrowserController::propertyChange(const PropertyChangeEvent& evt) throw ( RuntimeException )
1210 {
1211     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::propertyChange" );
1212     Reference< XPropertySet >  xSource(evt.Source, UNO_QUERY);
1213     if (!xSource.is())
1214         return;
1215 
1216     ::vos::OGuard aGuard(Application::GetSolarMutex());
1217     // the IsModified changed to sal_False ?
1218     if  (   (evt.PropertyName.equals(PROPERTY_ISMODIFIED))
1219         &&  (::comphelper::getBOOL(evt.NewValue) == sal_False)
1220         )
1221     {   // -> the current field isn't modified anymore, too
1222         setCurrentModified( sal_False );
1223     }
1224 
1225     // switching to a new record ?
1226     if  (   (evt.PropertyName.equals(PROPERTY_ISNEW))
1227         &&  (::comphelper::getBOOL(evt.NewValue) == sal_True)
1228         )
1229     {
1230         if (::comphelper::getINT32(xSource->getPropertyValue(PROPERTY_ROWCOUNT)) == 0)
1231             // if we're switching to a new record and didn't have any records before we need to invalidate
1232             // all slots (as the cursor was invalid before the mode change and so the slots were disabled)
1233             InvalidateAll();
1234     }
1235 
1236 
1237     if (evt.PropertyName.equals(PROPERTY_FILTER))
1238     {
1239         InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1240     }
1241     else if (evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE))
1242     {
1243         InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1244     }
1245     else if (evt.PropertyName.equals(PROPERTY_ORDER))
1246     {
1247         InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1248     }
1249 
1250     // a new record count ? -> may be our search availability has changed
1251     if (evt.PropertyName.equals(PROPERTY_ROWCOUNT))
1252     {
1253         sal_Int32 nNewValue = 0, nOldValue = 0;
1254         evt.NewValue >>= nNewValue;
1255         evt.OldValue >>= nOldValue;
1256         if((nOldValue == 0 && nNewValue != 0) || (nOldValue != 0 && nNewValue == 0))
1257             InvalidateAll();
1258     }
1259 }
1260 
1261 //------------------------------------------------------------------------
1262 void SbaXDataBrowserController::modified(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
1263 {
1264     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::modified" );
1265     setCurrentModified( sal_True );
1266 }
1267 
1268 // -----------------------------------------------------------------------
1269 void SbaXDataBrowserController::elementInserted(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException )
1270 {
1271     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementInserted" );
1272     DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1273         "SbaXDataBrowserController::elementInserted: where did this come from (not from the grid model)?!");
1274     Reference< XPropertySet >  xNewColumn(evt.Element,UNO_QUERY);
1275     if ( xNewColumn.is() )
1276         AddColumnListener(xNewColumn);
1277 }
1278 
1279 // -----------------------------------------------------------------------
1280 void SbaXDataBrowserController::elementRemoved(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException )
1281 {
1282     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementRemoved" );
1283     DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1284         "SbaXDataBrowserController::elementRemoved: where did this come from (not from the grid model)?!");
1285     Reference< XPropertySet >  xOldColumn(evt.Element,UNO_QUERY);
1286     if ( xOldColumn.is() )
1287         RemoveColumnListener(xOldColumn);
1288 }
1289 
1290 // -----------------------------------------------------------------------
1291 void SbaXDataBrowserController::elementReplaced(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException )
1292 {
1293     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementReplaced" );
1294     DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1295         "SbaXDataBrowserController::elementReplaced: where did this come from (not from the grid model)?!");
1296     Reference< XPropertySet >  xOldColumn(evt.ReplacedElement,UNO_QUERY);
1297     if ( xOldColumn.is() )
1298         RemoveColumnListener(xOldColumn);
1299 
1300     Reference< XPropertySet >  xNewColumn(evt.Element,UNO_QUERY);
1301     if ( xNewColumn.is() )
1302         AddColumnListener(xNewColumn);
1303 }
1304 
1305 // -----------------------------------------------------------------------
1306 sal_Bool SbaXDataBrowserController::suspend(sal_Bool /*bSuspend*/) throw( RuntimeException )
1307 {
1308     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::suspend" );
1309     DBG_ASSERT(m_nPendingLoadFinished == 0, "SbaXDataBrowserController::suspend : there shouldn't be a pending load !");
1310 
1311     m_aAsyncGetCellFocus.CancelCall();
1312     m_aAsyncDisplayError.CancelCall();
1313     m_aAsyncInvalidateAll.CancelCall();
1314 
1315     sal_Bool bSuccess = SaveModified();
1316     return bSuccess;
1317 }
1318 // -----------------------------------------------------------------------
1319 void SbaXDataBrowserController::disposing()
1320 {
1321     // the base class
1322     SbaXDataBrowserController_Base::OGenericUnoController::disposing();
1323 
1324     // the data source
1325     Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
1326     if (xFormSet.is())
1327     {
1328         xFormSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
1329         xFormSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
1330         xFormSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
1331         xFormSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
1332         xFormSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
1333         xFormSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
1334         xFormSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
1335         xFormSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
1336     }
1337 
1338     Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster >  xFormError(getRowSet(), UNO_QUERY);
1339     if (xFormError.is())
1340         xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
1341 
1342     if (m_xLoadable.is())
1343         m_xLoadable->removeLoadListener(this);
1344 
1345     Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster >  xFormParameter(getRowSet(), UNO_QUERY);
1346     if (xFormParameter.is())
1347         xFormParameter->removeParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this);
1348 
1349     removeModelListeners(getControlModel());
1350 
1351     if ( getView() && m_pClipbordNotifier  )
1352     {
1353         m_pClipbordNotifier->ClearCallbackLink();
1354         m_pClipbordNotifier->AddRemoveListener( getView(), sal_False );
1355         m_pClipbordNotifier->release();
1356         m_pClipbordNotifier = NULL;
1357     }
1358 
1359     if (getBrowserView())
1360     {
1361         removeControlListeners(getBrowserView()->getGridControl());
1362         // don't delete explicitly, this is done by the owner (and user) of this controller (me hopes ...)
1363         clearView();
1364     }
1365 
1366     if(m_aInvalidateClipboard.IsActive())
1367         m_aInvalidateClipboard.Stop();
1368 
1369     // dispose the row set
1370     try
1371     {
1372         ::comphelper::disposeComponent(m_xRowSet);
1373 
1374         m_xRowSet           = NULL;
1375         m_xColumnsSupplier  = NULL;
1376         m_xLoadable         = NULL;
1377     }
1378     catch(Exception&)
1379     {
1380         DBG_UNHANDLED_EXCEPTION();
1381     }
1382     m_xParser.clear();
1383         // don't dispose, just reset - it's owned by the RowSet
1384 }
1385 //------------------------------------------------------------------------------
1386 void SbaXDataBrowserController::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException )
1387 {
1388     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::frameAction" );
1389     ::osl::MutexGuard aGuard( getMutex() );
1390 
1391     SbaXDataBrowserController_Base::frameAction( aEvent );
1392 
1393     if ( aEvent.Source == getFrame() )
1394         switch ( aEvent.Action )
1395         {
1396             case FrameAction_FRAME_ACTIVATED:
1397             case FrameAction_FRAME_UI_ACTIVATED:
1398                 // ensure that the active cell (if any) has the focus
1399                 m_aAsyncGetCellFocus.Call();
1400                 // start the clipboard timer
1401                 if (getBrowserView() && getBrowserView()->getVclControl() && !m_aInvalidateClipboard.IsActive())
1402                 {
1403                     m_aInvalidateClipboard.Start();
1404                     OnInvalidateClipboard( NULL );
1405                 }
1406                 break;
1407             case FrameAction_FRAME_DEACTIVATING:
1408             case FrameAction_FRAME_UI_DEACTIVATING:
1409                 // stop the clipboard invalidator
1410                 if (getBrowserView() && getBrowserView()->getVclControl() && m_aInvalidateClipboard.IsActive())
1411                 {
1412                     m_aInvalidateClipboard.Stop();
1413                     OnInvalidateClipboard( NULL );
1414                 }
1415                 // remove the "get cell focus"-event
1416                 m_aAsyncGetCellFocus.CancelCall();
1417                 break;
1418             default:
1419                 break;
1420         }
1421 }
1422 
1423 //------------------------------------------------------------------------------
1424 IMPL_LINK( SbaXDataBrowserController, OnAsyncDisplayError, void*, /* _pNotInterestedIn */ )
1425 {
1426     if ( m_aCurrentError.isValid() )
1427     {
1428         OSQLMessageBox aDlg( getBrowserView(), m_aCurrentError );
1429         aDlg.Execute();
1430     }
1431     return 0L;
1432 }
1433 
1434 //------------------------------------------------------------------------------
1435 void SbaXDataBrowserController::errorOccured(const ::com::sun::star::sdb::SQLErrorEvent& aEvent) throw( RuntimeException )
1436 {
1437     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::errorOccured" );
1438     ::osl::MutexGuard aGuard( getMutex() );
1439 
1440     SQLExceptionInfo aInfo( aEvent.Reason );
1441     if ( !aInfo.isValid() )
1442         return;
1443 
1444     if ( m_nFormActionNestingLevel )
1445     {
1446         OSL_ENSURE( !m_aCurrentError.isValid(), "SbaXDataBrowserController::errorOccured: can handle one error per transaction only!" );
1447         m_aCurrentError = aInfo;
1448     }
1449     else
1450     {
1451         m_aCurrentError = aInfo;
1452         m_aAsyncDisplayError.Call();
1453     }
1454 }
1455 
1456 //------------------------------------------------------------------------------
1457 sal_Bool SbaXDataBrowserController::approveParameter(const ::com::sun::star::form::DatabaseParameterEvent& aEvent) throw( RuntimeException )
1458 {
1459     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::approveParameter" );
1460     if (aEvent.Source != getRowSet())
1461     {
1462         // not my data source -> allow anything
1463         DBG_ERROR("SbaXDataBrowserController::approveParameter : invalid event source !");
1464         return sal_True;
1465     }
1466 
1467     Reference< ::com::sun::star::container::XIndexAccess >  xParameters = aEvent.Parameters;
1468     ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1469         // this may be executed in a non-main thread and we want to use vcl ...
1470     Window* pParent = Application::GetDefDialogParent();
1471         // don't use the content as parent if it isn't visible
1472     // (and don't use NULL as parent : this may be displayed in the beamer and really shouldn't be task-local)
1473         // 69297 - FS - 25.10.99
1474     if (getBrowserView() && getBrowserView()->IsVisible())
1475         pParent = getBrowserView();
1476 
1477     // default handling: instantiate an interaction handler and let it handle the parameter request
1478     try
1479     {
1480         // two continuations allowed: OK and Cancel
1481         OParameterContinuation* pParamValues = new OParameterContinuation;
1482         OInteractionAbort* pAbort = new OInteractionAbort;
1483         // the request
1484         ParametersRequest aRequest;
1485         aRequest.Parameters = xParameters;
1486         aRequest.Connection = getConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
1487         OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest));
1488         Reference< XInteractionRequest > xParamRequest(pParamRequest);
1489         // some knittings
1490         pParamRequest->addContinuation(pParamValues);
1491         pParamRequest->addContinuation(pAbort);
1492 
1493         // create the handler, let it handle the request
1494         Reference< XInteractionHandler > xHandler(getORB()->createInstance(SERVICE_TASK_INTERACTION_HANDLER), UNO_QUERY);
1495         if (xHandler.is())
1496             xHandler->handle(xParamRequest);
1497 
1498         if (!pParamValues->wasSelected())
1499         {   // canceled
1500             setLoadingCancelled();
1501             return sal_False;
1502         }
1503 
1504         // transfer the values into the parameter supplier
1505         Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
1506         if (aFinalValues.getLength() != aRequest.Parameters->getCount())
1507         {
1508             DBG_ERROR("SbaXDataBrowserController::approveParameter: the InteractionHandler returned nonsense!");
1509             setLoadingCancelled();
1510             return sal_False;
1511         }
1512         const PropertyValue* pFinalValues = aFinalValues.getConstArray();
1513         for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
1514         {
1515             Reference< XPropertySet > xParam;
1516             ::cppu::extractInterface(xParam, aRequest.Parameters->getByIndex(i));
1517             DBG_ASSERT(xParam.is(), "SbaXDataBrowserController::approveParameter: one of the parameters is no property set!");
1518             if (xParam.is())
1519             {
1520 #ifdef DBG_UTIL
1521                 ::rtl::OUString sName;
1522                 xParam->getPropertyValue(PROPERTY_NAME) >>= sName;
1523                 DBG_ASSERT(sName.equals(pFinalValues->Name), "SbaXDataBrowserController::approveParameter: suspicious value names!");
1524 #endif
1525                 try { xParam->setPropertyValue(PROPERTY_VALUE, pFinalValues->Value); }
1526                 catch(Exception&)
1527                 {
1528                     DBG_ERROR("SbaXDataBrowserController::approveParameter: setting one of the properties failed!");
1529                 }
1530             }
1531         }
1532     }
1533     catch( const Exception& )
1534     {
1535         DBG_UNHANDLED_EXCEPTION();
1536     }
1537 
1538     return sal_True;
1539 }
1540 
1541 
1542 //------------------------------------------------------------------------------
1543 sal_Bool SbaXDataBrowserController::approveReset(const ::com::sun::star::lang::EventObject& /*rEvent*/) throw( RuntimeException )
1544 {
1545     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::approveReset" );
1546     return sal_True;
1547 }
1548 
1549 //------------------------------------------------------------------------------
1550 void SbaXDataBrowserController::resetted(const ::com::sun::star::lang::EventObject& rEvent) throw( RuntimeException )
1551 {
1552     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::resetted" );
1553     DBG_ASSERT(rEvent.Source == getControlModel(), "SbaXDataBrowserController::resetted : where did this come from ?");
1554     (void)rEvent;
1555     setCurrentModified( sal_False );
1556 }
1557 
1558 //------------------------------------------------------------------------------
1559 sal_Bool SbaXDataBrowserController::confirmDelete(const ::com::sun::star::sdb::RowChangeEvent& /*aEvent*/) throw( RuntimeException )
1560 {
1561     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::confirmDelete" );
1562     if (QueryBox(getBrowserView(), ModuleRes(QUERY_BRW_DELETE_ROWS)).Execute() != RET_YES)
1563         return sal_False;
1564 
1565     return sal_True;
1566 }
1567 //------------------------------------------------------------------------------
1568 FeatureState SbaXDataBrowserController::GetState(sal_uInt16 nId) const
1569 {
1570     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::GetState" );
1571     FeatureState aReturn;
1572         // (disabled automatically)
1573 
1574     try
1575     {
1576         // no chance without a view
1577         if (!getBrowserView() || !getBrowserView()->getVclControl())
1578             return aReturn;
1579 
1580         switch (nId)
1581         {
1582             case ID_BROWSER_REMOVEFILTER:
1583                 if (!m_xParser.is())
1584                 {
1585                     aReturn.bEnabled = false;
1586                     return aReturn;
1587                 }
1588                 // any filter or sort order set ?
1589                 aReturn.bEnabled = m_xParser->getFilter().getLength() || m_xParser->getHavingClause().getLength() || m_xParser->getOrder().getLength();
1590                 return aReturn;
1591         }
1592         // no chance without valid models
1593         if (isValid() && !isValidCursor())
1594             return aReturn;
1595 
1596         switch (nId)
1597         {
1598             case ID_BROWSER_SEARCH:
1599             {
1600                 Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
1601                 sal_Int32 nCount = ::comphelper::getINT32(xFormSet->getPropertyValue(PROPERTY_ROWCOUNT));
1602                 aReturn.bEnabled = nCount != 0;
1603             }
1604             break;
1605             case ID_BROWSER_INSERT_ROW:
1606                 {
1607                     // check if it is available
1608                     sal_Bool bInsertPrivilege = ( m_nRowSetPrivileges & Privilege::INSERT) != 0;
1609                     sal_Bool bAllowInsertions = sal_True;
1610                     try
1611                     {
1612                         Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
1613                         OSL_VERIFY( xRowSetProps->getPropertyValue( ::rtl::OUString::createFromAscii( "AllowInserts" ) ) >>= bAllowInsertions );
1614                     }
1615                     catch( const Exception& )
1616                     {
1617                         DBG_UNHANDLED_EXCEPTION();
1618                     }
1619                     aReturn.bEnabled = bInsertPrivilege && bAllowInsertions;
1620                 }
1621                 break;
1622             case SID_FM_DELETEROWS:
1623                 {
1624                     // check if it is available
1625                     sal_Bool bDeletePrivilege = ( m_nRowSetPrivileges & Privilege::INSERT) != 0;
1626                     sal_Bool bAllowDeletions = sal_True;
1627                     sal_Int32 nRowCount = 0;
1628                     sal_Bool bInsertionRow = sal_False;
1629                     try
1630                     {
1631                         Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
1632                         OSL_VERIFY( xRowSetProps->getPropertyValue( ::rtl::OUString::createFromAscii( "AllowDeletes" ) ) >>= bAllowDeletions );
1633                         OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ROWCOUNT ) >>= nRowCount );
1634                         OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ISNEW ) >>= bInsertionRow );
1635                     }
1636                     catch( const Exception& )
1637                     {
1638                         DBG_UNHANDLED_EXCEPTION();
1639                     }
1640                     aReturn.bEnabled = bDeletePrivilege && bAllowDeletions && ( nRowCount != 0 ) && !bInsertionRow;
1641                 }
1642                 break;
1643 
1644             case ID_BROWSER_COPY:
1645                 if ( getBrowserView()->getVclControl()->GetSelectRowCount() )
1646                 {
1647                     aReturn.bEnabled = m_aCurrentFrame.isActive();
1648                     break;
1649                 }
1650                 // run through
1651             case ID_BROWSER_PASTE:
1652             case ID_BROWSER_CUT:
1653             {
1654                 CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller();
1655                 if (xCurrentController.Is() && xCurrentController->ISA(EditCellController))
1656                 {
1657                     Edit& rEdit = (Edit&)xCurrentController->GetWindow();
1658                     sal_Bool bHasLen = (rEdit.GetSelection().Len() != 0);
1659                     sal_Bool bIsReadOnly = rEdit.IsReadOnly();
1660                     switch (nId)
1661                     {
1662                         case ID_BROWSER_CUT:    aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen && !bIsReadOnly; break;
1663                         case SID_COPY   :       aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen; break;
1664                         case ID_BROWSER_PASTE:
1665                             aReturn.bEnabled = m_aCurrentFrame.isActive() && !bIsReadOnly;
1666                             if(aReturn.bEnabled)
1667                             {
1668                                 aReturn.bEnabled = aReturn.bEnabled && IsFormatSupported( m_aSystemClipboard.GetDataFlavorExVector(), FORMAT_STRING );
1669                             }
1670                             break;
1671                     }
1672                 }
1673             }
1674             break;
1675 
1676             case ID_BROWSER_SORTUP:
1677             case ID_BROWSER_SORTDOWN:
1678             case ID_BROWSER_AUTOFILTER:
1679             {
1680                 // a native statement can't be filtered or sorted
1681                 const Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
1682                 if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || !m_xParser.is() )
1683                     break;
1684 
1685                 Reference< XPropertySet >  xCurrentField = getBoundField();
1686                 if (!xCurrentField.is())
1687                     break;
1688 
1689                 aReturn.bEnabled = ::comphelper::getBOOL(xCurrentField->getPropertyValue(PROPERTY_ISSEARCHABLE));
1690                 const Reference< XRowSet > xRow = getRowSet();
1691                 aReturn.bEnabled =  aReturn.bEnabled
1692                                 &&  xRow.is()
1693                                 &&  !xRow->isBeforeFirst()
1694                                 &&  !xRow->isAfterLast()
1695                                 &&  !xRow->rowDeleted()
1696                                 &&  ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 );
1697             }
1698             break;
1699 
1700             case ID_BROWSER_FILTERCRIT:
1701                 if ( m_bCannotSelectUnfiltered && m_xParser.is() )
1702                 {
1703                     aReturn.bEnabled = sal_True;
1704                     break;
1705                 }
1706                 // no break
1707             case ID_BROWSER_ORDERCRIT:
1708                 {
1709                     const Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
1710                     if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || !m_xParser.is() )
1711                         break;
1712 
1713                     aReturn.bEnabled =  getRowSet().is()
1714                                     &&  ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 );
1715                 }
1716                 break;
1717 
1718             case ID_BROWSER_REFRESH:
1719                 aReturn.bEnabled = sal_True;
1720                 break;
1721 
1722             case ID_BROWSER_REDO:
1723                 aReturn.bEnabled = sal_False;   // simply forget it ;). no redo possible.
1724                 break;
1725 
1726             case ID_BROWSER_UNDORECORD:
1727             case ID_BROWSER_SAVERECORD:
1728             {
1729                 if (!m_bCurrentlyModified)
1730                 {
1731                     Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
1732                     if (xFormSet.is())
1733                         aReturn.bEnabled = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED));
1734                 }
1735                 else
1736                     aReturn.bEnabled = sal_True;
1737 
1738                 aReturn.sTitle = (ID_BROWSER_UNDORECORD == nId) ? m_sStateUndoRecord : m_sStateSaveRecord;
1739             }
1740             break;
1741             case ID_BROWSER_EDITDOC:
1742             {
1743                 // check if it is available
1744                 Reference< XPropertySet >  xDataSourceSet(getRowSet(), UNO_QUERY);
1745                 if (!xDataSourceSet.is())
1746                     break;  // no datasource -> no edit mode
1747 
1748                 sal_Int32 nDataSourcePrivileges = ::comphelper::getINT32(xDataSourceSet->getPropertyValue(PROPERTY_PRIVILEGES));
1749                 sal_Bool bInsertAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::INSERT) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowInserts")));
1750                 sal_Bool bUpdateAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::UPDATE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowUpdates")));
1751                 sal_Bool bDeleteAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::DELETE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowDeletes")));
1752                 if (!bInsertAllowedAndPossible && !bUpdateAllowedAndPossible && !bDeleteAllowedAndPossible)
1753                     break;  // no insert/update/delete -> no edit mode
1754 
1755                 if (!isValidCursor() || !isLoaded())
1756                     break;  // no cursor -> no edit mode
1757 
1758                 aReturn.bEnabled = sal_True;
1759 
1760                 sal_Int16 nGridMode = getBrowserView()->getVclControl()->GetOptions();
1761                 aReturn.bChecked = nGridMode > DbGridControl::OPT_READONLY;
1762             }
1763             break;
1764             case ID_BROWSER_FILTERED:
1765             {
1766                 aReturn.bEnabled = sal_False;
1767                 Reference< XPropertySet >  xActiveSet(getRowSet(), UNO_QUERY);
1768                 ::rtl::OUString aFilter = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_FILTER));
1769                 ::rtl::OUString aHaving = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_HAVING_CLAUSE));
1770                 if ( aFilter.getLength() || aHaving.getLength() )
1771                 {
1772                     xActiveSet->getPropertyValue( PROPERTY_APPLYFILTER ) >>= aReturn.bChecked;
1773                     aReturn.bEnabled = sal_True;
1774                 }
1775                 else
1776                 {
1777                     aReturn.bChecked = sal_False;
1778                     aReturn.bEnabled = sal_False;
1779                 }
1780             }
1781             break;
1782             default:
1783                 return SbaXDataBrowserController_Base::GetState(nId);
1784         }
1785     }
1786     catch(const Exception& )
1787     {
1788         DBG_UNHANDLED_EXCEPTION();
1789     }
1790 
1791     return aReturn;
1792 }
1793 
1794 //------------------------------------------------------------------------------
1795 void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrder,const Reference< XSingleSelectQueryComposer >& _xParser)
1796 {
1797     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserOrder" );
1798     Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1799     if (!m_xLoadable.is())
1800     {
1801         OSL_ENSURE(sal_False, "SbaXDataBrowserController::applyParserOrder: invalid row set!");
1802         return;
1803     }
1804 
1805     sal_uInt16 nPos = getCurrentColumnPosition();
1806     sal_Bool bSuccess = sal_False;
1807     try
1808     {
1809         xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_xParser->getOrder()));
1810         bSuccess = reloadForm(m_xLoadable);
1811     }
1812     catch(Exception&)
1813     {
1814     }
1815 
1816     if (!bSuccess)
1817     {
1818         xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_rOldOrder));
1819         //DO_SAFE( _xParser->setOrder(_rOldOrder), "SbaXDataBrowserController::applyParserOrder: could not restore the old order of my parser !" );
1820 
1821         try
1822         {
1823             if (loadingCancelled() || !reloadForm(m_xLoadable))
1824                 criticalFail();
1825         }
1826         catch(Exception&)
1827         {
1828             criticalFail();
1829         }
1830         InvalidateAll();
1831     }
1832     InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1833 
1834     setCurrentColumnPosition(nPos);
1835 }
1836 
1837 //------------------------------------------------------------------------------
1838 void SbaXDataBrowserController::applyParserFilter(const ::rtl::OUString& _rOldFilter, sal_Bool _bOldFilterApplied,const ::rtl::OUString& _sOldHaving,const Reference< XSingleSelectQueryComposer >& _xParser)
1839 {
1840     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserFilter" );
1841     Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
1842     if (!m_xLoadable.is())
1843     {
1844         OSL_ENSURE(sal_False, "SbaXDataBrowserController::applyParserFilter: invalid row set!");
1845         return;
1846     }
1847 
1848     sal_uInt16 nPos = getCurrentColumnPosition();
1849 
1850     sal_Bool bSuccess = sal_False;
1851     try
1852     {
1853         FormErrorHelper aError(this);
1854         xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_xParser->getFilter()));
1855         xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_xParser->getHavingClause()));
1856         xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(sal_Bool(sal_True)));
1857 
1858         bSuccess = reloadForm(m_xLoadable);
1859     }
1860     catch(Exception&)
1861     {
1862     }
1863 
1864     if (!bSuccess)
1865     {
1866         xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_rOldFilter));
1867         xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_sOldHaving));
1868         xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(_bOldFilterApplied));
1869 
1870         try
1871         {
1872             if (loadingCancelled() || !reloadForm(m_xLoadable))
1873                 criticalFail();
1874         }
1875         catch(Exception&)
1876         {
1877             criticalFail();
1878         }
1879         InvalidateAll();
1880     }
1881     InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1882 
1883     setCurrentColumnPosition(nPos);
1884 }
1885 
1886 //------------------------------------------------------------------------------
1887 Reference< XSingleSelectQueryComposer > SbaXDataBrowserController::createParser_nothrow()
1888 {
1889     Reference< XSingleSelectQueryComposer > xComposer;
1890     try
1891     {
1892         const Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
1893         const Reference< XMultiServiceFactory > xFactory(
1894             xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY_THROW );
1895         xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
1896 
1897         ::rtl::OUString sActiveCommand;
1898         OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ACTIVECOMMAND ) >>= sActiveCommand );
1899         if ( sActiveCommand.getLength() > 0 )
1900         {
1901             xComposer->setElementaryQuery( sActiveCommand );
1902         }
1903         else
1904         {
1905             ::rtl::OUString sCommand;
1906             OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
1907             sal_Int32 nCommandType = CommandType::COMMAND;
1908             OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMAND_TYPE ) >>= nCommandType );
1909             xComposer->setCommand( sCommand, nCommandType );
1910         }
1911 
1912         ::rtl::OUString sFilter;
1913         OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_FILTER ) >>= sFilter );
1914         xComposer->setFilter( sFilter );
1915 
1916         ::rtl::OUString sHavingClause;
1917         OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_HAVING_CLAUSE ) >>= sHavingClause );
1918         xComposer->setHavingClause( sHavingClause );
1919 
1920         ::rtl::OUString sOrder;
1921         OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ORDER ) >>= sOrder );
1922         xComposer->setOrder( sOrder );
1923     }
1924     catch ( const Exception& )
1925     {
1926         DBG_UNHANDLED_EXCEPTION();
1927     }
1928     return xComposer;
1929 }
1930 //------------------------------------------------------------------------------
1931 void SbaXDataBrowserController::ExecuteFilterSortCrit(sal_Bool bFilter)
1932 {
1933     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ExecuteFilterSortCrit" );
1934     if (!SaveModified())
1935         return;
1936 
1937     Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
1938 
1939     const ::rtl::OUString sOldVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder();
1940     const ::rtl::OUString sOldHaving = m_xParser->getHavingClause();
1941     Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow();
1942     try
1943     {
1944         Reference< ::com::sun::star::sdbcx::XColumnsSupplier> xSup = getColumnsSupplier();
1945         Reference< XConnection> xCon(xFormSet->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
1946         if(bFilter)
1947         {
1948             DlgFilterCrit aDlg( getBrowserView(), getORB(), xCon, xParser, xSup->getColumns() );
1949             String aFilter;
1950             if ( !aDlg.Execute() )
1951                 return; // if so we don't need to update the grid
1952             aDlg.BuildWherePart();
1953         }
1954         else
1955         {
1956             DlgOrderCrit aDlg( getBrowserView(),xCon,xParser,xSup->getColumns() );
1957             String aOrder;
1958             if(!aDlg.Execute())
1959             {
1960                 return; // if so we don't need to actualize the grid
1961             }
1962             aDlg.BuildOrderPart();
1963         }
1964     }
1965     catch(const SQLException& )
1966     {
1967         SQLExceptionInfo aError( ::cppu::getCaughtException() );
1968         showError( aError );
1969         return;
1970     }
1971     catch(Exception&)
1972     {
1973         return;
1974     }
1975 
1976     ::rtl::OUString sNewVal = bFilter ? xParser->getFilter() : xParser->getOrder();
1977     sal_Bool bOldFilterApplied(sal_False);
1978     if (bFilter)
1979     {
1980         try { bOldFilterApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER)); } catch(Exception&) { } ;
1981     }
1982 
1983     ::rtl::OUString sNewHaving = xParser->getHavingClause();
1984     if ( sOldVal.equals(sNewVal) && (!bFilter || sOldHaving.equals(sNewHaving)) )
1985         // nothing to be done
1986         return;
1987 
1988     if (bFilter)
1989         applyParserFilter(sOldVal, bOldFilterApplied,sOldHaving,xParser);
1990     else
1991         applyParserOrder(sOldVal,xParser);
1992 
1993     ::comphelper::disposeComponent(xParser);
1994 }
1995 
1996 //------------------------------------------------------------------------------
1997 void SbaXDataBrowserController::ExecuteSearch()
1998 {
1999     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ExecuteSearch" );
2000     // calculate the control source of the active field
2001     Reference< ::com::sun::star::form::XGrid >  xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2002     DBG_ASSERT(xGrid.is(), "SbaXDataBrowserController::ExecuteSearch : the control should have an ::com::sun::star::form::XGrid interface !");
2003 
2004     Reference< ::com::sun::star::form::XGridPeer >  xGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
2005     Reference< ::com::sun::star::container::XIndexContainer >  xColumns = xGridPeer->getColumns();
2006     DBG_ASSERT(xGridPeer.is() && xColumns.is(), "SbaXDataBrowserController::ExecuteSearch : invalid peer !");
2007 
2008     sal_Int16 nViewCol = xGrid->getCurrentColumnPosition();
2009     sal_Int16 nModelCol = getBrowserView()->View2ModelPos(nViewCol);
2010 
2011     Reference< XPropertySet >  xCurrentCol(xColumns->getByIndex(nModelCol),UNO_QUERY);
2012     String sActiveField = ::comphelper::getString(xCurrentCol->getPropertyValue(PROPERTY_CONTROLSOURCE));
2013 
2014     // the text within the current cell
2015     String sInitialText;
2016     Reference< ::com::sun::star::container::XIndexAccess >  xColControls(xGridPeer, UNO_QUERY);
2017     Reference< XInterface >  xCurControl(xColControls->getByIndex(nViewCol),UNO_QUERY);
2018     ::rtl::OUString aInitialText;
2019     if (IsSearchableControl(xCurControl, &aInitialText))
2020         sInitialText = (const sal_Unicode*)aInitialText;
2021 
2022     // prohibit the synchronization of the grid's display with the cursor's position
2023     Reference< XPropertySet >  xModelSet(getControlModel(), UNO_QUERY);
2024     DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::ExecuteSearch : no model set ?!");
2025     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_False)));
2026     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("AlwaysShowCursor"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
2027     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("CursorColor"), makeAny(sal_Int32(COL_LIGHTRED)));
2028 
2029     Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xNFS(::dbtools::getNumberFormats(::dbtools::getConnection(m_xRowSet), sal_True,getORB()));
2030 
2031     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2032     AbstractFmSearchDialog* pDialog = NULL;
2033     if ( pFact )
2034     {
2035         ::std::vector< String > aContextNames;
2036         aContextNames.push_back( String::CreateFromAscii("Standard") );
2037         pDialog = pFact->CreateFmSearchDialog(getBrowserView(), sInitialText, aContextNames, 0, LINK(this, SbaXDataBrowserController, OnSearchContextRequest));
2038     }
2039     DBG_ASSERT( pDialog, "SbaXDataBrowserController::ExecuteSearch: could not get the search dialog!" );
2040     if ( pDialog )
2041     {
2042         pDialog->SetActiveField( sActiveField );
2043         pDialog->SetFoundHandler( LINK( this, SbaXDataBrowserController, OnFoundData ) );
2044         pDialog->SetCanceledNotFoundHdl( LINK( this, SbaXDataBrowserController, OnCanceledNotFound ) );
2045         pDialog->Execute();
2046         delete pDialog;
2047     }
2048 
2049     // restore the grid's normal operating state
2050     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
2051     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("AlwaysShowCursor"), ::comphelper::makeBoolAny(sal_Bool(sal_False)));
2052     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("CursorColor"), Any());
2053 }
2054 
2055 //------------------------------------------------------------------------------
2056 void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& _rArgs)
2057 {
2058     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::Execute" );
2059     sal_Bool bSortUp = sal_True;
2060 
2061     switch (nId)
2062     {
2063         default:
2064             SbaXDataBrowserController_Base::Execute( nId, _rArgs );
2065             return;
2066 
2067         case ID_BROWSER_INSERT_ROW:
2068             try
2069             {
2070                 if (SaveModified())
2071                 {
2072                     getRowSet()->afterLast();
2073                     // check if it is available
2074                     Reference< XResultSetUpdate >  xUpdateCursor(getRowSet(), UNO_QUERY_THROW);
2075                     xUpdateCursor->moveToInsertRow();
2076                 }
2077             }
2078             catch(Exception&)
2079             {
2080                 OSL_ENSURE(0,"Exception caught!");
2081             }
2082             break;
2083         case SID_FM_DELETEROWS:
2084 
2085             if (SaveModified())
2086             {
2087                 SbaGridControl* pVclGrid = getBrowserView()->getVclControl();
2088                 if ( pVclGrid )
2089                 {
2090                     if( !pVclGrid->GetSelectRowCount() )
2091                     {
2092                         pVclGrid->DeactivateCell();
2093                         pVclGrid->SelectRow(pVclGrid->GetCurRow());
2094                     }
2095                     pVclGrid->DeleteSelectedRows();
2096                 }
2097             }
2098             break;
2099 
2100         case ID_BROWSER_FILTERED:
2101             if (SaveModified())
2102             {
2103                 Reference< XPropertySet >  xActiveSet(getRowSet(), UNO_QUERY);
2104                 sal_Bool bApplied = ::comphelper::getBOOL(xActiveSet->getPropertyValue(PROPERTY_APPLYFILTER));
2105                 xActiveSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(sal_Bool(!bApplied)));
2106                 reloadForm(m_xLoadable);
2107             }
2108             InvalidateFeature(ID_BROWSER_FILTERED);
2109             break;
2110         case ID_BROWSER_EDITDOC:
2111         {
2112             sal_Int16 nGridMode = getBrowserView()->getVclControl()->GetOptions();
2113             if (nGridMode == DbGridControl::OPT_READONLY)
2114                 getBrowserView()->getVclControl()->SetOptions(DbGridControl::OPT_UPDATE | DbGridControl::OPT_INSERT | DbGridControl::OPT_DELETE);
2115                     // the options not supported by the data source will be removed automatically
2116             else
2117             {
2118                 if ( !SaveModified( ) )
2119                     // give the user a chance to save the current record (if neccessary)
2120                     break;
2121 
2122                 // maybe the user wanted to reject the modified record ?
2123                 if (GetState(ID_BROWSER_UNDORECORD).bEnabled)
2124                     Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>());
2125 
2126                 getBrowserView()->getVclControl()->SetOptions(DbGridControl::OPT_READONLY);
2127             }
2128             InvalidateFeature(ID_BROWSER_EDITDOC);
2129         }
2130         break;
2131 
2132         case ID_BROWSER_SEARCH:
2133             if ( SaveModified( ) )
2134                 ExecuteSearch();
2135             break;
2136 
2137         case ID_BROWSER_COPY:
2138             if ( getBrowserView()->getVclControl()->GetSelectRowCount() > 0 )
2139             {
2140                 getBrowserView()->getVclControl()->CopySelectedRowsToClipboard();
2141                 break;
2142             }
2143             // run through
2144         case ID_BROWSER_CUT:
2145         case ID_BROWSER_PASTE:
2146         {
2147             CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller();
2148             if (!xCurrentController.Is())
2149                 // should be intercepted by GetState. Normally.
2150                 // Unfortunately ID_BROWSER_PASTE is a 'fast call' slot, which means it may be executed without checking if it is
2151                 // enabled. This would be really deadly herein if the current cell has no controller ...
2152                 // (FS - 13.04.99 - #64694#)
2153                 return;
2154 
2155             Edit& rEdit = (Edit&)xCurrentController->GetWindow();
2156             switch (nId)
2157             {
2158                 case ID_BROWSER_CUT :       rEdit.Cut();    break;
2159                 case SID_COPY   :           rEdit.Copy();   break;
2160                 case ID_BROWSER_PASTE   :   rEdit.Paste();  break;
2161             }
2162             if (ID_BROWSER_CUT == nId || ID_BROWSER_PASTE == nId)
2163             {
2164                 xCurrentController->SetModified();
2165                 rEdit.Modify();
2166             }
2167         }
2168         break;
2169 
2170         case ID_BROWSER_SORTDOWN:
2171             bSortUp = sal_False;
2172             // DON'T break
2173         case ID_BROWSER_SORTUP:
2174         {
2175             if (!SaveModified())
2176                 break;
2177 
2178             if (!isValidCursor())
2179                 break;
2180 
2181             // only one sort order
2182             Reference< XPropertySet >  xField(getBoundField(), UNO_QUERY);
2183             if (!xField.is())
2184                 break;
2185 
2186             Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow();
2187             const ::rtl::OUString sOldSort = xParser->getOrder();
2188             sal_Bool bParserSuccess = sal_False;
2189             HANDLE_SQL_ERRORS(
2190                 xParser->setOrder(::rtl::OUString()); xParser->appendOrderByColumn(xField, bSortUp),
2191                 bParserSuccess,
2192                 UniString(ModuleRes(SBA_BROWSER_SETTING_ORDER)),
2193                 "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2194             )
2195 
2196             if (bParserSuccess)
2197                 applyParserOrder(sOldSort,xParser);
2198         }
2199         break;
2200 
2201         case ID_BROWSER_AUTOFILTER:
2202         {
2203             if (!SaveModified())
2204                 break;
2205 
2206             if (!isValidCursor())
2207                 break;
2208 
2209             Reference< XPropertySet >  xField(getBoundField(), UNO_QUERY);
2210             if (!xField.is())
2211                 break;
2212 
2213             // check if the column is a aggregate function
2214             sal_Bool bHaving = sal_False;
2215             ::rtl::OUString sName;
2216             xField->getPropertyValue(PROPERTY_NAME) >>= sName;
2217             Reference< XColumnsSupplier > xColumnsSupplier(m_xParser, UNO_QUERY);
2218             Reference< ::com::sun::star::container::XNameAccess >  xCols = xColumnsSupplier.is() ? xColumnsSupplier->getColumns() : Reference< ::com::sun::star::container::XNameAccess > ();
2219             if ( xCols.is() && xCols->hasByName(sName) )
2220             {
2221                 Reference<XPropertySet> xProp(xCols->getByName(sName),UNO_QUERY);
2222                 static ::rtl::OUString sAgg(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction"));
2223                 if ( xProp->getPropertySetInfo()->hasPropertyByName(sAgg) )
2224                     xProp->getPropertyValue(sAgg) >>= bHaving;
2225             }
2226 
2227             Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow();
2228             const ::rtl::OUString sOldFilter = xParser->getFilter();
2229             const ::rtl::OUString sOldHaving = xParser->getHavingClause();
2230 
2231             Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
2232             sal_Bool bApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER));
2233             // do we have a filter but it's not applied ?
2234             // -> completely overwrite it, else append one
2235             if (!bApplied)
2236             {
2237                 DO_SAFE( (bHaving ? xParser->setHavingClause(::rtl::OUString()) : xParser->setFilter(::rtl::OUString())), "SbaXDataBrowserController::Execute : caught an exception while resetting the new filter !" );
2238             }
2239 
2240             sal_Bool bParserSuccess = sal_False;
2241 
2242             sal_Int32 nOp = SQLFilterOperator::EQUAL;
2243             if ( xField.is() )
2244             {
2245                 sal_Int32 nType = 0;
2246                 xField->getPropertyValue(PROPERTY_TYPE) >>= nType;
2247                 switch(nType)
2248                 {
2249                     case DataType::VARCHAR:
2250                     case DataType::CHAR:
2251                     case DataType::LONGVARCHAR:
2252                         nOp = SQLFilterOperator::LIKE;
2253                         break;
2254                     default:
2255                         nOp = SQLFilterOperator::EQUAL;
2256                 }
2257             }
2258 
2259             if ( bHaving )
2260             {
2261                 HANDLE_SQL_ERRORS(
2262                     xParser->appendHavingClauseByColumn(xField,sal_True,nOp),
2263                     bParserSuccess,
2264                     UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)),
2265                     "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2266                 )
2267             }
2268             else
2269             {
2270                 HANDLE_SQL_ERRORS(
2271                     xParser->appendFilterByColumn(xField,sal_True,nOp),
2272                     bParserSuccess,
2273                     UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)),
2274                     "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2275                 )
2276             }
2277 
2278             if (bParserSuccess)
2279                 applyParserFilter(sOldFilter, bApplied,sOldHaving,xParser);
2280 
2281             InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2282             InvalidateFeature(ID_BROWSER_FILTERED);
2283         }
2284         break;
2285 
2286         case ID_BROWSER_ORDERCRIT:
2287             ExecuteFilterSortCrit(sal_False);
2288             break;
2289 
2290         case ID_BROWSER_FILTERCRIT:
2291             ExecuteFilterSortCrit(sal_True);
2292             InvalidateFeature(ID_BROWSER_FILTERED);
2293             break;
2294 
2295         case ID_BROWSER_REMOVEFILTER:
2296         {
2297             if (!SaveModified())
2298                 break;
2299 
2300             sal_Bool bNeedPostReload = preReloadForm();
2301             // reset the filter and the sort property simutaneously so only _one_ new statement has to be
2302             // sent
2303             Reference< XPropertySet >  xSet(getRowSet(), UNO_QUERY);
2304             if ( xSet.is() )
2305             {
2306                 xSet->setPropertyValue(PROPERTY_FILTER,makeAny(::rtl::OUString()));
2307                 xSet->setPropertyValue(PROPERTY_HAVING_CLAUSE,makeAny(::rtl::OUString()));
2308                 xSet->setPropertyValue(PROPERTY_ORDER,makeAny(::rtl::OUString()));
2309             }
2310             try
2311             {
2312                 reloadForm(m_xLoadable);
2313                 if ( bNeedPostReload )
2314                     postReloadForm();
2315             }
2316             catch(Exception&)
2317             {
2318             }
2319             InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2320             InvalidateFeature(ID_BROWSER_FILTERED);
2321         }
2322         break;
2323 
2324         case ID_BROWSER_REFRESH:
2325             if ( SaveModified( ) )
2326             {
2327                 if (!reloadForm(m_xLoadable))
2328                     criticalFail();
2329             }
2330             break;
2331 
2332         case ID_BROWSER_SAVERECORD:
2333             if ( SaveModified( sal_False ) )
2334                 setCurrentModified( sal_False );
2335             break;
2336 
2337         case ID_BROWSER_UNDORECORD:
2338         {
2339             try
2340             {
2341                 // restore the cursor state
2342                 Reference< XResultSetUpdate >  xCursor(getRowSet(), UNO_QUERY);
2343                 Reference< XPropertySet >  xSet(xCursor, UNO_QUERY);
2344                 Any aVal = xSet->getPropertyValue(PROPERTY_ISNEW);
2345                 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2346                 {
2347                     xCursor->moveToInsertRow();
2348                     // no need to reset the grid model after we moved to the insert row, this is done implicitly by the
2349                     // form
2350                     // (and in some cases it may be deadly to do the reset explicitly after the form did it implicitly,
2351                     // cause the form's reset may be async, and this leads to some nice deadlock scenarios ....)
2352                 }
2353                 else
2354                 {
2355                     xCursor->cancelRowUpdates();
2356 
2357                     // restore the grids state
2358                     Reference< ::com::sun::star::form::XReset >  xReset(getControlModel(), UNO_QUERY);
2359                     if (xReset.is())
2360                         xReset->reset();
2361                 }
2362             }
2363             catch(SQLException&)
2364             {
2365             }
2366 
2367             setCurrentModified( sal_False );
2368         }
2369     }
2370 }
2371 
2372 //------------------------------------------------------------------------------
2373 sal_Bool SbaXDataBrowserController::SaveModified(sal_Bool bAskFor)
2374 {
2375     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SaveModified" );
2376     if ( bAskFor && GetState(ID_BROWSER_SAVERECORD).bEnabled )
2377     {
2378         getBrowserView()->getVclControl()->GrabFocus();
2379 
2380         QueryBox aQry(getBrowserView()->getVclControl(), ModuleRes(QUERY_BRW_SAVEMODIFIED));
2381 
2382         switch (aQry.Execute())
2383         {
2384             case RET_NO:
2385                 Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>());
2386                 return sal_True;
2387             case RET_CANCEL:
2388                 return sal_False;
2389         }
2390     }
2391 
2392     if ( !CommitCurrent() ) // das aktuelle Control committen lassen
2393         return sal_False;
2394 
2395     Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
2396     sal_Bool bResult = sal_False;
2397     try
2398     {
2399         if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED)))
2400         {
2401             Reference< XResultSetUpdate >  xCursor(getRowSet(), UNO_QUERY);
2402             if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISNEW)))
2403                 xCursor->insertRow();
2404             else
2405                 xCursor->updateRow();
2406         }
2407         bResult = sal_True;
2408     }
2409     catch(SQLException&)
2410     {
2411     }
2412     catch(Exception&)
2413     {
2414         DBG_ERROR("SbaXDataBrowserController::SaveModified : could not save the current record !");
2415         bResult = sal_False;
2416     }
2417 
2418     InvalidateFeature(ID_BROWSER_SAVERECORD);
2419     InvalidateFeature(ID_BROWSER_UNDORECORD);
2420     return bResult;
2421 }
2422 
2423 //------------------------------------------------------------------------------
2424 sal_Bool SbaXDataBrowserController::CommitCurrent()
2425 {
2426     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CommitCurrent" );
2427     if (!getBrowserView())
2428         return sal_True;
2429 
2430     Reference< ::com::sun::star::awt::XControl >  xActiveControl(getBrowserView()->getGridControl());
2431     Reference< ::com::sun::star::form::XBoundControl >  xLockingTest(xActiveControl, UNO_QUERY);
2432     sal_Bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
2433     if (xActiveControl.is() && !bControlIsLocked)
2434     {
2435         // zunaechst das Control fragen ob es das IFace unterstuetzt
2436         Reference< ::com::sun::star::form::XBoundComponent >  xBoundControl(xActiveControl, UNO_QUERY);
2437         if (!xBoundControl.is())
2438             xBoundControl  = Reference< ::com::sun::star::form::XBoundComponent > (xActiveControl->getModel(), UNO_QUERY);
2439         if (xBoundControl.is() && !xBoundControl->commit())
2440             return sal_False;
2441     }
2442     return sal_True;
2443 }
2444 
2445 //------------------------------------------------------------------------------
2446 void SbaXDataBrowserController::setCurrentModified( sal_Bool _bSet )
2447 {
2448     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setCurrentModified" );
2449     m_bCurrentlyModified = _bSet;
2450     InvalidateFeature( ID_BROWSER_SAVERECORD );
2451     InvalidateFeature( ID_BROWSER_UNDORECORD );
2452 }
2453 
2454 //------------------------------------------------------------------------------
2455 void SbaXDataBrowserController::RowChanged()
2456 {
2457     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::RowChanged" );
2458     setCurrentModified( sal_False );
2459 }
2460 
2461 //------------------------------------------------------------------------------
2462 void SbaXDataBrowserController::ColumnChanged()
2463 {
2464     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ColumnChanged" );
2465     InvalidateFeature(ID_BROWSER_SORTUP);
2466     InvalidateFeature(ID_BROWSER_SORTDOWN);
2467     InvalidateFeature(ID_BROWSER_ORDERCRIT);
2468     InvalidateFeature(ID_BROWSER_FILTERCRIT);
2469     InvalidateFeature(ID_BROWSER_AUTOFILTER);
2470     InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2471 
2472     setCurrentModified( sal_False );
2473 }
2474 
2475 //------------------------------------------------------------------------------
2476 void SbaXDataBrowserController::SelectionChanged()
2477 {
2478     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SelectionChanged" );
2479     // not interested in
2480 }
2481 
2482 //------------------------------------------------------------------------------
2483 void SbaXDataBrowserController::CellActivated()
2484 {
2485     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CellActivated" );
2486     m_aInvalidateClipboard.Start();
2487     OnInvalidateClipboard( NULL );
2488 }
2489 
2490 //------------------------------------------------------------------------------
2491 void SbaXDataBrowserController::CellDeactivated()
2492 {
2493     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CellDeactivated" );
2494     m_aInvalidateClipboard.Stop();
2495     OnInvalidateClipboard( NULL );
2496 }
2497 
2498 //------------------------------------------------------------------------------
2499 IMPL_LINK( SbaXDataBrowserController, OnClipboardChanged, void*, EMPTYARG )
2500 {
2501     ::vos::OGuard aGuard(Application::GetSolarMutex());
2502     return OnInvalidateClipboard( NULL );
2503 }
2504 
2505 //------------------------------------------------------------------------------
2506 IMPL_LINK(SbaXDataBrowserController, OnInvalidateClipboard, AutoTimer*, _pTimer)
2507 {
2508     InvalidateFeature(ID_BROWSER_CUT);
2509     InvalidateFeature(ID_BROWSER_COPY);
2510 
2511     // if the invalidation was triggered by the timer, we do not need to invalidate PASTE.
2512     // The timer is only for checking the CUT/COPY slots regulariry, which depend on the
2513     // selection state of the active cell
2514     // TODO: get a callback at the Edit which allows to be notified when the selection
2515     // changes. This would be much better than this cycle-eating polling mechanism here ....
2516     if ( _pTimer != &m_aInvalidateClipboard )
2517         InvalidateFeature(ID_BROWSER_PASTE);
2518 
2519     return 0L;
2520 }
2521 
2522 // -------------------------------------------------------------------------
2523 Reference< XPropertySet >  SbaXDataBrowserController::getBoundField(sal_uInt16 nViewPos) const
2524 {
2525     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SaveData" );
2526     Reference< XPropertySet >  xEmptyReturn;
2527 
2528     // get the current column from the grid
2529     if (nViewPos == (sal_uInt16)-1)
2530     {
2531         Reference< ::com::sun::star::form::XGrid >  xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2532         if (!xGrid.is())
2533             return xEmptyReturn;
2534         nViewPos = xGrid->getCurrentColumnPosition();
2535     }
2536     sal_uInt16 nCurrentCol = getBrowserView()->View2ModelPos(nViewPos);
2537     if (nCurrentCol == (sal_uInt16)-1)
2538         return xEmptyReturn;
2539 
2540     // get the according column from the model
2541     Reference< ::com::sun::star::container::XIndexContainer >  xCols(getControlModel(), UNO_QUERY);
2542     Reference< XPropertySet >  xCurrentCol(xCols->getByIndex(nCurrentCol),UNO_QUERY);
2543     if (!xCurrentCol.is())
2544         return xEmptyReturn;
2545 
2546     xEmptyReturn.set(xCurrentCol->getPropertyValue(PROPERTY_BOUNDFIELD) ,UNO_QUERY);
2547     return xEmptyReturn;
2548 }
2549 
2550 //------------------------------------------------------------------------------
2551 IMPL_LINK(SbaXDataBrowserController, OnSearchContextRequest, FmSearchContext*, pContext)
2552 {
2553     Reference< ::com::sun::star::container::XIndexAccess >  xPeerContainer(getBrowserView()->getGridControl(), UNO_QUERY);
2554 
2555     // check all grid columns for their control source
2556     Reference< ::com::sun::star::container::XIndexAccess >  xModelColumns(getFormComponent(), UNO_QUERY);
2557     DBG_ASSERT(xModelColumns.is(), "SbaXDataBrowserController::OnSearchContextRequest : there is a grid control without columns !");
2558         // the case 'no columns' should be indicated with an empty container, I think ...
2559     DBG_ASSERT(xModelColumns->getCount() >= xPeerContainer->getCount(), "SbaXDataBrowserController::OnSearchContextRequest : impossible : have more view than model columns !");
2560 
2561     String sFieldList;
2562     for (sal_Int32 nViewPos=0; nViewPos<xPeerContainer->getCount(); ++nViewPos)
2563     {
2564         Reference< XInterface >  xCurrentColumn(xPeerContainer->getByIndex(nViewPos),UNO_QUERY);
2565         if (!xCurrentColumn.is())
2566             continue;
2567 
2568         // can we use this column control fo searching ?
2569         if (!IsSearchableControl(xCurrentColumn))
2570             continue;
2571 
2572         sal_uInt16 nModelPos = getBrowserView()->View2ModelPos((sal_uInt16)nViewPos);
2573         Reference< XPropertySet >  xCurrentColModel(xModelColumns->getByIndex(nModelPos),UNO_QUERY);
2574         ::rtl::OUString aName = ::comphelper::getString(xCurrentColModel->getPropertyValue(PROPERTY_CONTROLSOURCE));
2575 
2576         sFieldList += (const sal_Unicode*)aName;
2577         sFieldList += ';';
2578 
2579         pContext->arrFields.push_back(xCurrentColumn);
2580     }
2581     sFieldList.EraseTrailingChars(';');
2582 
2583     pContext->xCursor.set(getRowSet(),UNO_QUERY);
2584     pContext->strUsedFields = sFieldList;
2585 
2586     // if the cursor is in a mode other than STANDARD -> reset
2587     Reference< XPropertySet >  xCursorSet(pContext->xCursor, UNO_QUERY);
2588     DBG_ASSERT(xCursorSet.is() && !::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISMODIFIED)),
2589         "SbaXDataBrowserController::OnSearchContextRequest : please do not call for cursors with modified rows !");
2590     if (xCursorSet.is() && ::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISNEW)))
2591     {
2592         Reference< XResultSetUpdate >  xUpdateCursor(pContext->xCursor, UNO_QUERY);
2593         xUpdateCursor->moveToCurrentRow();
2594     }
2595     return pContext->arrFields.size();
2596 }
2597 
2598 //------------------------------------------------------------------------------
2599 IMPL_LINK(SbaXDataBrowserController, OnFoundData, FmFoundRecordInformation*, pInfo)
2600 {
2601     Reference< ::com::sun::star::sdbcx::XRowLocate >  xCursor(getRowSet(), UNO_QUERY);
2602     DBG_ASSERT(xCursor.is(), "SbaXDataBrowserController::OnFoundData : shit happens. sometimes. but this is simply impossible !");
2603 
2604     // move the cursor
2605     xCursor->moveToBookmark(pInfo->aPosition);
2606 
2607     // let the grid snyc it's display with the cursor
2608     Reference< XPropertySet >  xModelSet(getControlModel(), UNO_QUERY);
2609     DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::OnFoundData : no model set ?!");
2610     Any aOld = xModelSet->getPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"));
2611     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
2612     xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), aOld);
2613 
2614     // and move to the field
2615     Reference< ::com::sun::star::container::XIndexAccess >  aColumnControls(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
2616     sal_uInt16 nViewPos;
2617 
2618     for ( nViewPos = 0; nViewPos < aColumnControls->getCount(); ++nViewPos )
2619     {
2620         Reference< XInterface >  xCurrent(aColumnControls->getByIndex(nViewPos),UNO_QUERY);
2621         if (IsSearchableControl(xCurrent))
2622         {
2623             if (pInfo->nFieldPos)
2624                 --pInfo->nFieldPos;
2625             else
2626                 break;
2627         }
2628     }
2629 
2630     Reference< ::com::sun::star::form::XGrid >  xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2631     xGrid->setCurrentColumnPosition(nViewPos);
2632 
2633     return 0;
2634 }
2635 
2636 //------------------------------------------------------------------------------
2637 IMPL_LINK(SbaXDataBrowserController, OnCanceledNotFound, FmFoundRecordInformation*, pInfo)
2638 {
2639     Reference< ::com::sun::star::sdbcx::XRowLocate >  xCursor(getRowSet(), UNO_QUERY);
2640 
2641     try
2642     {
2643         DBG_ASSERT(xCursor.is(), "SbaXDataBrowserController::OnCanceledNotFound : shit happens. sometimes. but this is simply impossible !");
2644         // move the cursor
2645         xCursor->moveToBookmark(pInfo->aPosition);
2646     }
2647     catch( const Exception& )
2648     {
2649         DBG_UNHANDLED_EXCEPTION();
2650     }
2651 
2652     try
2653     {
2654         // let the grid snyc it's display with the cursor
2655         Reference< XPropertySet >  xModelSet(getControlModel(), UNO_QUERY);
2656         DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::OnCanceledNotFound : no model set ?!");
2657         Any aOld = xModelSet->getPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"));
2658         xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
2659         xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), aOld);
2660     }
2661     catch( const Exception& )
2662     {
2663         DBG_UNHANDLED_EXCEPTION();
2664     }
2665 
2666     return 0L;
2667 }
2668 
2669 //------------------------------------------------------------------------------
2670 IMPL_LINK(SbaXDataBrowserController, OnAsyncGetCellFocus, void*, EMPTYARG)
2671 {
2672     SbaGridControl* pVclGrid = getBrowserView() ? getBrowserView()->getVclControl() : NULL;
2673     // if we have a controller, but the window for the controller doesn't have the focus, we correct this
2674     if(pVclGrid)
2675     {
2676         if (!pVclGrid->IsEditing())
2677             return 0L;
2678 
2679         if (pVclGrid->HasChildPathFocus())
2680             pVclGrid->Controller()->GetWindow().GrabFocus();
2681     }
2682 
2683     return 0L;
2684 }
2685 
2686 //------------------------------------------------------------------------------
2687 void SbaXDataBrowserController::criticalFail()
2688 {
2689     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::criticalFail" );
2690     InvalidateAll();
2691     m_nRowSetPrivileges = 0;
2692 }
2693 
2694 //------------------------------------------------------------------------------
2695 void SbaXDataBrowserController::LoadFinished(sal_Bool /*bWasSynch*/)
2696 {
2697     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::LoadFinished" );
2698     m_nRowSetPrivileges = 0;
2699 
2700     if (isValid() && !loadingCancelled())
2701     {
2702         // obtain cached values
2703         try
2704         {
2705             Reference< XPropertySet > xFormProps( m_xLoadable, UNO_QUERY_THROW );
2706             OSL_VERIFY( xFormProps->getPropertyValue( PROPERTY_PRIVILEGES ) >>= m_nRowSetPrivileges );
2707         }
2708         catch( const Exception& )
2709         {
2710             DBG_UNHANDLED_EXCEPTION();
2711         }
2712 
2713         // --------------------------------
2714         // switch the control to alive mode
2715         getBrowserView()->getGridControl()->setDesignMode(sal_False);
2716 
2717         // -------------------------------
2718         initializeParser();
2719 
2720         // -------------------------------
2721         InvalidateAll();
2722 
2723         m_aAsyncGetCellFocus.Call();
2724     }
2725 }
2726 // -----------------------------------------------------------------------------
2727 void SbaXDataBrowserController::initializeParser() const
2728 {
2729     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::initializeParser" );
2730     if ( !m_xParser.is() )
2731     {
2732         // ----------------------------------------------
2733         // create a parser (needed for filtering/sorting)
2734         try
2735         {
2736             const Reference< XPropertySet >  xFormSet(getRowSet(), UNO_QUERY);
2737             if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)))
2738             {   // (only if the statement isn't native)
2739                 // (it is allowed to use the PROPERTY_ISPASSTHROUGH : _after_ loading a form it is valid)
2740                 xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser;
2741             }
2742         }
2743         catch(Exception&)
2744         {
2745             DBG_UNHANDLED_EXCEPTION();
2746             m_xParser = NULL;
2747             // no further handling, we ignore the error
2748         }
2749     }
2750 }
2751 //------------------------------------------------------------------------------
2752 void SbaXDataBrowserController::loaded(const EventObject& /*aEvent*/) throw( RuntimeException )
2753 {
2754     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::loaded" );
2755     // not interested in
2756     // we're loading within an separate thread and have a handling  for it's "finished event"
2757 }
2758 
2759 //------------------------------------------------------------------------------
2760 void SbaXDataBrowserController::unloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2761 {
2762     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::unloading" );
2763     // not interested in
2764 }
2765 
2766 //------------------------------------------------------------------------------
2767 void SbaXDataBrowserController::unloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
2768 {
2769     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::unloaded" );
2770     m_xParser.clear();
2771     InvalidateAll();
2772         // do this asynchron, there are other listeners reacting on this message ...
2773         // (it's a little hack : the grid columns are listening to this event, too, and their bound field may
2774         // change as a reaction on that event. as we have no chance to be notified of this change (which is
2775         // the one we're interested in) we give them time to do what they want to before invalidating our
2776         // bound-field-dependent slots ....
2777 }
2778 
2779 //------------------------------------------------------------------------------
2780 void SbaXDataBrowserController::reloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2781 {
2782     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloading" );
2783     // not interested in
2784 }
2785 
2786 //------------------------------------------------------------------------------
2787 void SbaXDataBrowserController::reloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
2788 {
2789     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloaded" );
2790     InvalidateAll();
2791         // do this asynchronously, there are other listeners reacting on this message ...
2792         // (it's a little hack : the grid columns are listening to this event, too, and their bound field may
2793         // change as a reaction on that event. as we have no chance to be notified of this change (which is
2794         // the one we're interested in) we give them time to do what they want to before invalidating our
2795         // bound-field-dependent slots ....
2796 }
2797 //------------------------------------------------------------------------------
2798 void SbaXDataBrowserController::enterFormAction()
2799 {
2800     if ( !m_nFormActionNestingLevel )
2801         // first action -> reset
2802         m_aCurrentError.clear();
2803 
2804     ++m_nFormActionNestingLevel;
2805 }
2806 
2807 //------------------------------------------------------------------------------
2808 void SbaXDataBrowserController::leaveFormAction()
2809 {
2810     DBG_ASSERT( m_nFormActionNestingLevel > 0, "SbaXDataBrowserController::leaveFormAction : invalid call !" );
2811     if ( --m_nFormActionNestingLevel > 0 )
2812         return;
2813 
2814     if ( !m_aCurrentError.isValid() )
2815         return;
2816 
2817     m_aAsyncDisplayError.Call();
2818 }
2819 
2820 // -------------------------------------------------------------------------
2821 sal_Bool SbaXDataBrowserController::isLoaded() const
2822 {
2823     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::isLoaded" );
2824     return m_xLoadable.is() && m_xLoadable->isLoaded();
2825 }
2826 
2827 // -------------------------------------------------------------------------
2828 sal_Bool SbaXDataBrowserController::isValidCursor() const
2829 {
2830     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::isValidCursor" );
2831     if (!m_xColumnsSupplier.is())
2832         return sal_False;
2833     Reference< ::com::sun::star::container::XNameAccess >  xCols = m_xColumnsSupplier->getColumns();
2834     if (!xCols.is() || !xCols->hasElements())
2835         return sal_False;
2836 
2837     sal_Bool bIsValid = !(m_xRowSet->isBeforeFirst() || m_xRowSet->isAfterLast());
2838     if ( !bIsValid )
2839     {
2840         Reference<XPropertySet> xProp(m_xRowSet,UNO_QUERY);
2841         bIsValid = ::cppu::any2bool(xProp->getPropertyValue(PROPERTY_ISNEW));
2842         if ( !bIsValid )
2843         {
2844             bIsValid = m_xParser.is();
2845         }
2846     } // if ( !bIsValid )
2847     return bIsValid;
2848 }
2849 
2850 //==================================================================
2851 // LoadFormHelper
2852 //==================================================================
2853 
2854 class LoadFormHelper :public ::cppu::WeakImplHelper2< ::com::sun::star::form::XLoadListener,
2855                                                       XRowSetListener>
2856 {
2857     enum STATE { STARTED, LOADED, POSITIONED, DISPOSED };
2858     STATE   m_eState;
2859 
2860     Reference< XRowSet >                m_xForm;
2861 
2862     ::osl::Mutex    m_aAccessSafety;
2863 
2864 public:
2865     LoadFormHelper(const Reference< XRowSet > & _rxForm);
2866 
2867     // ::com::sun::star::form::XLoadListener
2868     virtual void SAL_CALL loaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2869     virtual void SAL_CALL unloaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2870     virtual void SAL_CALL unloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2871     virtual void SAL_CALL reloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2872     virtual void SAL_CALL reloaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2873 
2874     // XRowSetListener
2875     virtual void SAL_CALL cursorMoved(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException );
2876     virtual void SAL_CALL rowChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException );
2877     virtual void SAL_CALL rowSetChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException );
2878 
2879     // ::com::sun::star::lang::XEventListener
2880     virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException );
2881 
2882 
2883     bool WaitUntilReallyLoaded(bool _bOnlyIfLoaded);
2884         // waits 'til the first positioned event after the loaded event. returns true if successfull,
2885         // false if the form was disposed or unloaded before or while waiting
2886         // if _bOnlyIfLoaded is false and the form isn't loaded already loaded, false will be returned
2887         // (without any wating)
2888 
2889     void cancel();
2890 
2891 protected:
2892     ~LoadFormHelper();
2893 
2894     void implDispose();
2895 };
2896 
2897 DBG_NAME(LoadFormHelper)
2898 //------------------------------------------------------------------------------
2899 LoadFormHelper::LoadFormHelper(const Reference< XRowSet > & _rxForm)
2900     :m_eState(STARTED)
2901     ,m_xForm(_rxForm)
2902 {
2903     DBG_CTOR(LoadFormHelper,NULL);
2904 
2905     Reference< ::com::sun::star::form::XLoadable > (m_xForm, UNO_QUERY)->addLoadListener(this);
2906     m_xForm->addRowSetListener(this);
2907 }
2908 
2909 //------------------------------------------------------------------------------
2910 LoadFormHelper::~LoadFormHelper()
2911 {
2912     ::osl::MutexGuard aGuard(m_aAccessSafety);
2913     implDispose();
2914 
2915     DBG_DTOR(LoadFormHelper,NULL);
2916 }
2917 
2918 //------------------------------------------------------------------------------
2919 void LoadFormHelper::implDispose()
2920 {
2921     if (DISPOSED != m_eState)
2922     {
2923 
2924         Reference< ::com::sun::star::form::XLoadable > (m_xForm, UNO_QUERY)->removeLoadListener(this);
2925         m_xForm->removeRowSetListener(this);
2926         m_xForm = NULL;
2927         m_eState = DISPOSED;
2928     }
2929 }
2930 
2931 //------------------------------------------------------------------------------
2932 void SAL_CALL LoadFormHelper::loaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2933 {
2934     ::osl::MutexGuard aGuard(m_aAccessSafety);
2935     DBG_ASSERT(m_eState == STARTED || m_eState == DISPOSED, "LoadFormHelper::loaded : wrong call !");
2936     if (m_eState == STARTED)
2937         m_eState = LOADED;
2938 }
2939 
2940 //------------------------------------------------------------------------------
2941 void SAL_CALL LoadFormHelper::unloaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2942 {
2943     ::osl::MutexGuard aGuard(m_aAccessSafety);
2944     DBG_ERROR("LoadFormHelper::unloaded : shouldn't be called !");
2945     implDispose();
2946 }
2947 
2948 //------------------------------------------------------------------------------
2949 void SAL_CALL LoadFormHelper::unloading(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2950 {
2951 }
2952 
2953 //------------------------------------------------------------------------------
2954 void SAL_CALL LoadFormHelper::reloading(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2955 {
2956 }
2957 
2958 //------------------------------------------------------------------------------
2959 void SAL_CALL LoadFormHelper::reloaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2960 {
2961 }
2962 
2963 //------------------------------------------------------------------------------
2964 void SAL_CALL LoadFormHelper::cursorMoved(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException )
2965 {
2966     ::osl::MutexGuard aGuard(m_aAccessSafety);
2967     if (m_eState == LOADED)
2968         m_eState = POSITIONED;
2969 }
2970 
2971 //------------------------------------------------------------------------------
2972 void SAL_CALL LoadFormHelper::rowChanged(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException )
2973 {
2974 }
2975 
2976 //------------------------------------------------------------------------------
2977 void SAL_CALL LoadFormHelper::rowSetChanged(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException )
2978 {
2979 }
2980 
2981 //------------------------------------------------------------------------------
2982 void SAL_CALL LoadFormHelper::disposing(const ::com::sun::star::lang::EventObject& /*Source*/) throw( RuntimeException )
2983 {
2984     ::osl::MutexGuard aGuard(m_aAccessSafety);
2985     implDispose();
2986 }
2987 
2988 //------------------------------------------------------------------------------
2989 void LoadFormHelper::cancel()
2990 {
2991     implDispose();
2992 }
2993 
2994 //------------------------------------------------------------------------------
2995 bool LoadFormHelper::WaitUntilReallyLoaded(bool _bOnlyIfLoaded)
2996 {
2997     ::osl::ResettableMutexGuard aGuard( m_aAccessSafety );
2998     if (DISPOSED == m_eState)
2999         return false;
3000 
3001     if (_bOnlyIfLoaded && (STARTED == m_eState))
3002         // we did't get a "loaded" event ....
3003         return false;
3004 
3005     sal_Bool bDone = (POSITIONED == m_eState);
3006     aGuard.clear();
3007 
3008     while (!bDone)
3009     {
3010         aGuard.reset();
3011         bDone = (POSITIONED == m_eState);
3012         aGuard.clear();
3013     }
3014 
3015     aGuard.reset();
3016     implDispose();
3017 
3018     return true;
3019 }
3020 
3021 // -----------------------------------------------------------------------------
3022 sal_Int16 SbaXDataBrowserController::getCurrentColumnPosition()
3023 {
3024     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getCurrentColumnPosition" );
3025     Reference< ::com::sun::star::form::XGrid >  xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
3026     sal_Int16 nViewPos = -1;
3027     try
3028     {
3029         if ( xGrid.is() )
3030             nViewPos = xGrid->getCurrentColumnPosition();
3031     }
3032     catch(Exception&) {}
3033     return nViewPos;
3034 }
3035 // -----------------------------------------------------------------------------
3036 void SbaXDataBrowserController::setCurrentColumnPosition( sal_Int16 _nPos )
3037 {
3038     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setCurrentColumnPosition" );
3039     Reference< ::com::sun::star::form::XGrid >  xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
3040     try
3041     {
3042         if ( -1 != _nPos )
3043             xGrid->setCurrentColumnPosition(_nPos);
3044     }
3045     catch(Exception&) {}
3046 }
3047 // -----------------------------------------------------------------------------
3048 void SbaXDataBrowserController::BeforeDrop()
3049 {
3050     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::BeforeDrop" );
3051     Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster >  xFormError(getRowSet(), UNO_QUERY);
3052     if (xFormError.is())
3053         xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
3054 }
3055 // -----------------------------------------------------------------------------
3056 void SbaXDataBrowserController::AfterDrop()
3057 {
3058     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::AfterDrop" );
3059     Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster >  xFormError(getRowSet(), UNO_QUERY);
3060     if (xFormError.is())
3061         xFormError->addSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
3062 }
3063 // -----------------------------------------------------------------------------
3064 void SbaXDataBrowserController::addColumnListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
3065 {
3066     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addColumnListeners" );
3067 // ... all the grid columns
3068     Reference< ::com::sun::star::container::XIndexContainer >  xColumns(_xGridControlModel, UNO_QUERY);
3069     if (xColumns.is())
3070     {
3071         sal_Int32 nCount = xColumns->getCount();
3072         for (sal_uInt16 i=0; i < nCount; ++i)
3073         {
3074             Reference< XPropertySet >  xCol(xColumns->getByIndex(i),UNO_QUERY);
3075             AddColumnListener(xCol);
3076         }
3077     }
3078 }
3079 // -----------------------------------------------------------------------------
3080 sal_Bool SbaXDataBrowserController::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & /*xGrid*/)
3081 {
3082     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::InitializeGridModel" );
3083     return sal_True;
3084 }
3085 //..................................................................
3086 }   // namespace dbaui
3087 //..................................................................
3088